DB_Algorithm_and_Data_Structure_About_Sort

1,611 views

Published on

数据结构与算法.02.排序算法

Published in: Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,611
On SlideShare
0
From Embeds
0
Number of Embeds
312
Actions
Shares
0
Downloads
92
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

DB_Algorithm_and_Data_Structure_About_Sort

  1. 1. 数据结构与算法 ——排序相关 MySQL DBA 彭立勋 Alibaba B2B DBA Team
  2. 2. <ul><li>O(N^2) 排序 </li></ul><ul><li>冒泡排序 </li></ul><ul><li>选择排序 </li></ul><ul><li>插入排序 </li></ul><ul><li>O(N*LogN) 排序 </li></ul><ul><li>快速排序 </li></ul><ul><li>归并排序 </li></ul><ul><li>堆排序 </li></ul><ul><li>树排序 </li></ul><ul><li>O(N) 排序 </li></ul><ul><li>桶排序 </li></ul><ul><li>基数排序 </li></ul><ul><li>希尔排序 </li></ul>数据结构与算法——排序相关
  3. 3. <ul><li>区间排序 </li></ul><ul><li>ShortSort (Oracle) </li></ul><ul><li>TopK 算法 (Knuth) </li></ul><ul><li>TopMN 算法 (P.Linux) </li></ul>数据结构与算法——排序相关
  4. 4. 冒泡排序 <ul><li>它重复地访问要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。访问数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 </li></ul><ul><li>FOR I = 1 TO N-1 DO </li></ul><ul><li>FOR J = I+1 TO N DO </li></ul><ul><li>IF (A[i]>A[j]) THEN swap(A[i],A[j]); </li></ul><ul><li>END FOR </li></ul><ul><li>END FOR </li></ul>数据结构与算法——排序相关
  5. 5. 冒泡排序 <ul><li>数据结构:数组 </li></ul><ul><li>最差时间复杂度: O ( n 2 ) </li></ul><ul><li>最优时间复杂度: O ( n )—— 因为可以通过判断一轮比较后是否有交换来判定排序是否完成 </li></ul><ul><li>平均时间复杂度: O ( n 2 ) </li></ul><ul><li>最差空间复杂度: O ( n ) total,  O (1) auxiliary </li></ul>数据结构与算法——排序相关
  6. 6. 冒泡排序 数据结构与算法——排序相关
  7. 7. 选择排序 <ul><li>首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。 </li></ul><ul><li>FOR I = 1 TO N DO </li></ul><ul><li>A[i] = FindMin(I,N); </li></ul><ul><li>END FOR </li></ul>数据结构与算法——排序相关
  8. 8. 选择排序 <ul><li>数据结构:数组 </li></ul><ul><li>最差时间复杂度: О( n²) </li></ul><ul><li>最优时间复杂度: О( n²) </li></ul><ul><li>平均时间复杂度: О( n²) </li></ul><ul><li>最差空间复杂度: О( n)  total,  O(1) auxiliary </li></ul>数据结构与算法——排序相关
  9. 9. 选择排序 数据结构与算法——排序相关
  10. 10. 插入排序 <ul><li>它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 </li></ul><ul><li>FOR I = 2 TO N DO </li></ul><ul><li>J = FindPos(1,I-1,x); // 在有序的序列中找 X 的位置 </li></ul><ul><li>MoveNext(J,I); // 将需要占用位置的元素后移 </li></ul><ul><li>A[J] = x; // 空出的位置放入 X </li></ul><ul><li>END FOR </li></ul>数据结构与算法——排序相关
  11. 11. 插入排序 <ul><li>数据结构:数组 </li></ul><ul><li>最差时间复杂度: О( n²) </li></ul><ul><li>最优时间复杂度: О( n²) </li></ul><ul><li>平均时间复杂度: О( n²) </li></ul><ul><li>最差空间复杂度: О( n)  total,  O(1) auxiliary </li></ul>数据结构与算法——排序相关
  12. 12. 快速排序 <ul><li>从数列中挑出一个元素,称为 &quot; 基准 &quot; ,重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。这个称为分割操作。递归地( recursive )把小于基准值元素的子数列和大于基准值元素的子数列排序。 </li></ul>数据结构与算法——排序相关
  13. 13. 快速排序 <ul><li>数据结构: Varies </li></ul><ul><li>最差时间复杂度: Θ( n 2 ) </li></ul><ul><li>最优时间复杂度: Θ(nlogn) </li></ul><ul><li>平均时间复杂度: Θ(nlogn) comparisons </li></ul><ul><li>最差空间复杂度根据实现的方式不同而不同 </li></ul>数据结构与算法——排序相关
  14. 14. 快速排序 数据结构与算法——排序相关
  15. 15. 归并排序 <ul><li>元素首先分组,每组元素进行比较。然后每组元素看成一个元素,再分组比较。递归此过程直到只有一组元素的时候排序完成。 </li></ul><ul><li>void merge_sort(int arr[], int first, int last) { </li></ul><ul><li>int mid = 0; </li></ul><ul><li>if(first<last) { </li></ul><ul><li>mid = (first+last)/2; // 分成两组分别排序 </li></ul><ul><li>merge_sort(array, first, mid); // 对一个分组排序 </li></ul><ul><li>merge_sort(array, mid+1,last); // 对另一个分组排序 </li></ul><ul><li>merge(array,first,mid,last); // 归并两组排序 </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>数据结构与算法——排序相关
  16. 16. 归并排序 <ul><li>数据结构:数组 </li></ul><ul><li>最差时间复杂度: Θ( n log n ) </li></ul><ul><li>最优时间复杂度: Θ( n ) </li></ul><ul><li>平均时间复杂度: Θ( n log n ) </li></ul><ul><li>最差空间复杂度: Θ( n ) </li></ul>数据结构与算法——排序相关
  17. 17. 归并排序 数据结构与算法——排序相关
  18. 18. 堆排序 <ul><li>堆积树是一个近似完全二叉树的结构,并同时满足堆的属性:即子结点的键值或索引总是小于(或者大于)它的父结点。 </li></ul><ul><li>WHILE ( 堆不为空 ) { </li></ul><ul><li>A[i++] = GetRootFromHeap; // 取出堆根 </li></ul><ul><li>ShiftHeap; // 调堆 </li></ul><ul><li>} </li></ul>数据结构与算法——排序相关
  19. 19. 堆排序 <ul><li>数据结构:数组 </li></ul><ul><li>最差时间复杂度: O ( nlogn ) </li></ul><ul><li>最优时间复杂度: O ( nlogn ) </li></ul><ul><li>平均时间复杂度: Θ( nlogn ) </li></ul><ul><li>最差空间复杂度: O ( n ) total,  O (1)auxiliary </li></ul>数据结构与算法——排序相关
  20. 20. 堆排序 数据结构与算法——排序相关
  21. 21. 树排序 <ul><li>首先按照搜索二叉树对数据建树,然后中序遍历搜索树,即可得到有序数列。 </li></ul><ul><li>普通二叉搜索树, AVL 平衡二叉树等。 </li></ul>数据结构与算法——排序相关
  22. 22. 树排序 <ul><li>数据结构:数组 </li></ul><ul><li>最差时间复杂度:平衡树 O ( nlogn ) </li></ul><ul><li>非平衡树 O ( n^2 ) </li></ul><ul><li>最优时间复杂度: O ( nlogn ) </li></ul><ul><li>平均时间复杂度: Θ( nlogn ) </li></ul><ul><li>最差空间复杂度: O ( n ) total,  O (1) auxiliary </li></ul>数据结构与算法——排序相关
  23. 23. 桶排序 <ul><li>不基于比较,为每个元素设一个计数器,记录每个元素出现多少次。 </li></ul><ul><li>FOR I = 1 TO N DO </li></ul><ul><li>C[A[i]]++; // 将元素丢入桶中 </li></ul><ul><li>END FOR </li></ul><ul><li>FOR I = 1 TO MAX DO </li></ul><ul><li>输出 C[i] 个 I; // 讲元素依次倒出桶 </li></ul><ul><li>END FOR </li></ul>数据结构与算法——排序相关
  24. 24. 桶排序 <ul><li>数据结构:数组 </li></ul><ul><li>最差时间复杂度: Θ (n) </li></ul><ul><li>最优时间复杂度: Θ (n) </li></ul><ul><li>平均时间复杂度: Θ (n) </li></ul><ul><li>最差空间复杂度: O ( MAX ) total </li></ul>数据结构与算法——排序相关
  25. 25. 基数排序 <ul><li>将所有待比较数值 ( 正整数 ) 统一为同样的数位长度 , 数位较短的数前面补零 . 然后 , 从最低位开始 , 依次进行一次排序 . 这样从最低位排序一直到最高位排序完成以后 , 数列就变成一个有序序列 . 基数排序的方式可以采用 LSD ( Least significant digital )或 MSD ( Most significant digital ), LSD 的排序方式由键值的最右边开始,而 MSD 则相反,由键值的最左边开始。 </li></ul>数据结构与算法——排序相关
  26. 26. 希尔排序 <ul><li>对有 n 个元素的可比较资料,先取一个小于 n 的整数 d1 作为第一个增量,把文件的全部记录分成 d1 个组。所有距离为 d1 的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量 d2<d1 重复上述的分组和排序,直至所取的增量 dt=1(dt<dt-1<…<d2<d1) ,即所有记录放在同一组中进行直接插入排序为止。 </li></ul><ul><li>该方法实质上是一种 分组插入方法 。 </li></ul>数据结构与算法——排序相关
  27. 27. ShortSort <ul><li>ShortSort(N) ,先从序列中取 N 个元素,建立一个堆,从 N+1 开始,依次和堆根元素做比较,比根元素大 ( 小 ) ,则替换堆的根元素,重新调堆,直到没有元素来比较。 </li></ul><ul><li>H = CreateHeap(N); // 建立前 N 个元素的堆 </li></ul><ul><li>FOR I = N+1 TO Max DO </li></ul><ul><li>IF (A[i] > H[0]) H[0] = A[i]; // 替换堆根 </li></ul><ul><li>ShiftHeap(); // 调堆 </li></ul><ul><li>END FOR </li></ul>数据结构与算法——排序相关
  28. 28. ShortSort <ul><li>数据结构:数组 </li></ul><ul><li>最差时间复杂度: O (n+ nlogk ) </li></ul><ul><li>最优时间复杂度: O (n+ klogk ) </li></ul><ul><li>平均时间复杂度: Θ( n+xlogn ) [k < x < n] </li></ul><ul><li>最差空间复杂度: O ( n ) total,  O (1)auxiliary </li></ul><ul><li>劣势:如果要最大的 N 个,而数据本身升序,那么每次都需要调堆,相当于完全排序。 </li></ul>数据结构与算法——排序相关
  29. 29. TopK <ul><li>利用二分思想,每次对元素分成左大右小两堆,判断左边的元素数量,如果大约 K 则继续二分左堆,如果已经小于 K ,那么取上次二分结果的左堆进行排序。 </li></ul><ul><li>WHILE (|LeftGroup[now]| > K) { </li></ul><ul><li>// 如果左堆元素多于 K 个则继续二分 </li></ul><ul><li>LeftGroup[1-now] = Split(LeftGroup[now]); </li></ul><ul><li>} </li></ul><ul><li>Sort(LeftGroup[1-now] ); // 在左堆中排序 </li></ul>数据结构与算法——排序相关
  30. 30. TopK <ul><li>数据结构:数组 </li></ul><ul><li>最差时间复杂度: O ((n+k)log(n/k)+ klogk ) </li></ul><ul><li>最优时间复杂度: O ((n+k)log(n/k)+ klogk ) </li></ul><ul><li>平均时间复杂度: Θ ((n+k)log(n/k)+ klogk ) </li></ul><ul><li>最差空间复杂度根据实现的方式不同而不同 </li></ul><ul><li>优势:利用随机的”基准”,可以有效避免全排序 </li></ul>数据结构与算法——排序相关
  31. 31. TopMN <ul><li>排序 M..N 位的元素,则需要抛弃 1..M-1,N+1..MAX 两部分的元素。利用二分思想,每次对元素分成左大右小两堆,分别处理。左堆继续二分分出前 M-1 个元素,右堆继续二分分出 N+1 个之后的元素。排除无效元素后的元素集,再进行排序。 </li></ul><ul><li>H = Split(A); // 元素分成两堆 </li></ul><ul><li>利用 TopK 的思想将前 M-1 个元素排到一组。 </li></ul><ul><li>利用 TopK 的思想将 N+1 位后的元素排到一组。 </li></ul><ul><li>Sort(A,M,N). </li></ul><ul><li>备注:可以不用严格要求 M..N 分出来,可以有部分无效元素,只要去掉大部分无效元素即可。 </li></ul>数据结构与算法——排序相关
  32. 32. 数据库算法与数据结构系列 <ul><li>B 树相关 </li></ul><ul><li>排序相关 [*] </li></ul><ul><li>锁相关 </li></ul><ul><li>缓存相关 </li></ul><ul><li>* 操作系统相关 ( 调度模型 / 段页管理 ) </li></ul><ul><li>* 人工智能相关 ( 遗传算法 / 神经网络 ) </li></ul>数据结构与算法——排序相关
  33. 33. 数据库原理系列 <ul><li>笛卡尔积与集合理论 </li></ul><ul><li>数据库范式理论 </li></ul><ul><li>分布式事务理论 </li></ul>数据结构与算法——排序相关

×