156
Sort 郭至軒(KuoE0[email protected] KuoE0.ch

[ACM-ICPC] Sort

Embed Size (px)

Citation preview

Page 3: [ACM-ICPC] Sort

Bubble Sort氣泡排序法

Page 4: [ACM-ICPC] Sort

Algorithm

1.從第一個元素開始比較每一對相鄰元素

2.若第一個元素大於第二個元素則交換

3.每次遞減需要比較的元素對直到不需比較

Page 5: [ACM-ICPC] Sort

Origin

10 2 7 9 1

10 972 1

Page 6: [ACM-ICPC] Sort

7210

1st Iteration

9 1

Page 7: [ACM-ICPC] Sort

721010 2

1st Iteration

9 1

Page 8: [ACM-ICPC] Sort

7210 102

1st Iteration

9 1

Page 9: [ACM-ICPC] Sort

77210 102

1st Iteration

9 12

Page 10: [ACM-ICPC] Sort

77210 102

1st Iteration

9 12

Page 11: [ACM-ICPC] Sort

77210 102

1st Iteration

9 12 97

Page 12: [ACM-ICPC] Sort

77210 102

1st Iteration

9 12 97

Page 13: [ACM-ICPC] Sort

77210 102

1st Iteration

9 12 97 19

Page 14: [ACM-ICPC] Sort

77210 102

1st Iteration

9 12 97 19

Page 15: [ACM-ICPC] Sort

77210 102

1st Iteration

2 7 9 1 10

9 12 97 19 101

Page 16: [ACM-ICPC] Sort

172

2nd Iteration

109

Page 17: [ACM-ICPC] Sort

172 72

2nd Iteration

109

Page 18: [ACM-ICPC] Sort

172 72

2nd Iteration

109

Page 19: [ACM-ICPC] Sort

172 72

2nd Iteration

1092 9

Page 20: [ACM-ICPC] Sort

172 72

2nd Iteration

1092 9

Page 21: [ACM-ICPC] Sort

1172 72

2nd Iteration

1092 97

Page 22: [ACM-ICPC] Sort

1172 72

2nd Iteration

1092 97

Page 23: [ACM-ICPC] Sort

1172 72

2nd Iteration

2 7 1 9 10

1092 97 1 9

Page 24: [ACM-ICPC] Sort

3rd Iteration

10972 1

Page 25: [ACM-ICPC] Sort

3rd Iteration

10972 12 7

Page 26: [ACM-ICPC] Sort

3rd Iteration

10972 12 7

Page 27: [ACM-ICPC] Sort

3rd Iteration

10972 12 7 12

Page 28: [ACM-ICPC] Sort

3rd Iteration

10972 12 712

Page 29: [ACM-ICPC] Sort

3rd Iteration

10972 1

2 1 7 9 10

2 712 1 7

Page 30: [ACM-ICPC] Sort

4th Iteration

10972 1

Page 31: [ACM-ICPC] Sort

4th Iteration

10972 12 1

Page 32: [ACM-ICPC] Sort

4th Iteration

10972 121

Page 33: [ACM-ICPC] Sort

4th Iteration

1 2 7 9 10

10972 1211 2

Page 34: [ACM-ICPC] Sort

Result

1 2 7 9 10

109721

Page 35: [ACM-ICPC] Sort

Source Code

for ( 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 ] );

Page 36: [ACM-ICPC] Sort

Time Complexity

