插入排序
插入排序是一种简单直观的排序方法,其基本思想在于每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录插入完成。
直接插入排序
例如list1=[5,3,4,2,1]。根据直接插入排序,我们将从1到len(list1)的数进行插入,首先3与5比较。i=1,j=0 大于等于0,3小于5插入,list1[1]=list1[0]。 j = − 1 j=-1 j=−1,则list1[0]=data=3.
- 空间复杂度: O ( 1 ) O(1) O(1)
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 稳定
最好情况下列表有序,只需要比较不需要插入,时间复杂度为 O ( n ) O(n) O(n);
最坏情况下,列表逆序,空间复杂度为 O ( n 2 ) O(n^2) O(n2)
def InsertSort(list1):
for i in range(1,len(list1)):
Data=list1[i]
j=i-1
while j>=0:
if Data<list1[j]:
list1[j+1]=list1[j]
j=j-1
else:
break
list1[j+1]=Data
return list1
折半插入排序
先折半查找出元素的待插入位置,然后再统一地移动待插入位置之后的所有元素。当表为顺序表时可以用折半查找来实现。
- 空间复杂度: O ( 1 ) O(1) O(1)
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 稳定
def binaryInsert(list1):
for i in range(1, len(list1)):
data = list1[i]
low = 0
high = i-1
while low <= high:
mid = (low + high) // 2
if data > list1[mid]:
low = mid + 1
else:
high = mid - 1
# 跳出循环后 low, mid 都是一样的, high = low - 1
for j in range(i, low, -1):
list1[j] = list1[j - 1]
list1[low] = data
return list1
希尔排序
希尔排序的每一次排序都是 i,i+gap,i+2gap…的插入排序
- 空间复杂度: O ( 1 ) O(1) O(1)
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 不稳定的
def shell_sort(list1):
n = len(list1)
gap = n // 2
while gap >= 1:
for i in range(gap, n):
while (i-gap)>=0:
if list1[i] < list1[i - gap]:
list1[i], list1[i - gap] = list1[i - gap], list1[i]
else:
break
i=i-gap
gap //=2
return list1
交换排序
所谓交换,就是根据序列中两个元素的关键字的比较结果来对换这两个记录在序列的位置。
冒泡排序
- 空间复杂度: O ( 1 ) O(1) O(1)
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 稳定的
def bubblesort(list1):
for i in range(len(list1)-1):
for j in range(len(list1)-i-1):
if list1[j]>list1[j+1]:
list1[j],list1[j+1]=list1[j+1],list1[j]
return list1
def bubble_sort(list1):
n=len(list1)
for i in range(n-1):
temp=list1[0]
index=0
for j in range(n-i):
if list1[j]>temp:
temp=list1[j]
index=j
list1[index],list1[n-i-1]=list1[n-i-1],list1[index]
return list1
快速排序
- 空间复杂度:平均情况为 O ( l o g 2 n ) O(log_2n) O(log2n)
- 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
- 不稳定的
def quicksort(array,low,high):
if low < high:
pivotpops = partion(array,low,high)
quicksort(array,low,pivotpops-1)
quicksort(array,pivotpops+1,high)
def partion(array,low,high):
pivot = array[low]
while low < high: #找出最终位置
while low < high and array[high] >= pivot: #找出右侧比该数小的数
high -= 1
if low<high:
array[low] = array[high]
while low < high and array[low] <= pivot: #找出左侧比该数大的数
low += 1
if low<high:
array[high] = array[low]
array[low] = pivot
return low
选择排序
选择排序的基本思想是:每一趟(例如第i趟)在后面(n-i+1)个待排序元素中选区关键字最小的元素,作为有序子序列的第i个元素。
简单选择排序
- 空间复杂度: O ( 1 ) O(1) O(1)
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 不稳定的
def SelectionSort(list1):
for i in range(0,len(list1)):
mini=list1[i]
index=i
for j in range(i+1,len(list1)):
if list1[j]<mini:
mini=list1[j]
index=j
list1[index],list1[i]=list1[i],list1[index]
return list1
堆排序
- 空间复杂度: O ( 1 ) O(1) O(1)
- 时间复杂度: O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
- 不稳定
def fixDown(a,k,n):
N=n-1
while 2*k<=N:
j=2*k
if j<N and a[j]<a[j+1]:
j+=1
if a[k]<a[j]:
a[k],a[j]=a[j],a[k]
k=j
else:
break
def heapSort(l):
n=len(l)-1
for i in range(n//2,0,-1):
fixDown(l,i,len(l))
while n>1:
l[1],l[n]=l[n],l[1]
fixDown(l,1,n)
n-=1
return l[1:]
归并排序和基数排序
“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。
归并排序
def merge(left, right):
i, j = 0, 0
result = []
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]
return result
def merge_sort(lists):
# 归并排序
if len(lists) <= 1:
return lists
num = len(lists) // 2
left = merge_sort(lists[:num])
right = merge_sort(lists[num:])
return merge(left, right)