主流排序算法比较:
注:
√/×:当a在b前,若a=b,排序后a仍在b前(稳定)
In/Out:所有排序操作内存中执行(In),有"外存"辅助(Out)
一:冒泡排序
"气泡越大,冒得越快!"
每轮遍历选出max的数放于数组最后,相邻的两数比较,满足条件即交换(原地排序)
def __init__(self, l):
self.l = l
def bubble_sort(self):
n = len(self.l)
for i in range(0, n-1):
for j in range(0, n-1-i):
if self.l[j] > self.l[j + 1]:
self.l[j],self.l[j+1] = self.l[j+1],self.l[j]
二:选择排序
遍历数组找出min的数与第一个数交换,下次遍历数组选出次小的与第二个数交换,直到第n个与第n-1个数比较结束。(原地排序)
def select_sort(self):
n = len(self.l)
for i in range(0, n-1):
min = i
for j in range(i + 1, n):
if self.l[j] < self.l[min]:
min = j
if i != min:
self.l[i],self.l[min] = self.l[min],self.l[i]
三:插入排序
1.从第一个元素开始;
2.取下一个元素a,已排好的序列中从后向前扫描;
3.若a<某元素,将该元素移到下一位置;
4.重复3,直到找到已排序元素小于或等于新元素的位置,插入;
5.重复2~4步,至结束。
(原地排序)
def insert_sort(self):
n = len(self.l)
for i in range(1, n):
x = self.l[i]
j = i - 1
while j >= 0 and self.l[j] > x:
self.l[j+1] = self.l[j]
j -= 1
self.l[j+1] = x
四:快速排序
1.设置变量i = 0,j = len ( list ) - 1;(边界是i < j)
2.设第一个元素为base(基准);
3.从j开始往前搜索,找到list[j] < base的索引j;
4.从i开始往后搜索,找到list[i] > base的索引i;
5.交换i,j处的元素
6.当i = j时,则交换0,i处的元素;(分治完成,索引i两边的元素)
7.递归左边(0,i - 1),递归右边(i + 1,n)
def quick_sort(self, start, end):
if start < end:
i, j = start, end
base = self.l[i]
while i < j:
while (i < j) and (self.l[j] >= base):
j = j - 1
self.l[i] = self.l[j]
while (i < j) and (self.l[i] <= base):
i = i + 1
self.l[j] = self.l[i]
self.l[i] = base
self.quick_sort(start, i - 1)
self.quick_sort(j + 1, end)
五:归并排序
"分治法!二分"
排序性能很不错,非常稳定,代价是额外内存!
def merge_sort(self, list): # 拆
if len(list) <= 1:
return list
middle = len(list) // 2
left = self.merge_sort(list[:middle])
right = self.merge_sort(list[middle:])
return self.merge(left, right)
def merge(self, a, b): # 合并
res = []
i = j = 0
while i < len(a) and j < len(b):
if a[i] < b[j]:
res.append(a[i])
i += 1
else:
res.append(b[j])
j += 1
res.extend(a[i:])
res.extend(b[j:])
return res
六:堆排序
"分治法!二分"
排序性能很不错,非常稳定,代价是额外内存!
(原地排序)
def heap_sort(self, array):
if not array:
return array
n = len(array)
# 最后一个结点的下标为n//2
# 建立初始大根堆
for i in range(n//2, -1, -1):
self.Max_heap(array, i, n)
for j in range(n-1, 0, -1):
# 把堆顶元素即第一大与最后一个元素互换
array[0], array[j] = array[j], array[0]
# 换完位置之后将剩余的元素重新调整成大根堆
self.Max_heap(array, 0, j)
return
# 调整父结点为大根堆
def Max_heap(self, array, pa, n):
son = 2 * pa + 1
temp = array[pa]
while son < n:
if son+1 < n and array[son] < array[son+1]:
son += 1
if temp > array[son]:
break
array[pa] = array[son]
pa = son
son = 2 * pa + 1
array[pa] = temp
七:希尔排序
"改进后的分组插入排序!"
并不是很稳定。。。
def shell_sort(self):
n = len(self.l)
step = n // 2
while step > 0:
for i in range(step, n):
while i >= step and self.l[i-step] > self.l[i]:
self.l[i-step], self.l[i] = self.l[i], self.l[i-step]
i -= step
step = step // 2
return