五类经典排序算法原理及Python实现

1 冒泡排序 BubbleSort

1.1 原理:

多次扫描整个数组,每次扫描都比较相邻两个元素,如果逆序,则交换两个元素。

第一次扫描结果是数值最大元素到数组的最后位置,比较的次数是n(数组长度)-1。

第二次扫描,因为最大元素已经在最后位置,所以需要比较的次数为n-2

以此类推,一共需要扫描n-1次。

 

1.2 算法实现:

两次for循环即可实现。第一层循环控制扫描的次数,第二层循环控制每次扫描需要比较的次数。

交换两个相邻元素利用一个temp的变量即可

 

1.3 Python代码实现:

if __name__ == '__main__':
Original = input('Please input number split with ,:')
OriginalList = Original.split(',')
print(type(OriginalList))
#按照,为间隔将输入内容放入到数组中,数组中的元素是字符串
OriginalList = list(map(int,OriginalList))
#将数组中的字符串强制转换为int类型
print('Original List',OriginalList)
for i in range(1,OriginalList.__len__()-1):
for j in range(0,OriginalList.__len__()-1):
if OriginalList[j]>OriginalList[j+1]:
a = OriginalList[j]
OriginalList[j] = OriginalList[j+1]
OriginalList[j+1] = a
else:
continue
print('result List',OriginalList)

 2 选择排序 SelectionSort

2.1 原理:

多次扫描整个数组,每次选择一个最小值,加入到结果数组中。

第一次扫描,应该得到数组中最小值,然后需要从原始数组中去掉该最小值,得到一个新的原始数组。

然后对于这个原始数组进行第二次扫描,再得到一个最小值,加入到结果数组。

 

2.2 算法实现

两个数组,一个是原始数组,另一个是结果数组。

两次for循环,第一层控制扫描数组的次数,第二层控制每次扫描中遍历数组中所有元素,查找出最小值。

需要设定一个最小值变量,用来存储每次扫描中的最小值,然后将最小值加入到结果数组中。并且每次扫描后,原始数组中都应该去掉该次扫描中得到的最小值,得到一个新的原始数组,进入到下一次的扫描中。

 

2.3 Python代码实现:

if __name__ == '__main__':
Original = input('Please input number split with ,:')
OriginalList = Original.split(',')
OriginalList = list(map(int,OriginalList))
lenth = OriginalList.__len__()
print('Original List',OriginalList)
resultList = []
for i in range(1,lenth+1):
minItem = OriginalList[0]
place = 0
for j in range(1,OriginalList.__len__()):
if OriginalList[j]<minItem:
minItem = OriginalList[j]
place = j
else:
continue
resultList.append(minItem)
OriginalList.pop(place)
#将数组中指定位置的元素移除
print('result List',resultList)

3 插入排序 Insertion Sort

3.1 原理

建立一个结果数组,然后多次扫描原始数组,每次取原始数组其中一个元素,然后遍历结果数组,将元素插入到正确位置。原始数组的所有元素插入完毕后,得到的结果数组自然是有序的数列。

 

3.2 算法实现:

两层for循环控制,第一层依次取原始数组中的每一个元素,第二层遍历结果数组中的所有元素,将原始数组中取到的元素插入正确的位置。

需要声明一个临时变量,记录需要插入的结果数组的位置。再每次第二层for循环结束后,把从原始数组中取出的元素插入到结果数组中临时变量记录的位置。

3.3 Python代码实现:

def InsertSortFunction(OriginalList):
lenth = OriginalList.__len__()
resultList = []
resultList.append(OriginalList[0])
#将元素加入数组的最末位
for i in range(1,lenth):
for j in range(0,resultList.__len__()):
temp = resultList.__len__()
if OriginalList[i]<=resultList[j]:
temp = j
break
else:
continue
resultList.insert(temp,OriginalList[i])
#将元素加入到数组的指定位置
return resultList

if __name__ == '__main__':
Original = input('Please input number split with ,:')
OriginalList = Original.split(',')
OriginalList = list(map(int,OriginalList))
print('Original List',OriginalList)
resultList = InsertSortFunction(OriginalList)
print('ResultList',resultList)
 

4 快速排序 Quick Sort

