Zhong

Keep thinking. Keep moving.

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

合并排序

合并排序的思路是:把数组分成两部分,分别进行排序,再把排好序的两部分合并成排序数组。合并排序对一个n个元素的数组排序所需时间是O(nlogn)。用合并排序排序{9, 4, 5, 2, 1, 7, 4, 6}过程如下:

MergeSort_thumb6_thumb

算法C++实现:

 1 //对n个数进行合并排序
 2 void Merge(int A[], int low, int mid, int high)
 3 {
 4     int B[];//辅助数组
 5     int s = low , t = mid + 1 , k = low;
 6 
 7     //将小元素添加到辅助数组
 8     while( s<=mid && t<=high )
 9     {
10         if(A[s]<=A[t])
11         {
12             B[k] = A[s];
13             s = s + 1;
14         }
15         else
16         {
17             B[k] = A[t];
18             t = t + 1;
19         }
20         k = k + 1;
21     }
22 
23     if(s == mid + 1)
24     {
25         //把A[t...high]中剩余的元素复制到B数组
26         for(int i = k ; i <= high ; i++)
27             B[i] = A[t++];
28     }
29     else
30     {
31         //把A[s...mid]中剩余的元素复制到B数组
32         for(int i = k ; i <= high ; i++)
33             B[i] = A[s++];
34     }
35 
36     //把B数组复制到A数组
37     for(int j = low ; j <= high ; j++)
38         A[j] = B[j];
39 }
40 
41 void mergesort(int A[] , int low ,int high)
42 {
43     if(low < high)
44     {
45         //把数组分成两部分分别排序在合并
46         int mid = (low+high)/2;
47         mergesort(A , low , mid);
48         mergesort(A , mid+1 , high);
49         Merge(A , low , mid , high);
50     }
51 }
MergeSort

 

快速排序

快速排序的思路是:通过Split算法划分数组A[low…high],求得A[low]的位置w,使得小于或等于A[w]的元素所处位置为A[low…w-1],大于或等于A[w]的元素的位置为A[w+1…high],再对两个划分后的子数组递归排序。快速排序最好情形的时间复杂度为O(nlogn),最坏的情形为O(n*n),平均时间复杂度O(nlogn)。对数组{4, 6, 3, 1, 8, 7, 2, 5}排序过程如下:

QuickSort_thumb3_thumb

算法C++实现如下:

 

 1 QuickSortint Split(int A[], int low, int high)
 2 {
 3     int i = low;
 4     int x = A[low];
 5 
 6     //从左往右扫描,围绕x划分数组
 7     for(int j = low+1 ; j <= high ; j++)
 8     {
 9         if(A[j] <= x)
10         {
11             i++;
12             if(i != j)
13             {
14                 A[0] = A[i];
15                 A[i] = A[j];
16                 A[j] = A[0];
17             }
18         }
19     }
20 
21     //A[low]填入i位置
22     A[0] = A[low];
23     A[low] = A[i];
24     A[i] = A[0];
25 
26     return i;
27 }
28 
29 void quicksort(int A[], int low, int high)
30 {
31     int w;
32     if(low < high)
33     {
34         w = Split(A, low, high);//把数组划分成两部分
35         quicksort(A, low, w-1);//对左半部分递归处理
36         quicksort(A, w+1, high);//对有半部分递归处理
37     }
38 }
QuickSort

 

合并排序和快速排序执行时间比较

