《算法导论》(一)--插入排序与合并排序

插入排序

书上说的很好,用打牌作比方。就是一边是排好序的,剩下的是待排序的,每次取一个待排序的元素,找到按序的位置,插入已排好序的部分中。元素取完也就结束了。复杂度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 }

 

 

合并排序

合并排序是一种分治法,实现上用了递归结构。过程是:先将待排序的元素分为两部分,一般是对等长度的两部分,称为左右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 }

 

 

合并排序的扩展应用

对合并排序稍作一些改动,可以以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-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 }

 

posted on 2010-09-01 18:31  小交响曲  阅读(441)  评论(1编辑  收藏  举报

导航