当前位置:   article > 正文

算法导论—排序算法总结_算法导论 排序

算法导论 排序

华电北风吹

天津大学认知计算与应用重点实验室

最后修改日期:2015/8/22


声明:本文涉及的所有排序算法定义功能对输入进行从小到大排序

符号解释:

     n:输入数据个数

Θ(n):n的同阶无穷大


Part I Array Sort

一、选择排序

  1. def SelectSort(a):
  2. for i in range(0,len(a)-1):
  3. minIndex=i
  4. for j in range(i+1,len(a)):
  5. if a[j]<a[minIndex]:
  6. minIndex=j
  7. if minIndex !=i:
  8. temp=a[minIndex]
  9. a[minIndex]=a[i]
  10. a[i]=temp
  11. return a
  12. a=[2,5,3,8,6,1,4,9]
  13. SelectSort (a)
  14. print(a)
从前往后,依次选择当前位置以后最小的数与当前位置交换

计算复杂度theta(n^2)

二、冒泡排序

  1. def BubbleSort (a):
  2. k=len(a)
  3. for i in range(0,k-1):
  4. for j in range(k-1,i,-1):
  5. if a[j]<a[j-1]:
  6. a[j-1],a[j]=a[j],a[j-1]
  7. return a
  8. a=[2,5,3,8,6,7,1,4,9]
  9. BubbleSort (a)
  10. print(a)

从前往后,反复交换相邻的未按次序排列的元素

计算复杂度theta(n^2)

三、插入排序

  1. def InsertSort(a):
  2. for j in range(1,len(a)):
  3. key=a[j]
  4. i=j-1
  5. while(i>=0 and a[i]>key):
  6. a[i+1]=a[i]
  7. i=i-1
  8. a[i+1]=key
  9. a=[2,5,3,8,6,1,4,9]
  10. InsertSort (a)
  11. print(a)

从前往后,讲下一个数据插入到前面已经排好序的数组里面

最好的情况:已经从小到大排好序,计算复杂度theta(n)

最坏的情况:输入顺序为从大到小,计算复杂度theta(n^2)

当数据量很大的时候,不必要一个一个往前找,可以根据二分发,减少计算量

 四、归并排序

  1. def MergeSort(a):
  2. n=len(a)
  3. if n==1:
  4. return a
  5. mid=(n+1)//2
  6. b=MergeSort(a[0:mid])
  7. c=MergeSort(a[mid:n])
  8. i=0
  9. j=0
  10. b.append(float("inf"))
  11. c.append(float("inf"))
  12. for k in range(0,n):
  13. if b[i]<c[j]:
  14. a[k]=b[i]
  15. i+=1
  16. else:
  17. a[k]=c[j]
  18. j+=1
  19. return a
  20. a=[2,5,3,8,6,7,1,4,9]
  21. MergeSort (a)
  22. print(a)

分治策略,先划分子序列,后归并排序

计算复杂度theta(nlog(n))

