插入排序
书上说的很好,用打牌作比方。就是一边是排好序的,剩下的是待排序的,每次取一个待排序的元素,找到按序的位置,插入已排好序的部分中。元素取完也就结束了。复杂度O(n^2)。
代码:
1
#include
<
iostream
>
2 using namespace std;
3 #define LENGTH 11
4
5 void insert_sort( int array[], int len)
6 {
7 int i,j;
8
9 for (i = 1 ;i < len;i ++ )
10 {
11 int key = array[i];
12 for (j = i - 1 ;j >= 0 && array[j] > key;j -- )
13 {
14 array[j + 1 ] = array[j];
15 }
16 array[j + 1 ] = key;
17 }
18 }
19 int main()
20 {
21 int array[LENGTH] = { 9 , 3 , 5 , 12 , 7 , 34 , 56 , 28 , 16 , 4 , 10 };
22 int i = 0 ;
23
24 for (i = 0 ;i < LENGTH;i ++ )
25 {
26 cout << array[i] << " " ;
27 }
28 cout << endl;
29
30 insert_sort(array,LENGTH); // sort
31
32 for (i = 0 ;i < LENGTH;i ++ )
33 {
34 cout << array[i] << " " ;
35 }
36 cout << endl;
37 }
2 using namespace std;
3 #define LENGTH 11
4
5 void insert_sort( int array[], int len)
6 {
7 int i,j;
8
9 for (i = 1 ;i < len;i ++ )
10 {
11 int key = array[i];
12 for (j = i - 1 ;j >= 0 && array[j] > key;j -- )
13 {
14 array[j + 1 ] = array[j];
15 }
16 array[j + 1 ] = key;
17 }
18 }
19 int main()
20 {
21 int array[LENGTH] = { 9 , 3 , 5 , 12 , 7 , 34 , 56 , 28 , 16 , 4 , 10 };
22 int i = 0 ;
23
24 for (i = 0 ;i < LENGTH;i ++ )
25 {
26 cout << array[i] << " " ;
27 }
28 cout << endl;
29
30 insert_sort(array,LENGTH); // sort
31
32 for (i = 0 ;i < LENGTH;i ++ )
33 {
34 cout << array[i] << " " ;
35 }
36 cout << endl;
37 }
合并排序
合并排序是一种分治法,实现上用了递归结构。过程是:先将待排序的元素分为两部分,一般是对等长度的两部分,称为左右L、R,先分别将L,R进行合并排序,然后将排序好的L、R合并在一起,则所有元素都有序。复杂度O(nlgn)。
代码
1
#include
<
iostream
>
2 using namespace std;
3 #define LENGTH 10
4
5 void merge( int array[], int start, int middle, int end)
6 {
7 int i,j,k;
8 int n1 = middle - start + 1 ,n2 = end - middle;
9 int * L = new int [n1 + 1 ], * R = new int [n2 + 1 ];
10
11 for (i = 0 ;i < n1;i ++ )
12 {
13 L[i] = array[start + i];
14 }
15 for (i = 0 ;i < n2;i ++ )
16 {
17 R[i] = array[middle + i + 1 ];
18 }
19 L[n1] = INT_MAX;
20 R[n2] = INT_MAX;
21
22 i = 0 ,j = 0 ;
23 for (k = start;k <= end;k ++ )
24 {
25 if (L[i] <= R[j])
26 {
27 array[k] = L[i];
28 i ++ ;
29 }
30 else
31 {
32 array[k] = R[j];
33 j ++ ;
34 }
35 }
36 }
37
38 void merge_sort( int array[], int start, int end)
39 {
40 int i,j;
41 if (start < end)
42 {
43 int middle = (start + end) / 2 ;
44 merge_sort(array,start,middle);
45 merge_sort(array,middle + 1 ,end);
46 merge(array,start,middle,end);
47 }
48 }
49
50 int main()
51 {
52 int i = 0 ;
53 int array[LENGTH] = { 9 , 12 , 5 , 24 , 8 , 7 , 15 , 10 , 0 , 22 };
54 for (i = 0 ;i < LENGTH;i ++ )
55 {
56 cout << array[i] << " " ;
57 }
58 cout << endl;
59
60 merge_sort(array, 0 ,LENGTH - 1 );
61
62 for (i = 0 ;i < LENGTH;i ++ )
63 {
64 cout << array[i] << " " ;
65 }
66 cout << endl;
67
68 return 0 ;
69 }
2 using namespace std;
3 #define LENGTH 10
4
5 void merge( int array[], int start, int middle, int end)
6 {
7 int i,j,k;
8 int n1 = middle - start + 1 ,n2 = end - middle;
9 int * L = new int [n1 + 1 ], * R = new int [n2 + 1 ];
10
11 for (i = 0 ;i < n1;i ++ )
12 {
13 L[i] = array[start + i];
14 }
15 for (i = 0 ;i < n2;i ++ )
16 {
17 R[i] = array[middle + i + 1 ];
18 }
19 L[n1] = INT_MAX;
20 R[n2] = INT_MAX;
21
22 i = 0 ,j = 0 ;
23 for (k = start;k <= end;k ++ )
24 {
25 if (L[i] <= R[j])
26 {
27 array[k] = L[i];
28 i ++ ;
29 }
30 else
31 {
32 array[k] = R[j];
33 j ++ ;
34 }
35 }
36 }
37
38 void merge_sort( int array[], int start, int end)
39 {
40 int i,j;
41 if (start < end)
42 {
43 int middle = (start + end) / 2 ;
44 merge_sort(array,start,middle);
45 merge_sort(array,middle + 1 ,end);
46 merge(array,start,middle,end);
47 }
48 }
49
50 int main()
51 {
52 int i = 0 ;
53 int array[LENGTH] = { 9 , 12 , 5 , 24 , 8 , 7 , 15 , 10 , 0 , 22 };
54 for (i = 0 ;i < LENGTH;i ++ )
55 {
56 cout << array[i] << " " ;
57 }
58 cout << endl;
59
60 merge_sort(array, 0 ,LENGTH - 1 );
61
62 for (i = 0 ;i < LENGTH;i ++ )
63 {
64 cout << array[i] << " " ;
65 }
66 cout << endl;
67
68 return 0 ;
69 }
合并排序的扩展应用
对合并排序稍作一些改动,可以以O(nlgn)的复杂度实现其他功能。
思考题2.3.7
思路:
I 对集合S中的元素进行排序,选择复杂度为O(nlgn)的排序算法,这里是合并排序
II 从两头开始遍历排序后S的元素,下标分别为i、j,若S[i]+S[j]==x,返回;若S[i]+S[j]>x,j--;若S[i]+S[j]<x,i++
代码
1
#include
<
iostream
>
2 using namespace std;
3 #define LENGTH 10
4
5 void merge( int array[], int start, int middle, int end)
6 {
7 int i,j,k;
8 int n1 = middle - start + 1 ,n2 = end - middle;
9 int * L = new int [n1 + 1 ], * R = new int [n2 + 1 ];
10
11 for (i = 0 ;i < n1;i ++ )
12 {
13 L[i] = array[start + i];
14 }
15 for (i = 0 ;i < n2;i ++ )
16 {
17 R[i] = array[middle + i + 1 ];
18 }
19 L[n1] = INT_MAX;
20 R[n2] = INT_MAX;
21
22 i = 0 ,j = 0 ;
23 for (k = start;k <= end;k ++ )
24 {
25 if (L[i] <= R[j])
26 {
27 array[k] = L[i];
28 i ++ ;
29 }
30 else
31 {
32 array[k] = R[j];
33 j ++ ;
34 }
35 }
36 }
37
38 void merge_sort( int array[], int start, int end)
39 {
40 int i,j;
41 if (start < end)
42 {
43 int middle = (start + end) / 2 ;
44 merge_sort(array,start,middle);
45 merge_sort(array,middle + 1 ,end);
46 merge(array,start,middle,end);
47 }
48 }
49
50 bool find_two_ele( int array[], int len, int x, int & x1, int & x2)
51 {
52 int i,j;
53 for (i = 0 ,j = len - 1 ;i < len;)
54 {
55 int sum = array[i] + array[j];
56 if (sum == x)
57 {
58 x1 = array[i];
59 x2 = array[j];
60 return true ;
61 }
62 else
63 if (sum > x)
64 {
65 j -- ;
66 }
67 else
68 {
69 i ++ ;
70 }
71 }
72 return false ;
73 }
74 int main()
75 {
76 int i = 0 ;
77 int array[LENGTH] = { 9 , 12 , 5 , 24 , 8 , 7 , 15 , 10 , 0 , 22 };
78
79 merge_sort(array, 0 ,LENGTH - 1 );
80
81 int x = 15 ,x1,x2;
82
83 if (find_two_ele(array,LENGTH,x,x1,x2))
84 {
85 cout << " Yes. " << x << " = " << x1 << " + " << x2 << endl;
86 } else
87 {
88 cout << " No. " << endl;
89 }
90
91 return 0 ;
92 }
2 using namespace std;
3 #define LENGTH 10
4
5 void merge( int array[], int start, int middle, int end)
6 {
7 int i,j,k;
8 int n1 = middle - start + 1 ,n2 = end - middle;
9 int * L = new int [n1 + 1 ], * R = new int [n2 + 1 ];
10
11 for (i = 0 ;i < n1;i ++ )
12 {
13 L[i] = array[start + i];
14 }
15 for (i = 0 ;i < n2;i ++ )
16 {
17 R[i] = array[middle + i + 1 ];
18 }
19 L[n1] = INT_MAX;
20 R[n2] = INT_MAX;
21
22 i = 0 ,j = 0 ;
23 for (k = start;k <= end;k ++ )
24 {
25 if (L[i] <= R[j])
26 {
27 array[k] = L[i];
28 i ++ ;
29 }
30 else
31 {
32 array[k] = R[j];
33 j ++ ;
34 }
35 }
36 }
37
38 void merge_sort( int array[], int start, int end)
39 {
40 int i,j;
41 if (start < end)
42 {
43 int middle = (start + end) / 2 ;
44 merge_sort(array,start,middle);
45 merge_sort(array,middle + 1 ,end);
46 merge(array,start,middle,end);
47 }
48 }
49
50 bool find_two_ele( int array[], int len, int x, int & x1, int & x2)
51 {
52 int i,j;
53 for (i = 0 ,j = len - 1 ;i < len;)
54 {
55 int sum = array[i] + array[j];
56 if (sum == x)
57 {
58 x1 = array[i];
59 x2 = array[j];
60 return true ;
61 }
62 else
63 if (sum > x)
64 {
65 j -- ;
66 }
67 else
68 {
69 i ++ ;
70 }
71 }
72 return false ;
73 }
74 int main()
75 {
76 int i = 0 ;
77 int array[LENGTH] = { 9 , 12 , 5 , 24 , 8 , 7 , 15 , 10 , 0 , 22 };
78
79 merge_sort(array, 0 ,LENGTH - 1 );
80
81 int x = 15 ,x1,x2;
82
83 if (find_two_ele(array,LENGTH,x,x1,x2))
84 {
85 cout << " Yes. " << x << " = " << x1 << " + " << x2 << endl;
86 } else
87 {
88 cout << " No. " << endl;
89 }
90
91 return 0 ;
92 }
练习题2-4
逆序对问题,可以在合并的时候统计有多少逆序对。
代码
1
/*
***************
2 逆序对问题
3 *************** */
4 #include < iostream >
5 using namespace std;
6 #define LENGTH 10
7
8 int Num = 0 ;
9
10 int merge( int array[], int start, int middle, int end)
11 {
12 int i,j,k,count = 0 ;
13 int n1 = middle - start + 1 ,n2 = end - middle;
14 int * L = new int [n1 + 1 ], * R = new int [n2 + 1 ];
15 for (i = 0 ;i < n1;i ++ )
16 {
17 L[i] = array[start + i];
18 }
19 for (i = 0 ;i < n2;i ++ )
20 {
21 R[i] = array[middle + i + 1 ];
22 }
23 L[n1] = INT_MAX,R[n2] = INT_MAX;
24
25 i = 0 ,j = 0 ;
26 for (k = start;k <= end;k ++ )
27 {
28 if (L[i] < R[j])
29 {
30 array[k] = L[i];
31 i ++ ;
32 }
33 else
34 {
35 array[k] = R[j];
36 count += middle - start - i + 1 ; // count
37 j ++ ;
38 }
39 }
40
41 return count;
42 }
43
44 int merge_sort( int array[], int start, int end)
45 {
46 if (start < end)
47 {
48 int middle = (start + end) / 2 ;
49 merge_sort(array,start,middle);
50 merge_sort(array,middle + 1 ,end);
51 Num += merge(array,start,middle,end);
52
53 return Num;
54 }
55 }
56
57 int main()
58 {
59 int array[LENGTH] = { 9 , 12 , 5 , 24 , 8 , 7 , 15 , 10 , 0 , 22 };
60
61 cout << merge_sort(array, 0 ,LENGTH - 1 ) << endl;
62
63 for ( int i = 0 ;i < LENGTH;i ++ )
64 {
65 cout << array[i] << " " ;
66 }
67 cout << endl;
68
69 return 0 ;
70 }
2 逆序对问题
3 *************** */
4 #include < iostream >
5 using namespace std;
6 #define LENGTH 10
7
8 int Num = 0 ;
9
10 int merge( int array[], int start, int middle, int end)
11 {
12 int i,j,k,count = 0 ;
13 int n1 = middle - start + 1 ,n2 = end - middle;
14 int * L = new int [n1 + 1 ], * R = new int [n2 + 1 ];
15 for (i = 0 ;i < n1;i ++ )
16 {
17 L[i] = array[start + i];
18 }
19 for (i = 0 ;i < n2;i ++ )
20 {
21 R[i] = array[middle + i + 1 ];
22 }
23 L[n1] = INT_MAX,R[n2] = INT_MAX;
24
25 i = 0 ,j = 0 ;
26 for (k = start;k <= end;k ++ )
27 {
28 if (L[i] < R[j])
29 {
30 array[k] = L[i];
31 i ++ ;
32 }
33 else
34 {
35 array[k] = R[j];
36 count += middle - start - i + 1 ; // count
37 j ++ ;
38 }
39 }
40
41 return count;
42 }
43
44 int merge_sort( int array[], int start, int end)
45 {
46 if (start < end)
47 {
48 int middle = (start + end) / 2 ;
49 merge_sort(array,start,middle);
50 merge_sort(array,middle + 1 ,end);
51 Num += merge(array,start,middle,end);
52
53 return Num;
54 }
55 }
56
57 int main()
58 {
59 int array[LENGTH] = { 9 , 12 , 5 , 24 , 8 , 7 , 15 , 10 , 0 , 22 };
60
61 cout << merge_sort(array, 0 ,LENGTH - 1 ) << endl;
62
63 for ( int i = 0 ;i < LENGTH;i ++ )
64 {
65 cout << array[i] << " " ;
66 }
67 cout << endl;
68
69 return 0 ;
70 }