zoukankan      html  css  js  c++  java
  • 内部排序->交换排序->快速排序

    文字描述 

      快速排序是对起泡排序的一种改进。它的基本思想是,通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

      一趟快速排序描述:假设待排序的序列为{L.r[s], L.r[s+1], … , L.r[t]},首先任意选取一个记录(通常选第一个记录L.r[s])作为枢轴(pivot), 然后按下述原则重新排列其余记录:将所有关键字较它小的记录都安置在它的位置之前,将所有关键字较它大的记录都安置在它的位置之后。由此以该“枢轴”记录最后所落得位置i作分界线,将序列{L.r[s], L.r[s+1], … , L.r[t]}分割成两个子序列{L.r[s], L.r[s+1], …, L.r[i-1]}和{L.r[i+1], L.r[i+2], …, L.r[t]}。至此,完成一趟快速排序。

    示意图

    算法分析

      快速排序的平均时间为knlnn, 其中n为记录个数,k为某个常数。经验证明,在所有同数量级(nlogn)的排序方法中,其平均时间性能最好。但是,若初始记录序列按关键字有序或基本有序时,快速排序将蜕化为起泡排序,其时间复杂度为n*n.

      辅助空间为1,但是需要一个栈空间来实现递归。若每趟排序都将记录序列均匀的分割成长度相接近的两个子序列,则栈的最大深度为[log2n]+1;若每趟排序之后,枢轴位置都在最边上,则栈的最大深度为n。

      是不稳定的排序方法

    代码实现

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #define DEBUG
      5 
      6 #define EQ(a, b) ((a) == (b))
      7 #define LT(a, b) ((a) <  (b))
      8 #define LQ(a, b) ((a) <= (b))
      9 
     10 #define MAXSIZE 20
     11 typedef int KeyType;
     12 typedef char InfoType;
     13 typedef struct{
     14     KeyType key;
     15     InfoType otherinfo;
     16 }RedType;
     17 
     18 typedef struct{
     19     RedType r[MAXSIZE+1];
     20     int length;
     21 }SqList;
     22 
     23 void PrintList(SqList L){
     24     int i = 0;
     25     printf("下标值:");
     26     for(i=0; i<=L.length; i++){
     27         printf("[%d] ", i);
     28     }
     29     printf("
    关键字:");
     30     for(i=0; i<=L.length; i++){
     31         printf(" %-3d", L.r[i].key);
     32     }
     33     printf("
    其他值:");
     34     for(i=0; i<=L.length; i++){
     35         printf(" %-3c", L.r[i].otherinfo);
     36     }
     37     printf("
    
    ");
     38     return ;
     39 }
     40 
     41 /*
     42  *交换顺序表L中子表L.r[low,...,high]的纪录,枢轴记录到位,
     43  *并返回其所在位置,此时在它之前(后)均不大于(小于)它
     44  */
     45 int Partition(SqList *L, int low, int high)
     46 {
     47     //用字表的第一个记录作枢轴纪录
     48     L->r[0] = L->r[low];
     49     //pivotkey表示枢轴记录的关键字值
     50     KeyType pivotkey = L->r[low].key;
     51 
     52     //从表的两端交替向中间扫描
     53     while(low<high){
     54         //将比枢轴记录小的记录移到低端
     55         while(low<high && L->r[high].key>=pivotkey)    --high;
     56         L->r[low] = L->r[high];
     57 
     58         //将比枢轴记录大的记录移到高端
     59         while(low<high && L->r[low].key<=pivotkey) ++low;
     60         L->r[high] = L->r[low];
     61     }
     62     //枢轴记录到位
     63     L->r[low] = L->r[0];
     64     //返回枢轴位置
     65     return low;
     66 }
     67 
     68 /*
     69  * 对顺序表L中子表L.r[low,...,high]作快速排序
     70  */
     71 void QSort(SqList *L, int low, int high)
     72 {
     73     
     74     KeyType pivotkey;
     75     if(low<high){
     76         //将L.r[low,...,high]一分为二,低(高)于pivotkey的均不大于(小于)它
     77         pivotkey = Partition(L, low, high);
     78 #ifdef DEBUG
     79         printf("一趟快速排序后(low=%d, high=%d), pivotkey=%d
    ",low, high, pivotkey);
     80         PrintList(*L);
     81 #endif
     82         //对低字表递归排序,pivotkey是轴枢位置
     83         QSort(L, low, pivotkey-1);
     84         //对高子表递归排序
     85         QSort(L, pivotkey+1, high);
     86     }
     87 }
     88 
     89 /*对顺序表L作快速排序*/
     90 void QuickSort(SqList *L)
     91 {
     92     printf("对顺序表L作快速排序:
    
    ");
     93     QSort(L, 1, L->length);
     94 }
     95 
     96 int  main(int argc, char *argv[])
     97 {
     98     if(argc < 2){
     99         return -1;
    100     }
    101     SqList L;
    102     int i = 0;
    103     for(i=1; i<argc; i++){
    104         if(i>MAXSIZE)
    105             break;
    106         L.r[i].key = atoi(argv[i]);
    107         L.r[i].otherinfo = 'a'+i-1;
    108     }
    109     L.length = (i-1);
    110     L.r[0].key = 0;
    111     L.r[0].otherinfo = '0';
    112     printf("输入数据:
    ");
    113     PrintList(L);
    114     //对顺序表L进行快速排序    
    115     QuickSort(&L);
    116 
    117     return 0;
    118 }
    快速排序

    运行

  • 相关阅读:
    地形碰撞检测方法(转)
    无法在web服务器上启动调试 打开的URL的IIS辅助进程没有运行
    VBA中变量申明
    由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面
    JSON与XML的比较
    缺少对公共可见类型或成员“XXX”的 XML 注释
    iis下网站无法找到该页 (iis无法显示aspx文件问题)
    C#实现所有经典排序算法
    因为此版本的应用程序不支持其项目类型(.csproj) .
    C# winform 捕获全局异常
  • 原文地址:https://www.cnblogs.com/aimmiao/p/9367645.html
Copyright © 2011-2022 走看看