第二次看算法导论,感觉对这本书的精髓有了更进一步的掌握,在此,把我认为比较重要的排序算法做一个总结,欢迎大家批评指正!
排序算法从大的概念分为比较排序和非比较排序,
比较排序包括:合并排序、堆排序、快速排序
非比较排序: 计数排序、桶排序、基数排序
一、插入排序:
1、简单介绍:插入排序作为最基本的入门排序,算法思想最简单,最容易实现。
该算法是一个就地排序算法,思想是:将数组A中的元素A[1......n]依此插入到已经拍好序的sequenceA中。
2、时间复杂度: best: O(n) average: O(n^2) worst: O(n^2)
3、空间复杂度: O(1)
4、插入排序的数据结构
INSERTION-SORT(A)
for j <- 2 to length[A]
do key <- A[j]
# Insert A[j] into the sorted sequence A[1...j-1].
i <- j-1
while i>0 and A[i]>key
do A[i+1] <- A[i]
i <- i-1
A[i+1] <- key
5、python实现插入排序代码:
'''
insert_sort
author: fuhongyu
time: 2018-07-27
time compliexity:O(n^2)
objective: 10 minutes
'''
def inser_sort(lists):
for i in range(1,len(lists)):
key = lists[i]
j = i-1
# insert lists[j] into sequence lists
while j >= 0:
if lists[j] > key:
lists[j+1] = lists[j]
lists[j] = key
j -= 1
return lists
二、合并排序:
1、简单介绍:合并排序采取了分治法的思想,在每一层递归上都有三个步骤:<1>分解 <2>解决 <3> 合并
2、时间复杂度:best: O(n*logn) average: O(n*logn) worst: O(n*logn)
3、空间复杂度:O(n)
4、合并排序算法数据结构:
MERGE_SORT(A, p, r)
if p < r
then q <- (p+r)/2 # 取下限
MERGE_SORT(A, p, q)
MERGE_SORT(A, q+1, r)
MERGE(A, p, q, r)
5、python实现合并排序算法代码:
'''
merge_sort
author: fuhongyu
time: 2018-07-27
time complexity: O(n^2)
objective:15 minutes
'''
def merge(a ,b):# 合并两个list
i = 0
j = 0
result = []
while i<len(a) and j <len(b):
if a[i] < b[j]:
result.append(a[i])
i += 1
else:
result.append(b[j])
j += 1
if i == len(a):
for i in b[j:]:
result.append(i)
else:
for i in a[i:]:
result.append(i)
return result
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)
测试排序函数:
lists = [3,4,2,6,4,8,3,0,20,34,1,4,56,3]
merge_sort(lists)
6、补充:归并算法,归即递归,并即合并。该算法运行速度很快,但因为是递归算法,故对CPU消耗很大
三、堆排序:
1、简单介绍:像合并排序而不像插入排序,堆排序的运行时间是O(n*logn)。像插入排序而不像合并排序,他是一种原地排序算法,在任何时候,数组中只有常数个元素存储在输入数组以外。这样,堆排序就把上述两种排序的算法的优点结合起来了。
2、时间复杂度: best: O(n*logn) average: O(n*logn) worst: O(n*logn)
3、空间复杂度:O(1)
4、算法说明:堆排序过程主要分为三步:
1)保持堆的性质:将堆调整为最大堆:MAX-HEAPIFY(A, i),使i为根的子树称为最大堆。
2)建堆: BUILD-MAX-HEAPIFY :将一个数组A[1...n]变成一个最大堆。
3)堆排序算法:HEAPSORT(A) : 将数组A进行排序
5、python实现代码如下:
'''
function:heap sort
author: fuhongyu
time: 2018-07-28
completion:15 minutes
time complecity:O(n*logn)
'''
def max_heap(lists, i, size):
lchild = 2*i
rchild = 2*i+1
max = i
if lchild < size and lists[lchild] > lists[max]:
max = lchild
if rchild < size and lists[rchild] > lists[max]:
max = rchild
if max != i:
lists[i] , lists[max] = lists[max], lists[i]
max_heap(lists, max, size)
def build_heap( lists):
size = len(lists)
for i in range(0, size//2)[::-1]:
max_heap(lists, i, size)
return lists
def heap_sort( lists):
size = len(lists)
lists = build_heap(lists)
print(lists)
for i in range(0, size)[::-1]:
lists[i], lists[0] = lists[0], lists[i]
max_heap(lists, 0 ,i)
print(lists)
测试上面的程序:
lists = [4,1,3,2,16,9,10,14,8,7]
heap_sort(lists)
6、应用:
虽然堆排序算法是一个很漂亮的算法,但在实际中,快速排序的一个好的实现往往优于堆排序。尽管这样,堆数据结构还是有很大的用处。一个很常见的应用就是:作为高效的优先级队列,包括最大优先级队列和最小优先级队列,分别对应最大堆和最小堆。
一个堆可以在O(lgn)时间内,支持大小为n的集合上的任意优先队列的操作。
四、快速排序:
接下来要讲的快速排序通常情况下,是用于排序的最佳的实用选择。这是因为其平均性能相当好:期望的运行时间为O(nlogn),且O(nlogn)记号中隐藏的常数因子很小。另外,它还能够进行就地排序,在虚存环境中也能很好地工作。接下来我们便来好好了解一下快速排序的思想。
1、时间复杂度: best: O(n*logn) average: O(n*logn) worst: O(n^2)
2、空间复杂度: O(logn)
3、算法描述:
像合并排序一样,快速排序也是基于分支模式的,主要分为以下三个步骤:分解、解决、合并
4、快速排序的数据结构:
QUICKSORT(A, p, r)
if p<r
then q <- PARTITION(A, p, r)
QUICKSORT(A, p, q-1)
QUICKSORT(A, q+1, r)
为排序一个完整的数组A,最初的调用是QUICKSORT(A, 1, length(A))
快速排序算法的关键是PARTITION过程,它对子数组A[p...r]进行就地重排:
PARTITION(A,p, r)
x <- A[r]
i <- p-1
for j <- p to r-1
do if A[j]<=x
then i <- i+1
exchange A[i] <-> A[j]
exchange A[i+1] <-> A[r]
return i+1
5、python实现快速排序代码:
'''
quick_sort
author: fuhongyu
time: 2018-07-27
time complecity: O(nlog(n))
object:15 minutes
'''
def quick_sort(array, l, r):
if l < r:
q = partition(array, l, r)
quick_sort(array, l, q - 1)
quick_sort(array, q + 1, r)
return array
def partition(array, l, r):
x = array[r]
i = l - 1
for j in range(l, r):
if array[j] <= x:
i += 1
array[i], array[j] = array[j], array[i]
array[i + 1], array[r] = array[r], array[i+1]
return i + 1
测试快速排序代码:
lists = [3,5,1,2,7]
quick_sort(lists, 0, len(lists)-1)
五、冒泡排序:
1、简单说明:冒泡排序的实现非常简单,时间复杂度大,但是作为经典的排序算法还是值得一提的。
2、python 实现冒泡排序算法代码:
'''
bubbling_sort
author: fuhongyu
time: 2018年7月27日
时间复杂度: n^2
目标:5 minutes
'''
def bubblesort(lists):
for i in range(len(lists)-1):
for j in range(i+1 , len(lists)):
if lists[i] > lists[j]:
temp = lists[i]
lists[i] = lists[j]
lists[j] = temp
return lists