4.1原理:

选出一个基准元素,通常是第一个,然后对于剩下的元素进行判断,比基准元素小的移动位置到基准元素的左边,比基准元素大的移动位置到基准元素的右边。第一次调用方法,基准元素被放置于准确的位置。

然后对于左边和右边两个数列再重复这个方法,以此类推,最后可以得到一个有序的数列。

 

4.2算法实现:

首先选取基准元素,通常是第一个,然后声明两个位置变量i,j,分别指向数组第一个和最后一个位置,然后先从后往前依次判断各个元素是否比基准元素小,再此过程中j也不断向前移动。找到比基准元素小的元素后,将该元素放置到i位置。然后再从前往后依次判断各个元素是否比基准元素大,再此过程中i也不断向后移动。找到比基准元素大的元素后,将该元素放置到j的位置。然后再从j的位置继续往前查找。

这样一直到i与j重合,这个位置就应该是基准元素的位置。此时基准元素被放置在准确的位置,左边是所有比它小的元素,右边是所有比它大的元素。

然后开始在方法中递归调用这个方法本身,对于基准元素两边的数列再次使用快速排序。

Point:在实现方法时需要注意几点

1 要为递归调用找到一个出口,在方法初始要判断i与j的位置,如果i>=j,则直接return,说明数列在拆分排序中已经没有需要排序的数列了。

2 方法有3个参数,数组,起始位置(也就是i),结束位置(也就是j),在调用方法时,一定要注意两个位置的参数输入。

 

4.3 Python代码实现:

def QuickSortFunction(listtest,a,b):
if (a<b):
i = a
j = b
temp = listtest[a]
while (i < j):
while (i < j and listtest[j] >= temp):
j = j - 1
listtest[i] = listtest[j]
while (i < j and listtest[i] <= temp):
i = i + 1
listtest[j] = listtest[i]
listtest[i] = temp
QuickSortFunction(listtest,a,i-1)
QuickSortFunction(listtest,i+1,b)
return listtest
if __name__ == '__main__':
Original = input('Please input number split with ,:')
OriginalList = Original.split(',')
OriginalList = list(map(int,OriginalList))
print('Original List',OriginalList)
QuickSortFunction(OriginalList,0,OriginalList.__len__()-1)
print('Result List',OriginalList)

5 希尔排序 Shell Sort

5.1 原理

把一个数组,按照间隔拆分成不同的子数组,然后按照直接插入排序方法将这些子数组排列为正确顺序,然后在减小间隔,再进行排序,一直到间隔为1,最后一次执行插入排序,得到有序队列。

间隔通常取值数组长度/3向上取整(n//3+1),取值的原理还没具体取研究(TBD)

 

5.2 算法实现

首先设定初始间隔gap。

当间隔大于1时,说明需要拆分成若个子数组,进行排序。两层循环实现,第一层是利用gap为步长,拆分子数组。然后第二层分别是将子数组结合为一个新的临时数组,用直接插入方法对临时数组进行排序,然后将正序的临时数组写入到原有数列中的正确位置中。

不断缩小间隔,直到间隔不大于1,说明不再需要拆分成子序列,则执行直接插入方法,得到有序数列。

5.3 Python代码实现:


from Algorithm.Sort import InsertionSort

if __name__ == '__main__':
Original = input('Please input number split with ,:')
OriginalList = Original.split(',')
OriginalList = list(map(int, OriginalList))
print('Original List', OriginalList)
lengh = OriginalList.__len__()
gap = lengh//3+1
# "//"代表除法向下取整,"/"代表除法结果浮点数,"%"是取余
while (gap>1):
for i in range(0,gap):
tempList = []
for j in range(i,lengh,gap):
tempList.append(OriginalList[j])
tempResult = list(InsertionSort.InsertSortFunction(tempList))
for a,b in zip(range(i,lengh,gap),range(0,tempResult.__len__())):
OriginalList[a] = tempResult[b]
gap = gap//3+1
OriginalList = InsertionSort.InsertSortFunction(OriginalList)
print('ResultList', OriginalList)
posted @ 2019-06-05 23:23  Jolin_赵大王  阅读(278)  评论(0编辑  收藏  举报