随机产生20组数据,第一组500000个,第二组1000000个,以此类推,到第20组10000000个,数据范围为(0,100000),对同一组数据进行合并排序和快速排序,记录运行时间,程序如下:

  1 #include <iostream>
  2 #include <stdlib.h>
  3 #include <time.h>
  4 #include <string>
  5 
  6 using namespace std;
  7 
  8 int A[10000001];//数据数组
  9 int C[10000001];//复制数组
 10 int B[10000001];//辅助数组
 11 
 12 //初始化,随机产生n个数据保存在C数组中
 13 void Initialize(int n)
 14 {
 15     srand((unsigned)time(0));
 16     for(int i = 1 ; i <= n ; i++)
 17         C[i] = rand()%100000;
 18 }
 19 
 20 //复制C数组元素到A数组
 21 void CopyCtoA(int n)
 22 {
 23     for(int i = 1 ; i <= n ; i++)
 24         A[i] = C[i];
 25 }
 26 
 27 
 28 //Merge
 29 void Merge(int A[], int low, int mid, int high)
 30 {
 31     //int B[100001];//辅助数组
 32     int s = low , t = mid + 1 , k = low;
 33 
 34     //将小元素添加到辅助数组
 35     while( s<=mid && t<=high )
 36     {
 37         if(A[s]<=A[t])
 38         {
 39             B[k] = A[s];
 40             s = s + 1;
 41         }
 42         else
 43         {
 44             B[k] = A[t];
 45             t = t + 1;
 46         }
 47         k = k + 1;
 48     }
 49 
 50     if(s == mid + 1)
 51     {
 52         //把A[t...high]中剩余的元素复制到B数组
 53         for(int i = k ; i <= high ; i++)
 54             B[i] = A[t++];
 55     }
 56     else
 57     {
 58         //把A[s...mid]中剩余的元素复制到B数组
 59         for(int i = k ; i <= high ; i++)
 60             B[i] = A[s++];
 61     }
 62 
 63     //把B数组复制到A数组
 64     for(int j = low ; j <= high ; j++)
 65         A[j] = B[j];
 66 }
 67 
 68 //MergeSort
 69 void MergeSort(int A[], int low, int high)
 70 {
 71     if(low < high)
 72     {
 73         //把数组分成两部分分别排序在合并
 74         int mid = (low+high)/2;
 75         MergeSort(A , low , mid);
 76         MergeSort(A , mid+1 , high);
 77         Merge(A , low , mid , high);
 78     }
 79 }
 80 
 81 //Split
 82 int Split(int A[],int low,int high)
 83 {
 84      A[0]=A[low];    //把基准记录暂存在A[0]中
 85      int key=A[low];
 86      while(low<high)
 87      {
 88          while((low<high)&&(A[high]>=key))    //从右到左扫描
 89             high--;
 90          if(low<high)                    //low>=high而退出的循环,不需要移动数据
 91              A[low++]=A[high];         //记录,并将low往右移动一个单位
 92          while((low<high)&&(A[low]<=key))     //从左到右扫描
 93             low++;
 94          if(low<high)
 95             A[high--]=A[low];             //记录,并将up往左移动一个单位
 96      }
 97      A[low]=A[0];     //正确的位置填入基准位置
 98      return low;     //返回当前填入基准记录的所在位置
 99 }
100 
101 //QuickSort
102 void QuickSort(int A[], int low, int high)
103 {
104     int mid;
105     if(low < high)
106     {
107         mid = Split(A, low, high);//把数组划分成两部分
108         QuickSort(A, low, mid-1);//对左半部分递归处理
109         QuickSort(A, mid+1, high);//对有半部分递归处理
110     }
111 }
112 
113 
114 
115 //对n个数执行合并排序或快速排序,计算输出执行时间
116 void Sort_ExcutionTime(int n , string sort_type)
117 {
118     CopyCtoA(n);
119     clock_t start, end;
120     double totaltime;
121 
122     if(sort_type == "MergeSort")
123     {
124         start = clock();
125         MergeSort(A, 1, n);
126         end = clock();
127     }
128     else if(sort_type == "QuickSort")
129     {
130         start = clock();
131         QuickSort(A, 1, n);
132         end = clock();
133     }
134 
135     totaltime = (double)(end-start)/CLOCKS_PER_SEC*1000;
136     //totaltime = end-start;
137     cout<<sort_type<<" running time is: "<<totaltime<<" ms"<<'\n';
138 }
139 
140 //执行程序
141 void Excute()
142 {
143     for(int i = 1 ; i <= 20 ; i++)
144     {
145         Initialize(500000*i);
146         cout<<"n="<<500000*i<<'\n';
147         Sort_ExcutionTime(500000*i, "MergeSort");
148         Sort_ExcutionTime(500000*i, "QuickSort");
149         cout<<'\n';
150     }
151 }
152 
153 int main()
154 {
155     Excute();
156     return 0;
157 }
View Code

 


执行结果:

                                            

  排序同一组数据,当数据量较少时,QuickSort的运行时间比MergeSort的运行时间少,随着数据增加,MergeSort的运行时间比QuickSort的运行时间少。

可看出对同一组数据快速排序执行的时间少于合并排序,随着数据的增加,这种差距不断增大。

 

 

posted on 2013-10-21 14:46  stwzhong  阅读(2773)  评论(0编辑  收藏  举报