注意:非原址运算

 五、堆排序

  1. def HeapAdjust(lst,k,n):
  2. while(2*k+1<n):
  3. j=2*k+1
  4. if j+1<n and lst[j]<lst[j+1]:
  5. j=j+1
  6. if lst[j]>lst[k]:
  7. lst[k],lst[j]=lst[j],lst[k]
  8. k=j
  9. else:
  10. break
  11. return lst
  12. def HeapSort(lst):
  13. n=len(lst)
  14. for i in range(n//2-1,-1,-1):
  15. lst=HeapAdjust(lst,i,n)
  16. for i in range(n-1,0,-1):
  17. lst[0],lst[i]=lst[i],lst[0]
  18. lst=HeapAdjust(lst,0,i)
  19. return lst
  20. a=[1,5,2,8,3,4,6,9,7]
  21. HeapSort(a)
  22. print(a)

代码注释:http://blog.csdn.net/zhangzhengyi03539/article/details/44889951

构建大根堆,然后堆顶元素与序列最后一个元素交换,序列长度减一,对堆顶元素构建大根堆

计算复杂度theta(nlogn)

我觉得这个算法还有可能改进的地方,因为每次堆顶元素与最后一个元素交换,而最后一个元素是大根堆叶子上的元素,也就是在这条支路中最小的元素,这样在重新对堆顶元素构建大根队的过程中需要迭代好多步骤。

 

六、快速排序

例子一:

  1. def QuickSort(a,start,end):
  2. key=a[start]
  3. i=start+1
  4. j=end
  5. while i<j:
  6. while a[i]<=key and i<j:
  7. i+=1
  8. while a[j]>key and j>i-1:
  9. j-=1
  10. if i<j:
  11. a[i],a[j]=a[j],a[i]
  12. a[start],a[j]=a[j],a[start]
  13. if j-1>start:
  14. QuickSort(a,start,j-1)
  15. if j+1<end:
  16. QuickSort(a,j+1,end)
  17. return a
  18. a=[1,5,2,8,3,4,6,9,7]
  19. QuickSort(a,0,len(a)-1)
  20. print(a)

例子二:

  1. def QuickSort(a,start,end):
  2. key=a[end]
  3. i=start-1
  4. for j in range(start,end):
  5. if a[j]<key:
  6. i+=1
  7. a[i],a[j]=a[j],a[i]
  8. a[i+1],a[end]=a[end],a[i+1]
  9. if i>start:
  10. QuickSort(a,start,i)
  11. if i+2<end:
  12. QuickSort(a,i+2,end)
  13. return a
  14. a=[1,5,2,8,3,4,6,9,7]
  15. QuickSort(a,0,len(a)-1)
  16. print(a)

分治策略,最好的情况当然是每次都是二分了

平均情况/期望情况:计算复杂度theta(nlogn)

最坏的情况:计算复杂度theta(n^2)

 对于例子二,考虑这样一种情况,输入序列最后一个是最大的,然后对j循环的时候每次都要执行交换操作。还有就是快速排序的随机化版本,每次从输入中随机挑选一个数与key所在的数交换,然后执行快速排序。


Part II List Struct Sort

  1. #include <iostream>
  2. using namespace std;
  3. struct Node
  4. {
  5. int val;
  6. Node * Next;
  7. };
  8. Node* MergeList(Node* root1, Node* root2)
  9. {
  10. Node* root = new Node;
  11. Node*p = root, *p1 = root1, *p2 = root2;
  12. while ((p1!=NULL)&&(p2!=NULL))
  13. {
  14. if (p1->val <= p2->val)
  15. {
  16. p->Next = p1;
  17. p = p->Next;
  18. p1 = p1->Next;
  19. }
  20. else
  21. {
  22. p->Next = p2;
  23. p = p->Next;
  24. p2 = p2->Next;
  25. }
  26. }
  27. if (p1 != NULL)
  28. p->Next = p1;
  29. else
  30. p->Next = p2;
  31. p = root->Next;
  32. delete root;
  33. return p;
  34. }
  35. Node* MergeSort(Node* root)
  36. {
  37. if ((root == NULL) || (root->Next == NULL))
  38. return root;
  39. int length = 0;
  40. Node*p = root;
  41. while (p!=NULL)
  42. {
  43. length++;
  44. p = p->Next;
  45. }
  46. p = root;
  47. Node *root2;
  48. for (int i = 0; i < length / 2-1; i++)
  49. {
  50. p = p->Next;
  51. }
  52. root2 = p->Next;
  53. p->Next = NULL;
  54. root = MergeSort(root);
  55. root2 = MergeSort(root2);
  56. root = MergeList(root, root2);
  57. return root;
  58. }
  59. int main()
  60. {
  61. Node *p1 = new Node{ 6,NULL };
  62. Node *p2 = new Node{ 3,NULL };
  63. Node *p3 = new Node{ 9,NULL };
  64. Node *p4 = new Node{ 7,NULL };
  65. Node *p5 = new Node{ 1,NULL };
  66. Node *p6 = new Node{ 2,NULL };
  67. Node *p7 = new Node{ 4,NULL };
  68. p1->Next = p2;
  69. p2->Next = p3;
  70. p3->Next = p4;
  71. p4->Next = p5;
  72. p5->Next = p6;
  73. p6->Next = p7;
  74. Node*p = p1;
  75. while (p != NULL)
  76. {
  77. cout << p->val << " ";
  78. p = p->Next;
  79. }
  80. cout << endl;
  81. p1 = MergeSort(p1);
  82. p = p1;
  83. while (p!=NULL)
  84. {
  85. cout << p->val << " ";
  86. p = p->Next;
  87. }
  88. cout << endl;
  89. return 0;
  90. }


Part II List Struct Sort
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/500443
推荐阅读
相关标签
  

闽ICP备14008679号