1.快速排序
- 思路
- 选取数组的第一个值作为参考值
- 选取两个指针,初始状态一个指向第一个元素,一个指向最后一个元素;
- 如果右边指针指向的元素大于等于参考值则不需要进行操作,并把指针左移;
- 上一步在数组右侧找到了符合要求的元素,就把它放到左指针指向的位置;
- 如果左边指针指向的元素小于参考值则不需要进行操作,并把指针右移;
- 上一步在数组左侧找到了符合要求的元素,就把它放到右指针指向的位置;
- 当左右指针相遇后,把参考值放入相遇的位置;
- 对上一次操作完的数组的左右两段进行上述步骤的排序;
- 代码
def quick_sort(alist,first,last):
if first>=last:
return
mid_value=alist[first]
low=first
high=last
while low<high:
while low<high and alist[high]>=mid_value:
high-=1
alist[low]=alist[high]
while low<high and alist[low]<mid_value:
low+=1
alist[high]=alist[low]
alist[low]=mid_value
quick_sort(alist,first,low-1)
quick_sort(alist,low+1,last)
2.冒泡排序
- 思路
- 对从第一个元素开始,依次与它后面的元素作比较,若小的在后面就互相交换位置,第一轮保证最大的元素沉入数组末尾
- 外层循环保证进行arr.length次排序
- 可以使用flag标记进行优化,初始为false,若是其中一轮进行了元素交换则设置为true。一轮排序完成后若flag为false则说明该轮没有进行交换,排序已经完成。
- 代码
def sort(numList):
flag=False
for j in range(len(numList)-1):
for i in range(len(numList)-1):
if numList[i]>numList[i+1]:
flag=True
temp=numList[i]
numList[i]=numList[i+1]
numList[i+1]=temp
if not flag:
break
else:
flag=False
return numList
3. 插入排序
- 思路:从第二个元素开始,把该元素之前的所有元素看成有序数组,并把该元素插入有序数组中合适的位置。
- 代码
def main():
num_list=[2,51,3,40,8,1,6]
# 从第二个元素开始选择,插入前面有序元素组中,和有序元素组中最后一个元素比较
# 若比它大则放在它后面,否则继续和它前面的元素比较
for i in range(1,len(num_list)):
insert_value=num_list[i]
insert_index=i-1
while insert_index>=0 and insert_value<num_list[insert_index]:
# 如果插入值小于有序列表待插入位置的值,则待插入位置的值后移
num_list[insert_index+1]=num_list[insert_index]
insert_index-=1
num_list[insert_index+1]=insert_value
4.选择排序
- 思路:思路较为简单,首先把第一个元素当做最小值min,遍历后面的元素,如果找到更小的元素则和min交换,从而更新了min值,遍历一轮后第一个值就是真正的最小值了;按照此思路再寻找第二小的值。
- 代码
def main():
numList=[4,5,1,0,5,88,7]
for i in range(len(numList)):
min=numList[i]
for j in range(i,len(numList)):
if min > numList[j]:
temp=min
min=numList[j]
numList[j]=temp
numList[i]=min
for i in range(len(numList)):
print(numList[i])
5. 希尔排序
- 思路
- 求出数组长度,第一次把每两个元素分成一组,所以第一次分成的组数gap=arr.length/2,同一组元素之间索引值相隔(增量)为gap,对每一组进行插入排序。
- 增量缩小为上一次的一半,再对同一组使用插入排序
- 直到增量为0时,数组已经排完序
这个链接说的比较好懂 :希尔排序思路
- 代码
def main():
"""对数组分组,初始增量为length/2,后面的分组在前面的基础上/2,对每个分组
使用插入排序
每一步的结果大体的趋势是小的大部分都前移了,数组趋于有序
普通插入法对相对有序的序列插入效率高
"""
num_list=[8,9,1,70,2,3,5,4,6,0]
gap=len(num_list)
# 第一层循环取不同的gap值
while gap>0:
gap=int(gap/2)
if gap==0:
break
# 第二层循环开始对每组进行插入排序
# 从第gap个元素开始,每次向前移动一次,也就换成下一组插入排序了,一共有gap组。但是再经历gap次又会对第一组排序
for i in range(gap,len(num_list)):
# 这一层循环是对上层循环遍历到的元素和与它同一组的之前的所有元素比较
# 它和它同一组的之前的元素索引相差gap
insert_value=num_list[i]
insert_index=i-gap
while insert_index >= 0 and insert_value<num_list[insert_index]:
# 判断此时的元素和同组前一个元素谁大谁小
num_list[insert_index+gap]=num_list[insert_index]
insert_index=insert_index-gap
num_list[insert_index+gap]=insert_value
7.常见排序算法的时间复杂度比较
时间复杂度分析的相关博文:超详细的算法复杂度比较