需要递归的排序方式:快速排序归并排序算法分析

来源:互联网 发布:karunesh 知乎 编辑:程序博客网 时间:2024/05/16 12:58

该方法的基本思想是:

1.先从数列中取出一个数作为基准数。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。

以一个数组作为示例,取区间第一个数为基准数。

0

1

2

3

4

5

6

7

8

9

72

6

57

88

60

42

83

73

48

85

初始时,i = 0;  j = 9;   X = a[i] = 72

由于已经将a[0]中的数保存到X中,可以理解成在数组a[0]上挖了个坑,可以将其它数据填充到这来。

从j开始向前找一个比X小或等于X的数。当j=8,符合条件,将a[8]挖出再填到上一个坑a[0]中。a[0]=a[8]; i++;  这样一个坑a[0]就被搞定了,但又形成了一个新坑a[8],这怎么办了?简单,再找数字来填a[8]这个坑。这次从i开始向后找一个大于X的数,当i=3,符合条件,将a[3]挖出再填到上一个坑中a[8]=a[3]; j--;

 

数组变为:

0

1

2

3

4

5

6

7

8

9

48

6

57

88

60

42

83

73

88

85

 i = 3;   j = 7;   X=72

再重复上面的步骤,先从后向前找,再从前向后找

从j开始向前找,当j=5,符合条件,将a[5]挖出填到上一个坑中,a[3] = a[5]; i++;

从i开始向后找,当i=5时,由于i==j退出。

此时,i = j = 5,而a[5]刚好又是上次挖的坑,因此将X填入a[5]。

快速排序函数段如图所示,

int quicksort(vector<int> &v, int left, int right){
if(left < right){
int key = v[left];
int low = left;
int high = right;
while(low < high){
while(low < high && v[high] > key){
high--;
}
v[low] = v[high];
while(low < high && v[low] < key){
low++;
}
v[high] = v[low];
}
v[low] = key;
quicksort(v,left,low-1);
quicksort(v,low+1,right);
}
}

这样通过先递的分解数列,再合数列就完成了归并排序。

[cpp] view plain copy
  1. //将有二个有序数列a[first...mid]和a[mid...last]合并。  
  2. void mergearray(int a[], int first, int mid, int last, int temp[])  
  3. {  
  4.     int i = first, j = mid + 1;  
  5.     int m = mid,   n = last;  
  6.     int k = 0;  
  7.       
  8.     while (i <= m && j <= n)  
  9.     {  
  10.         if (a[i] <= a[j])  
  11.             temp[k++] = a[i++];  
  12.         else  
  13.             temp[k++] = a[j++];  
  14.     }  
  15.       
  16.     while (i <= m)  
  17.         temp[k++] = a[i++];  
  18.       
  19.     while (j <= n)  
  20.         temp[k++] = a[j++];  
  21.       
  22.     for (i = 0; i < k; i++)  
  23.         a[first + i] = temp[i];  
  24. }  
  25. void mergesort(int a[], int first, int last, int temp[])  
  26. {  
  27.     if (first < last)  
  28.     {  
  29.         int mid = (first + last) / 2;  
  30.         mergesort(a, first, mid, temp);    //左边有序  
  31.         mergesort(a, mid + 1, last, temp); //右边有序  
  32.         mergearray(a, first, mid, last, temp); //再将二个有序数列合并  
  33.     }  
  34. }  
  35.   
  36. bool MergeSort(int a[], int n)  
  37. {  
  38.     int *p = new int[n];  
  39.     if (p == NULL)  
  40.         return false;  
  41.     mergesort(a, 0, n - 1, p);  
  42.     delete[] p;  
  43.     return true;  
  44. }  

 

归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)。因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的。


1 0
原创粉丝点击