1. 直接插入排序——升序
#直接插入排序 升序排序
def insert_sort(a):
length = len(a)
for i in range(1, length):
if a[i] < a[i - 1]:
j= i -1
temp = a[i]
while j >= 0 and temp < a[j]:
a[j + 1] = a[j]
j -= 1
a[j + 1] = temp
return a
print(insert_sort([2, 5, 2, 7, 1, 6]))
是稳定的,时间复杂度,最好
,最差
,空间复杂度
。
2. 折半插入排序——升序
#折半插入排序 升序排序
def bi_insert_sort(a):
length = len(a)
for i in range(1, length):
low = 0
high = i - 1
temp = a[i]
while low <= high:
mid = (low + high) // 2
if a[mid] <= temp:
low = mid + 1
else:
high = mid - 1
for j in range(i, low, -1):
a[j] = a[j - 1]
a[low] = temp
return a
print(bi_insert_sort([2, 5, 2, 7, 1, 6]))
折半插入排序算法相比较于直接插入排序算法,只是减少了关键字间的比较次数,而记录的移动次数没有进行优化,所以该算法的时间复杂度仍是
3. 希尔排序
#希尔排序 升序排序
def shell_sort(a):
length = len(a)
interval = length // 2
while interval > 0:
for i in range(interval, length):
j = i - interval
if a[i] < a[j]:
temp = a[i]
while j > -1:
if a[j] > temp:
a[j + interval] = a[j]
j -= interval
else:
break
a[j + interval] = temp
interval = interval // 2
return a
print(shell_sort([49, 38, 64, 97, 76, 13, 27, 49, 55, 4]))
不稳定;
一般的初次取序列的一半为增量,以后每次减半,直到增量为1;
对于关键字的值较小的记录,其前移的过程不是一步一步的,而是跳跃性的前移,并且在最后一次对整表进行插入排序时减少了比较和排序的次数。时间复杂度,近似为O(N^1.25)
4. 冒泡排序
#冒泡排序 升序排序
def swap(index1, index2, a):
temp = a[index1]
a[index1] = a[index2]
a[index2] = temp
return a
def soap_sort(a):
length = len(a)
for i in range(length):
for j in range(1, length - i):
if a[j - 1] > a[j]:
a = swap(j, j - 1, a)
return a
print(soap_sort([49, 38, 64, 97, 76, 13, 27, 49, 55, 4]))
若表中记录本身为正序存放,则整个排序过程只需进行 n-1(n 为表中记录的个数)次比较,且不需要移动记录;若表中记录为逆序存放(最坏的情况),则需要 n-1趟排序,进行 n(n-1)/2 次比较和数据的移动。所以该算法的时间复杂度为
5. 快速排序
#快速排序 升序排序
def q_sort(a, low, high):
temp = a[low]
start = low
end = high
while low < high:
while low < high and a[high] >= temp:
high -= 1
a[low] = a[high]
while low < high and a[low] <= temp:
low += 1
a[high] = a[low]
a[low] = temp
if start < low - 1:
a = q_sort(a, start, low - 1)
if low + 1 < end:
a = q_sort(a, low + 1, end)
return a
def quick_sort(a):
length = len(a)
a = q_sort(a, 0, length - 1)
return a
print(quick_sort([49, 38, 64, 97, 76, 13, 27, 49, 55, 4]))
快速排序算法的平均时间复杂度为O(nlogn)
,是所有时间复杂度相同的排序方法中性能最好的排序算法,不稳定。
最坏情况发生在每次划分过程产生的两个区间分别包含n-1个元素和1个元素的时候,运行时间为
最好情况是每次划分过程产生的区间大小都为n/2,时间复杂度为O(nlogn)
6. 选择排序
#选择排序 升序排序
def swap(a, index1, index2):
temp = a[index1]
a[index1] = a[index2]
a[index2] = temp
return a
def select_sort(a):
length = len(a)
for i in range(length):
temp = a[i]
index = i
for j in range(i, length):
if a[j] < temp:
index = j
temp = a[j]
a = swap(a, i, index)
return a
print(select_sort([49, 38, 64, 97, 76, 13, 27, 49, 55, 4]))
运行时间为,比较次数没有好坏之分,移动有,稳定。
7. 堆排序
class Solution:
def __init__(self):
self.minNums=[]
self.maxNums=[]
def maxHeapInsert(self,num):
self.maxNums.append(num)
lens = len(self.maxNums)
i = lens - 1
while i > 0:
if self.maxNums[i] > self.maxNums[(i - 1) / 2]:
t = self.maxNums[(i - 1) / 2]
self.maxNums[(i - 1) / 2] = self.maxNums[i]
self.maxNums[i] = t
i = (i - 1) / 2
else:
break
def maxHeapPop(self):
t = self.maxNums[0]
self.maxNums[0] = self.maxNums[-1]
self.maxNums.pop()
lens = len(self.maxNums)
i = 0
while 2 * i + 1 < lens:
nexti = 2 * i + 1
if (nexti + 1 < lens) and self.maxNums[nexti + 1] > self.maxNums[nexti]:
nexti += 1
if self.maxNums[nexti] > self.maxNums[i]:
tmp = self.maxNums[i]
self.maxNums[i] = self.maxNums[nexti]
self.maxNums[nexti] = tmp
i = nexti
else:
break
return t
def minHeapInsert(self,num):
self.minNums.append(num)
lens = len(self.minNums)
i = lens - 1
while i > 0:
if self.minNums[i] < self.minNums[(i - 1) / 2]:
t = self.minNums[(i - 1) / 2]
self.minNums[(i - 1) / 2] = self.minNums[i]
self.minNums[i] = t
i = (i - 1) / 2
else:
break
def minHeapPop(self):
t = self.minNums[0]
self.minNums[0] = self.minNums[-1]
self.minNums.pop()
lens = len(self.minNums)
i = 0
while 2 * i + 1 < lens:
nexti = 2 * i + 1
if (nexti + 1 < lens) and self.minNums[nexti + 1] < self.minNums[nexti]:
nexti += 1
if self.minNums[nexti] < self.minNums[i]:
tmp = self.minNums[i]
self.minNums[i] = self.minNums[nexti]
self.minNums[nexti] = tmp
i = nexti
else:
break
return t
时间复杂度,空间复杂度
,胜在后期每插入一个数字,排好只需要
,比较和移动次数没有好坏之分,不稳定。
8. 归并排序
def merge(a, b):
c = []
h = j = 0
while j < len(a) and h < len(b):
if a[j] < b[h]:
c.append(a[j])
j += 1
else:
c.append(b[h])
h += 1
if j == len(a):
for i in b[h:]:
c.append(i)
else:
for i in a[j:]:
c.append(i)
return c
def merge_sort(lists):
if len(lists) <= 1:
return lists
middle = len(lists)/2
left = merge_sort(lists[:middle])
right = merge_sort(lists[middle:])
return merge(left, right)
print merge_sort([4, 7, 8, 3, 5, 9])
归并排序算法的时间复杂度为,空间复杂度
,比较和移动次数没有好坏之分,稳定。