算法之排序算法总结

来源:互联网 发布:成立淘宝客团队 编辑:程序博客网 时间:2024/06/05 17:19

个人总结,仅供参考。详细内容请阅读《Introduce to Algorithm》算法导论

heap sort

  • 用数组存储最大堆,用二叉树表示最大堆特征结构
    图1(heap与array对应关系)
    这里写图片描述
Parent(i)
return i/2 取下等
Left(i)
return 2i
Right(i)
return 2i+1

max-heap的特征 : A[Parent(i)]>=A[i]

method:

  • maxHeapity:时间复杂程度为O(lgn), 是维护max-heap性质的关键.
  • buildMaxHeap:线性时间复杂程度, 输入一个乱序的数组,最终生成最大堆.
  • heapSort:时间复杂程度为O(nlgn), 对数组进行排序.
  • maxHeapInsert、heapExtractMax、heapIncreaseKey、heapMaximum : 时间复杂程度为O(lgn) , 利用堆实现优先级队列.

图2(求maxHeapity)
maxHeapity

//maxHeapity : 假设节点i的左右子树都已经是最大堆maxHeapity(A, i ) {  l = Left(i)  r = Right(i)  largest = i  if l <= A.hipeSize && A[l] > A[i]    largest = l  if r < A.heapSize && A[r] > A[largest]    largest = r  if largest != i    exchange A[i] with A[largest] //**不稳定**    maxHeapity(a, largest)}

图3(buidMaxHeap)
buidMaxHeap

buildMaxHeap(A) {  A.heapSize = A.length      for i = A.length/2 to 1 //取下等         maxHeapity(A, i)}heapSort(A) {  buildMaxHeap(A)  for i = A.length dowmto 2    exchange A[1] with A[i]    A.heapSize = A.heapSize - 1    maxHeapity(A, 1)}
  • priority queue:根据排序数值的大小,确定优先级
heapMaximum(A){ return A[1]}heapExtractMax(A) {  if A.heapSize < 1    error "heap underflow"  max = A[1]  A[1] = A[A.heapSize]  A.heapSize = A.heapSize -1  maxHeapity(A, 1)  return max}heapIncreaseKey(A, i, key) {  if key < A[i]    error "new key is smaller than current key"  A[i] = key  while i > 1 and A[PARENT[i] < A[i]]   exchange A[i] with A[PARENT[i]]   i = PARENT[i]}maxHeapInsert(A, key) {  A.heapSize = A.heapSize + 1  A[A.heapSize] = -@  heapIncreaseKey(A, A.heapSize ,key)}

扩展:思考如何使用FIFO队列,FILO栈实现优先级队列。

quick sort

  • 思路:拆分–根据pivot把数组分为两半
    图4(partition示意图)
    partition
quickSort(A, p, r) {  if p < r    q = partition(A, p, r)    quickSort(A, p, q - 1)    quickSort(A, q + 1, r)}partition(A, p, r) {  x = A[r]  i = p - 1  for j = p to r -1    if A[j] <= x      i = i + 1      exchange A[i] with A[j]   // **不稳定**  exchange A[i + 1] with A[r]  return i + 1}

扩展:注意我们选择的partition选取的pivot总是最后一个数,思考如何实现随机选取pivot。文章底部给出实现思路。

insert,bubble,select sort O(n2)

  • bubble : 找到最大数,移到最后
  • Insert :从后插入到排好序的数值
  • shell : 缩小增量排序,又叫分组插入排序法,根据增量分成相应的组,再缩小增量,到1。
  • select : 从待排序的数组中选出最大或最小元素,与起始位置交换 //不稳定
insertSort(A) {  for j = 2 to A.length    key = A[j]    //Insert A[j] into the sorted sequence A[1..j - 1]    i = j - 1    while i > 0 && A[i] > key      A[i + 1] = A[i]      i = i - 1    A[i + 1] = key  }

merge sort

  • 思路:先拆分,再合并排好序的两个数组
mergeSort(A, p, r) {  if p < r    q = _(p + r)/2_    mergeSort(A, p , q)    mergeSort(A, p + 1, r)    merge(A, p, q, r)}merge(A, p, q, r) {  n1 = q - p + 1  n2 = r - q  let L[1..n1 + 1] and R[1..n2 + 1] be new array  for i = 1 to n1    L[i] = A[p + i -1]  for j = 1 to n2    R[j] = A[q + j]  L[n1 + 1] = @  R[n2 + 1] = @  i = 1  j = 1  for k = p to r    if L[i] <= R[j]      A[k] = L[i]      i = i + 1    else A[k] = R[j]      j = j + 1}

bucket sort

适合场景:输入的n个数在很小的一个区间内, 平均时间复杂程度为O(n).
图5(桶排序示意图)
bucketSort

bucketSort(A) {  let B[0..n - 1] be a new array  n = A.length  for i = 0 to n - 1    make B[i] an empty list  for i = 1 to n    insert A[i] into list B[_nA[i]_]  for i = 0 to n - 1    sort list B[i] with insertion sort  concatenate the list B[0]...B[n - 1] together in order}

radix sort

假设数组A中的元素都是d位数的整数,1是最小的位数,d是最高的位数。如图6是由d = 3 组成的数组
图6(radixSort示意图)
radixSort

radixSort(A, d) {  for i = 1 to d    use a stable sort to sort array A on digit i}

图7(排序算法总结)
排序算法总结

//随机快排quickSortRandom(A, p, r) {  if p < r    q = partitionRandom(A, p, r)    quickSortRandom(A, p, q - 1)    quickSortRandom(A, q + 1, r)}partitionRandom(A, p, r) {  x = random(p, r);  exchange A[x] with A[r]  return partition(A, p, r)}
2 0
原创粉丝点击