for ( 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

Page 37: [ACM-ICPC] Sort

n × n = n2

Time Complexity: O(n2)

Page 38: [ACM-ICPC] Sort

從範例中可發現...

耗費許多時間檢查有序數對

Page 39: [ACM-ICPC] Sort

Merge Sort合併排序法

Page 40: [ACM-ICPC] Sort

Algorithm

採用 divide & conquer 策略

Page 41: [ACM-ICPC] Sort

Divide

將當前數列對半切割遞迴進行直到僅剩一個元素

Page 42: [ACM-ICPC] Sort

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 83 57 61

92

Page 43: [ACM-ICPC] Sort

Conquer1. 利用兩個指標指向兩個有序數列 A 與 B2. 比較指標指向的數值3. 將較小的數值放入新的數列 C,並將該指標指向下一數值

4. 直到某一指標指向數列結尾,將另一數列剩餘的數值放都入數列 C

Page 44: [ACM-ICPC] Sort

Merge Two Sequence

98 765432 1

Page 45: [ACM-ICPC] Sort

Merge Two Sequence

98 765432

1

Page 46: [ACM-ICPC] Sort

Merge Two Sequence

98 76543

21

Page 47: [ACM-ICPC] Sort

Merge Two Sequence

98 7654

321

Page 48: [ACM-ICPC] Sort

Merge Two Sequence

98 765

4321

Page 49: [ACM-ICPC] Sort

Merge Two Sequence

98 76

54321

Page 50: [ACM-ICPC] Sort

Merge Two Sequence

98 7

654321

Page 51: [ACM-ICPC] Sort

Merge Two Sequence

98

7654321

Page 52: [ACM-ICPC] Sort

Merge Two Sequence

9

87654321

Page 53: [ACM-ICPC] Sort

Merge Two Sequence

987654321

Page 54: [ACM-ICPC] Sort

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 83 57 61

92

Page 55: [ACM-ICPC] Sort

int 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++ ];

elseC[ p ] = A[ p2++ ];

}for ( int i = L; i < R; ++i )A[ i ] = C[ i - L ];

}

Source Code

Page 56: [ACM-ICPC] Sort

Time Complexitytotal time

Page 57: [ACM-ICPC] Sort

Time Complexitytotal time

n

2 * (n/2) = n

...

n * (n/n) = n

Page 58: [ACM-ICPC] Sort

Best height

}log2n

Page 59: [ACM-ICPC] Sort

Time Complexity: O(nlog2n)

Page 60: [ACM-ICPC] Sort

Quick Sort快速排序法

Page 61: [ACM-ICPC] Sort

Algorithm

採用 divide & conquer 策略

Page 62: [ACM-ICPC] Sort

Divide

從數列中挑出一個元素作為 pivot,利用 pivot 將原數列分為兩個子數列:•所有元素小於 pivot 的數列 A•所有元素大於 pivot 的元素的數列 B•等於 pivot 的元素可放置在任一個中

Page 63: [ACM-ICPC] Sort

2 9 4 3 8 7 5 1 6

Page 64: [ACM-ICPC] Sort

2 9 4 3 8 7 5 1 62 74 3 5 1 69 8

Page 65: [ACM-ICPC] Sort

9 82 4 3 5 1 6

2 9 4 3 8 7 5 1 6

2

7

4 3 5 1 6 9 8

Page 66: [ACM-ICPC] Sort

9 82 4 3 5 1 62 4 5 1 6

2 9 4 3 8 7 5 1 6

2

7

4 3 5 1 6 9 83

Page 67: [ACM-ICPC] Sort

4 5 62 1

9 82 4 3 5 1 6

2 4 51 6

2 9 4 3 8 7 5 1 6

2

7

4 3 5 1 6 9 83

Page 68: [ACM-ICPC] Sort

4 5 62 12

9 82 4 3 5 1 6

2 4 51 6

2 9 4 3 8 7 5 1 6

2

7

4 3 5 1 6 9 83

1

Page 69: [ACM-ICPC] Sort

4 5 62 1

2

9 82 4 3 5 1 6

2 4 51 6

2 9 4 3 8 7 5 1 6

2

2

7

4 3 5 1 6 9 83

1

Page 70: [ACM-ICPC] Sort

4 5 65 62 1

2

9 82 4 3 5 1 6

2 4 51 6

2 9 4 3 8 7 5 1 6

