C语言练习之 快速排序(三)

  摘要:程序员在成长的过程中,排序算法是绕不开的话题,在纷扰的实际生产中,算法没有绝对的好坏之分,只有合适与不合适之别,这次主要记录

快速排序算法。

一、快速排序: 

  快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。

  1.分治思想:

  分治法的基本思想是:将复杂的规模较大的任务,拆分成规模较小,而且和规模较大的任务解决方案相似的任务,然后递归的执行小任务,执行完成

小任务后,最终组合完成规模较大的任务。

  2.快速排序思想 

  设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为:
  ①分解: 
     在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
    注意:
     划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(注意pivot=R[pivotpos]):
     R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys
                  其中low≤pivotpos≤high。
  ②求解: 
     通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。

③组合: 
 因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。

二、快速排序算法QuickSort

  void QuickSort(SeqList R,int low,int high)
   { //对R[low..high]快速排序
     int pivotpos; //划分后的基准记录的位置
     if(low<high){//仅当区间长度大于1时才须排序
        pivotpos=Partition(R,low,high); //对R[low..high]做划分
        QuickSort(R,low,pivotpos-1); //对左区间递归排序
        QuickSort(R,pivotpos+1,high); //对右区间递归排序
      }
    } //QuickSort

三、快速排序算法代码举例

 1 #include <string>
 2 #include<iostream>
 3 
 4 #define SWAP(X,Y) X=X+Y;Y=X-Y;X=X-Y
 5 
 6 using namespace std;
 7 
 8 void qsort(int a[],int left,int right); //快速排序
 9 void print(int a[], int len);
10 
11 
12 int main(int argc, char *argv) {
13 
14     int a[11] = {0,99,45,12,36,69,22,62,796,4,696 };
15     printf("before sort:
");
16     print(a, 10);
17     qsort(a, 1, 10);
18     printf("after sort:
");
19     print(a, 10);
20     return 0;
21     
22 
23 }
24 /*
25 **实现数据从小到大的排列
26 */
27 void qsort(int a[], int left, int right) {
28     int i, j;
29     i = left;
30     j = right;    
31     a[0] = a[left];    //预留数组第一个元素作为比较基准base
32 
33     while (i < j) {
34         while (i<j&&a[0]<a[j])
35         {
36             j--;              //数组从右向左移动
37         }
38         if (i < j)
39         {
40             a[i] = a[j];
41             i++;
42         }
43 
44         while (i<j&&a[i]<=a[0])
45         {
46             i++;           //数组从右向左移动
47         }
48         if (i < j) {
49             a[j] = a[i];
50             j--;
51         }
52     }
53     a[i] = a[0];     //将基准值放入数组
54     
55     if (left < i) {   
56         qsort(a, left, j - 1);    //分治基准的左侧
57     }
58 
59     if (i < right) {
60         qsort(a, j+1, right);
61     }
62 }
63 
64 
65 void print(int a[], int len) {
66     for (int i = 1; i <= len; i++) {
67         printf("a[%d]=%d ", i, a[i]);
68     }
69     printf("
");
70 }
View Code

该代码在VS2015上运行如下图3-1所示:

部分随笔转载自网友nba76ers 博客:https://www.cnblogs.com/foreverking/articles/2234225.html

注:具体算法示意图也可以参考网友nba76ers 博客

原文地址:https://www.cnblogs.com/xuelanga000/p/11383548.html