• 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 博客

  • 相关阅读:
    nginx重启失败的解决方法
    Linux开机禁用开启防火墙
    Linux查看系统版本信息的几种方法
    Linux修改时区的正确方法
    Linux中awk的gsub函数用法
    Linux 的mktemp 命令详解
    tomcat的简单概要小结
    {面试题8: 旋转数组的最小数字}
    {面试题7: 使用两个队列实现一个栈}
    {面试题7: 用两个栈实现队列}
  • 原文地址:https://www.cnblogs.com/xuelanga000/p/11383548.html
Copyright © 2020-2023  润新知