2

2

7

4 3 5 1 6 9 83

1 4

Page 71: [ACM-ICPC] Sort

5 6

4 5 6

5 6

2 1

2

9 82 4 3 5 1 6

2 4 51 6

2 9 4 3 8 7 5 1 6

2

2

7

4 3 5 1 6 9 83

1 4

Page 72: [ACM-ICPC] Sort

5 65

4 5 6

5 6

2 1

2

9 82 4 3 5 1 6

2 4 51 6

2 9 4 3 8 7 5 1 6

2

2

7

4 3 5 1 6 9 83

1 4

6

Page 73: [ACM-ICPC] Sort

5 6

5

4 5 6

5 6

2 1

2

9 82 4 3 5 1 6

2 4 51 6

2 9 4 3 8 7 5 1 6

2

5

2

7

4 3 5 1 6 9 83

1 4

6

Page 74: [ACM-ICPC] Sort

5 6

5

4 5 6

5 6

2 1

2

9 892 4 3 5 1 6

2 4 51 6

2 9 4 3 8 7 5 1 6

2

5

2

7

4 3 5 1 6 9 83

1 4

6

8

Page 75: [ACM-ICPC] Sort

5 6

5

4 5 6

5 6

2 1

2

9 8

9

2 4 3 5 1 6

2 4 51 6

2 9 4 3 8 7 5 1 6

9

2

5

2

7

4 3 5 1 6 9 83

1 4

6

8

Page 76: [ACM-ICPC] Sort

Conquer

由於子數列已被 pivot 分為兩段,一段小於等於 pivot 的數列 A,另一段大於等於 pivot 的數列 B。

Page 77: [ACM-ICPC] Sort

Conquer

由於子數列已被 pivot 分為兩段,一段小於等於 pivot 的數列 A,另一段大於等於 pivot 的數列 B。

A BC

Page 78: [ACM-ICPC] Sort

22

Page 79: [ACM-ICPC] Sort

22

1

Page 80: [ACM-ICPC] Sort

2

21

Page 81: [ACM-ICPC] Sort

1 21 2

2

5

2

5

1

6

Page 82: [ACM-ICPC] Sort

1 21 2

2

5

2

5

1

6

Page 83: [ACM-ICPC] Sort

5 6

1 21 2

5 62

5

2

5

1

6

4

Page 84: [ACM-ICPC] Sort

5 6

1 21 2 5 6

2

5

2

5

1

6

4

Page 85: [ACM-ICPC] Sort

4 5 6

5 6

1 21 2 4 5 65 6

2

5

2

5

1

6

4

3

Page 86: [ACM-ICPC] Sort

4 5 6

5 6

1 2

1 2 4 5 6

5 6

2

5

2

5

1

6

4

3

Page 87: [ACM-ICPC] Sort

1 2 3 4 5 6

4 5 6

5 6

1 2

1 2 4 5 6

5 6

1 2 3 4 5 6

9

2

5

2

5

91

6

4

3 8

Page 88: [ACM-ICPC] Sort

1 2 3 4 5 6

4 5 6

5 6

1 2

1 2 4 5 6

5 6

1 2 3 4 5 6

9

2

5

2

5

9

1

6

4

3 8

Page 89: [ACM-ICPC] Sort

8 91 2 3 4 5 6 8 9

4 5 6

5 6

1 2

1 2 4 5 6

5 6

1 2 3 4 5 6

9

2

5

2

5

9

7

1

6

4

3 8

Page 90: [ACM-ICPC] Sort

8 91 2 3 4 5 6

8 9

4 5 6

5 6

1 2

1 2 4 5 6

5 6

1 2 3 4 5 6

9

2

5

2

5

9

7

1

6

4

3 8

Page 91: [ACM-ICPC] Sort

8 91 2 3 4 5 6

8 9

4 5 6

5 6

1 2

1 2 4 5 6

5 6

