[ACM-ICPC] Sort

650 views

Published on

Published in: Education
1 Comment
1 Like
Statistics
Notes
No Downloads
Views
Total views
650
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
31
Comments
1
Likes
1
Embeds 0
No embeds

No notes for slide

[ACM-ICPC] Sort

  1. 1. Sort 郭至軒(KuoE0)KuoE0.tw@gmail.com KuoE0.ch
  2. 2. Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) http://creativecommons.org/licenses/by-sa/3.0/ Latest update: Feb 27, 2013
  3. 3. Bubble Sort 氣泡排序法
  4. 4. Algorithm1. 從第一個元素開始比較每一對相鄰元素2. 若第一個元素大於第二個元素則交換3. 每次遞減需要比較的元素對直到不需比 較
  5. 5. Origin10 2 7 9 110 2 7 9 1
  6. 6. 1 st Iteration10 2 7 9 1
  7. 7. 1 st Iteration10 2 7 9 1
  8. 8. 1 st Iteration210 2 10 7 9 1
  9. 9. 1 st Iteration210 2 10 7 9 1
  10. 10. 1 st Iteration210 2 7 7 10 9 1
  11. 11. 1 st Iteration210 2 7 7 10 9 1
  12. 12. 1 st Iteration210 2 7 7 9 9 10 1
  13. 13. 1 st Iteration210 2 7 7 9 9 10 1
  14. 14. 1 st Iteration210 2 7 7 9 1 9 1 10
  15. 15. 1 st Iteration2 7 9 1 10210 2 7 7 9 1 9 1 10
  16. 16. 2 nd Iteration2 7 9 1 10
  17. 17. 2 nd Iteration2 7 9 1 10
  18. 18. 2 nd Iteration2 7 9 1 10
  19. 19. 2 nd Iteration2 7 9 1 10
  20. 20. 2 nd Iteration2 7 9 1 10
  21. 21. 2 nd Iteration2 7 9 1 10
  22. 22. 2 nd Iteration2 7 1 9 1 9 10
  23. 23. 2 nd Iteration2 7 1 9 102 7 1 9 1 9 10
  24. 24. 3 rd Iteration2 7 1 9 10
  25. 25. 3 rd Iteration2 7 1 9 10
  26. 26. 3 rd Iteration2 7 1 9 10
  27. 27. 3 rd Iteration2 7 1 9 10
  28. 28. 3 rd Iteration2 1 7 1 7 9 10
  29. 29. 3 rd Iteration2 1 7 9 102 1 7 1 7 9 10
  30. 30. 4 th Iteration2 1 7 9 10
  31. 31. 4 th Iteration2 1 7 9 10
  32. 32. 4 th Iteration12 1 2 7 9 10
  33. 33. 4 th Iteration1 2 7 9 1012 1 2 7 9 10
  34. 34. Result1 2 7 9 101 2 7 9 10
  35. 35. Source Codefor ( int i = 0; i < n; ++i ) for ( int j = 0; j < n - 1 - i; ++j ) if ( A[ j ] > A[ j + 1 ] ) swap( A[ j ], A[ j + 1 ] );
  36. 36. Time Complexityfor ( int i = 0; i < n; ++i ) for ( int j = 0; j < n - 1 - i; ++j ) if ( A[ j ] > A[ j + 1 ] ) swap( A[ j ], A[ j + 1 ] ); 最大循環次數略估 第 1 層迴圈 n 第 2 層迴圈 n
  37. 37. n×n= n 2Time Complexity: O(n2)
  38. 38. 從範例中可發現...耗費許多時間檢查有序數對
  39. 39. Merge Sort 合併排序法
  40. 40. Algorithm採用 divide & conquer 策略
  41. 41. Divide將當前數列對半切割遞迴進行 直到 剩一個元素
  42. 42. 2 9 4 3 8 7 5 1 6 2 9 4 3 8 7 5 1 6 2 9 4 3 8 7 5 1 6 2 9 4 3 8 7 5 1 62 9
  43. 43. Conquer1. 利用兩個指標指向兩個有序數列 A 與 B2. 比較指標指向的數值3. 將較小的數值放入新的數列 C,並將該指標 指向下一數值4. 直到某一指標指向數列結尾,將另一數列剩 餘的數值放都入數列 C
  44. 44. Merge Two Sequence2 3 4 8 9 1 5 6 7
  45. 45. Merge Two Sequence2 3 4 8 9 5 6 7 1
  46. 46. Merge Two Sequence 3 4 8 9 5 6 7 1 2
  47. 47. Merge Two Sequence 4 8 9 5 6 7 1 2 3
  48. 48. Merge Two Sequence 8 9 5 6 7 1 2 3 4
  49. 49. Merge Two Sequence 8 9 6 7 1 2 3 4 5
  50. 50. Merge Two Sequence 8 9 7 1 2 3 4 5 6
  51. 51. Merge Two Sequence 8 9 1 2 3 4 5 6 7
  52. 52. Merge Two Sequence 9 1 2 3 4 5 6 7 8
  53. 53. Merge Two Sequence 1 2 3 4 5 6 7 8 9
  54. 54. 1 2 3 4 5 6 7 8 9 2 3 4 8 9 1 5 6 7 2 4 9 3 8 5 7 1 6 2 9 4 3 8 7 5 1 62 9
  55. 55. Source Codeint mergeSort( int L, int R ) { if ( R - L == 1 ) return; int mid = ( R + L ) / 2, C[ R - L ]; mergeSort( L, mid ); mergeSort( mid, R ); for ( int p1 = L, p2 = mid, p = 0; p < R - L; ++p ) { if ( ( p1 != mid && A[ p1 ] < A[ p2 ] ) || p2 == R ) C[ p ] = A[ p1++ ]; else C[ p ] = A[ p2++ ]; } for ( int i = L; i < R; ++i ) A[ i ] = C[ i - L ];}
  56. 56. Time Complexity total time
  57. 57. Time Complexity total time n 2 * (n/2) = n ... n * (n/n) = n
  58. 58. Best height } log2n
  59. 59. Time Complexity: O(nlog2n)
  60. 60. Quick Sort 快速排序法
  61. 61. Algorithm採用 divide & conquer 策略
  62. 62. Divide從數列中挑出一個元素作為 pivot,利用 pivot 將原數列分為兩個子數列:• 所有元素小於 pivot 的數列 A• 所有元素大於 pivot 的元素的數列 B• 等於 pivot 的元素可放置在任一個中
  63. 63. 2 9 4 3 8 7 5 1 6
  64. 64. 2 9 4 3 8 7 5 1 6
  65. 65. 2 9 4 3 8 7 5 1 62 4 3 5 1 6 9 8
  66. 66. 2 9 4 3 8 7 5 1 62 4 3 5 1 6 9 8
  67. 67. 2 9 4 3 8 7 5 1 6 2 4 3 5 1 6 9 82 1 4 5 6
  68. 68. 2 9 4 3 8 7 5 1 6 2 4 3 5 1 6 9 82 1 4 5 6
  69. 69. 2 9 4 3 8 7 5 1 6 2 4 3 5 1 6 9 82 1 4 5 6 2
  70. 70. 2 9 4 3 8 7 5 1 6 2 4 3 5 1 6 9 82 1 4 5 6 2
  71. 71. 2 9 4 3 8 7 5 1 6 2 4 3 5 1 6 9 82 1 4 5 6 2 5 6
  72. 72. 2 9 4 3 8 7 5 1 6 2 4 3 5 1 6 9 82 1 4 5 6 2 5 6
  73. 73. 2 9 4 3 8 7 5 1 6 2 4 3 5 1 6 9 82 1 4 5 6 2 5 6 5
  74. 74. 2 9 4 3 8 7 5 1 6 2 4 3 5 1 6 9 82 1 4 5 6 2 5 6 5
  75. 75. 2 9 4 3 8 7 5 1 6 2 4 3 5 1 6 9 82 1 4 5 6 9 2 5 6 5
  76. 76. Conquer由於子數列已被 pivot 分為兩段,一段小於等於 pivot 的數列 A,另一段大於等於 pivot 的數列 B。
  77. 77. Conquer由於子數列已被 pivot 分為兩段,一段小於等於 pivot 的數列 A,另一段大於等於 pivot 的數列 B。 A C B
  78. 78. 2
  79. 79. 1 2
  80. 80. 1 2 2
  81. 81. 1 2 2 6 5
  82. 82. 1 2 2 5 6 5
  83. 83. 1 2 4 2 5 6 5
  84. 84. 1 2 4 5 6 2 5 6 5
  85. 85. 31 2 4 5 6 2 5 6 5
  86. 86. 1 2 3 4 5 61 2 4 5 6 2 5 6 5
  87. 87. 1 2 3 4 5 6 81 2 4 5 6 9 2 5 6 5
  88. 88. 1 2 3 4 5 6 8 91 2 4 5 6 9 2 5 6 5
  89. 89. 7 1 2 3 4 5 6 8 91 2 4 5 6 9 2 5 6 5
  90. 90. 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 8 91 2 4 5 6 9 2 5 6 5
  91. 91. 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 8 91 2 4 5 6 9 2 5 6 5
  92. 92. Source Codevoid quickSort( int L, int R ) { if ( R - L <= 1 ) return; int pivot = N[ L ], p1 = L + 1, p2 = R - 1; do { while ( N[ p1++ ] <= pivot ) ; while ( N[ p2-- ] > pivot ) ; if ( p1 < p2 ) swap( N[ p1 ], N[ p2 ] ); } while ( p1 < p2 ); quickSort( L + 1, p1 ); quickSort( p1, R ); for ( int i = L + 1; i < p1; ++i ) swap( N[ i - 1 ], N[ i ] );}
  93. 93. How to Divide4 1 9 7 5 8 2 3 6
  94. 94. How to Divide4 1 9 7 5 8 2 3 6
  95. 95. How to Divide4 1 9 7 5 8 2 3 6
  96. 96. How to Divide4 1 9 7 5 8 2 3 6
  97. 97. How to Divide4 1 3 7 5 8 2 9 6
  98. 98. How to Divide4 1 3 7 5 8 2 9 6
  99. 99. How to Divide4 1 3 7 5 8 2 9 6
  100. 100. How to Divide4 1 3 2 5 8 7 9 6
  101. 101. How to Divide4 1 3 2 5 8 7 9 6
  102. 102. How to Divide4 1 3 2 5 8 7 9 6
  103. 103. How to Divide4 1 3 2 5 8 7 9 64 1 3 2 5 8 7 9 6
  104. 104. How to Conquer4 1 2 3 5 6 7 8 9
  105. 105. How to Conquer1 4 2 3 5 6 7 8 9
  106. 106. How to Conquer1 2 4 3 5 6 7 8 9
  107. 107. How to Conquer1 2 3 4 5 6 7 8 9
  108. 108. In-place Versionvoid quickSort( int L, int R ) { if ( R - L <= 1 ) return; int pivot = N[ R - 1 ], p = L; for ( int i = L; i < R - 1; ++i ) { if ( N[ i ] <= pivot ) { swap( N[ i ], N[ p ] ); ++p; } } swap( N[ R - 1 ], N[ p ] ); quickSort( L, p ); quickSort( p + 1, R );}
  109. 109. How to Divide2 9 4 3 8 7 5 1 6
  110. 110. How to Divide2 9 4 3 8 7 5 1 6
  111. 111. How to Divide2 9 4 3 8 7 5 1 6
  112. 112. How to Divide2 9 4 3 8 7 5 1 6
  113. 113. How to Divide2 9 4 3 8 7 5 1 6
  114. 114. How to Divide2 9 4 3 8 7 5 1 6
  115. 115. How to Divide2 9 4 3 8 7 5 1 6
  116. 116. How to Divide2 4 9 9 4 3 8 7 5 1 6
  117. 117. How to Divide2 4 9 9 4 3 8 7 5 1 6
  118. 118. How to Divide2 4 9 9 4 3 8 7 5 1 6
  119. 119. How to Divide2 4 9 3 4 9 3 8 7 5 1 6
  120. 120. How to Divide2 4 9 3 4 9 3 8 7 5 1 6
  121. 121. How to Divide2 4 9 3 4 9 3 8 7 5 1 6
  122. 122. How to Divide2 4 9 3 4 9 3 8 7 5 1 6
  123. 123. How to Divide2 4 9 3 4 9 3 8 7 5 1 6
  124. 124. How to Divide2 4 9 3 4 9 3 8 7 5 1 6
  125. 125. How to Divide2 4 9 3 4 9 3 8 7 5 1 6
  126. 126. How to Divide2 4 9 3 4 5 3 8 7 9 5 1 6
  127. 127. How to Divide2 4 9 3 4 5 3 8 7 9 5 1 6
  128. 128. How to Divide2 4 9 3 4 5 3 8 7 9 5 1 6
  129. 129. How to Divide2 4 9 3 4 5 3 8 1 7 9 5 8 1 6
  130. 130. How to Divide2 4 9 3 4 5 3 1 8 7 9 5 8 1 6
  131. 131. How to Divide2 4 9 3 4 5 3 1 8 6 7 9 5 8 1 7 6
  132. 132. How to Divide2 4 9 3 4 5 3 1 8 6 7 9 5 8 1 7 62 4 3 5 1 9 8 7
  133. 133. How to Conquer 61 2 3 4 5 7 8 9
  134. 134. How to Conquer1 2 3 4 5 6 7 8 91 2 3 4 5 7 8 9
  135. 135. Time Complexity total time
  136. 136. Time Complexity total time n 2 * (n/2) = n ... n * (n/n) = n
  137. 137. Best height } log2n
  138. 138. Worst height } n
  139. 139. Time Complexity: O(nlog2n) ~ O(n 2)
  140. 140. Average Time Complexity: O(nlog2n)
  141. 141. Builtin Function 如果你純粹想要排序罷了...
  142. 142. qsort (C/C++) • include <stdlib.h> or <cstdlib> • compare functionvoid qsort (void* base, size_t num, size_tsize, int (*compar)(const void*,const void*));
  143. 143. void qsort (void* base, size_t num, size_tsize, int (*compar)(const void*,const void*)); base: 指向欲排序列表起始位置之指標 num: 欲排序的元素數量 size: 各元素大小 compar: 比較函式的函式指標
  144. 144. Compare Function Function prototype:int function_name(const void* p1, const void* p2); return value means less than 0 p1 < p2 equal to 0 p1 == p2 greater than 0 p1 > p2
  145. 145. Exampleint cmp( const void* p1, const void* p2 ) { return *(int*)p1 - *(int*)p2;}int main() { int n, N[ 10010 ]; while ( scanf( “%d”, &n ) != EOF ) { int x; for ( int i = 0; i < n; ++i ) { scanf( “%d”, &x ); N[ i ] = x; } qsort( N, n, sizeof( int ), cmp ); } return 0;}
  146. 146. sort (STL) • include <algorithm> • compare function for customized behaviortemplate <class RandomAccessIterator>void sort (RandomAccessIterator first,RandomAccessIterator last);template <class RandomAccessIterator, class Compare>void sort (RandomAccessIterator first,RandomAccessIterator last, Compare comp);
  147. 147. Sort by operator <template <class RandomAccessIterator>void sort (RandomAccessIterator first,RandomAccessIterator last); first: 指向欲排序列表起始位置之 iterator last: 指向欲排序列表結尾位置之 iterator 指標可被轉型為 iterator!依照該資料型別的小於運算子 (<) 作為排序依據!
  148. 148. Customized Data Type Function prototype for operator <:bool operator< ( const type_name &p ) const; return value means TRUE this < p FALSE this >= p
  149. 149. Example (builtin type)int main() { int n, N[ 10010 ]; while ( scanf( “%d”, &n ) != EOF ) { int x; for ( int i = 0; i < n; ++i ) { scanf( “%d”, &x ); N[ i ] = x; } sort( N, N + n ); } return 0;}
  150. 150. Example (custom type)struct T { int x, y; bool operator< ( const T &p ) const { return x == p.x ? x < p.x : y < p.y; }};T pt[ 10010 ];int main() { int n; while ( scanf( “%d”, &n ) != EOF ) { int x, y; for ( int i = 0; i < n; ++i ) { scanf( “%d %d”, &x, &y ); pt[ i ].x = x, pt[ i ].y = y; } sort( pt, pt + n ); } return 0;}
  151. 151. Sort by Compare Functiontemplate <class RandomAccessIterator, class Compare>void sort (RandomAccessIterator first,RandomAccessIterator last, Compare comp); first: 指向欲排序列表起始位置之 iterator last: 指向欲排序列表結尾位置之 iterator comp: 比較函式 指標可被轉型為 iterator!
  152. 152. Customized Data Type Function prototyp:bool function_name ( type_name p1, type_name p2 ); return value means TRUE p1 < p2 FALSE p1 >= p2
  153. 153. Example (descending)bool descending( int p1, int p2 ) { return p1 >= p2;}int main() { int n, N[ 10010 ]; while ( scanf( “%d”, &n ) != EOF ) { int x; for ( int i = 0; i < n; ++i ) { scanf( “%d”, &x ); N[ i ] = x; } sort( N, N + n, descending ); } return 0;}
  154. 154. Reference• 冒泡排序 - 維基百科,自由的百科全書• 歸併排序 - 維基百科,自由的百科全書• 快速排序 - 維基百科,自由的百科全書• qsort - C++ Reference• sort - C++ Reference
  155. 155. Practice Now10810 - Ultra-QuickSort
  156. 156. Thank You for Your Listening.

×