zoukankan      html  css  js  c++  java
  • 合并排序和快速排序执行时间比较

    合并排序

    合并排序的思路是:把数组分成两部分,分别进行排序,再把排好序的两部分合并成排序数组。合并排序对一个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"<<'
    ';
    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<<'
    ';
    147         Sort_ExcutionTime(500000*i, "MergeSort");
    148         Sort_ExcutionTime(500000*i, "QuickSort");
    149         cout<<'
    ';
    150     }
    151 }
    152 
    153 int main()
    154 {
    155     Excute();
    156     return 0;
    157 }
    View Code

    执行结果:

                                                

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

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

  • 相关阅读:
    南京师范大学2021年高等代数考研试卷
    有限阶全图边图两种颜色后同色三角形数量最少为?(2019年清华大学丘成桐数学英才班)
    关于三个变元的正整数解(2019年清华大学丘成桐数学英才班)
    [Oracle工程师手记]归档日志产生量太大时的简易分析手段
    [Oracle 工程师手记] 如何查看 FRA 的使用率
    [Oracle数据库工程师手记] Data Guard broker 与 ORA-32701
    [Oracle工程师手记]CRSD 进程与 password 文件
    [oracle 工程师手记]RMAN duplicate 发生ORA-19504、ORA-17502、ORA-15001、ORA-27140 错误的解决过程
    [Oracle工程师手记] 备份恢复双城记(三)
    [Oracle工程师手记] 备份恢复双城记(二)
  • 原文地址:https://www.cnblogs.com/stwzhong/p/3380395.html
Copyright © 2011-2022 走看看