1 2 3 4 5 61 2 3 4 5 6 7 8 9

9

2

5

2

5

9

7

1

6

4

3 8

Page 92: [ACM-ICPC] Sort

void 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 ] );}

Source Code

Page 93: [ACM-ICPC] Sort

9 3

How to Divide

4 1 5 8 67 2

Page 94: [ACM-ICPC] Sort

9 3

How to Divide

4 1 5 8 64 7 2

Page 95: [ACM-ICPC] Sort

9 3

How to Divide

4 1 5 8 64 7 2

Page 96: [ACM-ICPC] Sort

9 3

How to Divide

4 1 5 8 64 7 2

Page 97: [ACM-ICPC] Sort

93

How to Divide

4 1 5 8 64 7 2

Page 98: [ACM-ICPC] Sort

93

How to Divide

4 1 5 8 64 7 2

Page 99: [ACM-ICPC] Sort

93

How to Divide

4 1 5 8 64 7 2

Page 100: [ACM-ICPC] Sort

93

How to Divide

4 1 5 8 64 72

Page 101: [ACM-ICPC] Sort

93

How to Divide

4 1 5 8 64 72

Page 102: [ACM-ICPC] Sort

93

How to Divide

4 1 5 8 64 72

Page 103: [ACM-ICPC] Sort

93

How to Divide

4 1 5 8 64 72

4 1 3 2 5 8 7 9 6

Page 104: [ACM-ICPC] Sort

5 6 7 8 93214

How to Conquer

Page 105: [ACM-ICPC] Sort

5 6 7 8 9321 4

How to Conquer

Page 106: [ACM-ICPC] Sort

5 6 7 8 9321 4

How to Conquer

Page 107: [ACM-ICPC] Sort

5 6 7 8 9321 4

How to Conquer

Page 108: [ACM-ICPC] Sort

void 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 );}

In-place Version

Page 109: [ACM-ICPC] Sort

9 4 3 65 18 7

How to Divide

2

Page 110: [ACM-ICPC] Sort

9 4 3 65 18 7

How to Divide

2 6

Page 111: [ACM-ICPC] Sort

9 4 3 65 18 7

How to Divide

22 6

Page 112: [ACM-ICPC] Sort

9 4 3 65 18 7

How to Divide

22 6

Page 113: [ACM-ICPC] Sort

9 4 3 65 18 7

How to Divide

222 6

Page 114: [ACM-ICPC] Sort

99 4 3 65 18 7

How to Divide

222 6

Page 115: [ACM-ICPC] Sort

99 44 3 65 18 7

How to Divide

222 9 6

Page 116: [ACM-ICPC] Sort

99 44 3 65 18 7

How to Divide

222 9 6

Page 117: [ACM-ICPC] Sort

99 44 3 65 18 7

How to Divide

222 94 6

Page 118: [ACM-ICPC] Sort

99 44 33 65 18 7

How to Divide

222 94 6

Page 119: [ACM-ICPC] Sort

99 44 33 65 18 7

How to Divide

222 94 6

Page 120: [ACM-ICPC] Sort

99 44 33 65 18 7

How to Divide

222 94 3 6

Page 121: [ACM-ICPC] Sort

99 44 33 65 18 78

How to Divide

222 94 3 6

Page 122: [ACM-ICPC] Sort

99 44 33 65 18 788

How to Divide

222 94 3 6

Page 123: [ACM-ICPC] Sort

99 44 33 65 18 78 78

How to Divide

222 94 3 6

Page 124: [ACM-ICPC] Sort

99 44 33 65 18 78 78 7

How to Divide

222 94 3 6

Page 125: [ACM-ICPC] Sort

99 44 33 65 158 78 78 7

How to Divide

222 94 3 6

Page 126: [ACM-ICPC] Sort

99 44 33 65 15 8 78 78 7

How to Divide

222 94 3 6

Page 127: [ACM-ICPC] Sort

99 44 33 65 15 8 78 78 7

How to Divide

222 5 94 3 6

Page 128: [ACM-ICPC] Sort

99 44 33 65 15 8 78 78 7

How to Divide

222 5 94 3 1 6

Page 129: [ACM-ICPC] Sort

99 44 33 65 15 8 78 7 87

How to Divide

222 5 94 3 1 6

Page 130: [ACM-ICPC] Sort

99 44 33 65 15 8 78 7 87

How to Divide

222 5 94 3 11 6

Page 131: [ACM-ICPC] Sort

99 44 33 65 15 8 78 7 8 7

How to Divide

222 5 94 3 11 6

Page 132: [ACM-ICPC] Sort

99 44 33 65 15 8 78 7 8 7

How to Divide

222 5 94 3 11 6

2 54 3 1 89 7

Page 133: [ACM-ICPC] Sort

6

How to Conquer

1 42 3 5 87 91 42 3 5 87 9

Page 134: [ACM-ICPC] Sort

6

How to Conquer

1 42 3 5 87 9

1 42 3 5 87 9

Page 135: [ACM-ICPC] Sort

Time Complexitytotal time

Page 136: [ACM-ICPC] Sort

Time Complexitytotal time

n

2 * (n/2) = n

...

n * (n/n) = n

Page 137: [ACM-ICPC] Sort

Best height

}log2n

Page 138: [ACM-ICPC] Sort

Worst height

}n

Page 139: [ACM-ICPC] Sort

Time Complexity:O(nlog2n) ~ O(n2)

Page 140: [ACM-ICPC] Sort

Average Time Complexity:O(nlog2n)

Page 141: [ACM-ICPC] Sort

Builtin Function如果你純粹想要排序罷了...

Page 142: [ACM-ICPC] Sort

qsort (C/C++)

• include <stdlib.h> or <cstdlib>

• compare function

void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));

Page 143: [ACM-ICPC] Sort

void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));

base: 指向欲排序列表起始位置之指標num: 欲排序的元素數量size: 各元素大小compar: 比較函式的函式指標

Page 144: [ACM-ICPC] Sort

Compare Function

Function prototype:int function_name(const void* p1, const void* p2);

return value meansless than 0 p1 < p2

equal to 0 p1 == p2

greater than 0 p1 > p2

Page 145: [ACM-ICPC] Sort

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;

}

Page 146: [ACM-ICPC] Sort

sort (STL)

• include <algorithm>

• compare function for customized behavior

template <class RandomAccessIterator>void sort (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

Page 147: [ACM-ICPC] Sort

template <class RandomAccessIterator>void sort (RandomAccessIterator first, RandomAccessIterator last);

first: 指向欲排序列表起始位置之 iteratorlast: 指向欲排序列表結尾位置之 iterator

指標可被轉型為 iterator!

依照該資料型別的小於運算子 (<) 作為排序依據!

Sort by operator <

Page 148: [ACM-ICPC] Sort

Customized Data Type

Function prototype for operator <:bool operator< ( const type_name &p ) const;

return value means

TRUE this < p

FALSE this >= p

Page 149: [ACM-ICPC] Sort

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;

}

Page 150: [ACM-ICPC] Sort

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;

}

Page 151: [ACM-ICPC] Sort

template <class RandomAccessIterator, class Compare>void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

first: 指向欲排序列表起始位置之 iteratorlast: 指向欲排序列表結尾位置之 iteratorcomp: 比較函式

Sort by Compare Function

指標可被轉型為 iterator!

Page 152: [ACM-ICPC] Sort

Customized Data Type

Function prototyp:bool function_name ( type_name p1, type_name p2 );

return value means

TRUE p1 < p2

FALSE p1 >= p2

Page 153: [ACM-ICPC] Sort

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;

}

Page 156: [ACM-ICPC] Sort

Thank You for Your Listening.