快速排序

基本原理

  a. 从线性表中选取一个元素,设为flag

  b. 然后将线性表后面小于flag的元素移动到前面,在前面大于flag的元素移到后面

  c. 结果就将线性表分成了两部分(称为两个子表),flag插入到其分界线的位置处,这个过程称为线性表的分割

  d. 通过对线性表的一次分割,就以flag为分界线,将线性表分成了前后两个子表,且前面子表中的所有元素均不大于flag,而后面子表中的所有元素均不小于flag

  e. 对分割得到的子表按上述原则进行分割,知道所有子表为空,此时线性表排序完成

操作流程

  a. 在表的第一、中间与最后一个元素中选取中项,设为 P(middle) ,并将 P(middle) 赋值给 flag ,再将表中的第一个元素移到 P(middle) 的位置上

  b. 设置两个指针 left 和 right 分别指向表的起始与最后的位置,反复做以下两步

     i. 将 right 逐渐减小,并逐次比较 P ( right ) 与 flag ,直到发现一个 P ( right ) < flag 为止,将 P ( right ) 移到 P ( left ) 的位置上

    ii. 将  left 逐渐减大,并逐次比较 P ( left ) 与 flag ,直到发现一个 P ( left ) > flag 为止,将 P ( left ) 移到 P ( right ) 的位置上

  c.当指针 left 和 right 指向同一个位置(即  left =right )为止,此时将 flag 移到 P ( left ) 位置上

效率

  快速排序法在最坏的情况下需要 n ( n-1 ) /2 次比较,实际效率比冒泡排序高

程序代码

  1 /**
  2   ******************************************************************************
  3   * @file           : quick_sort.c
  4   * @brief          : 快速排序函数及其使用范例
  5   ******************************************************************************
  6   * @attention
  7   *
  8   * 本程序参考了《计算机软件技术基础》3.3.1例程
  9   * 表长度大于十,对表进行分割
 10   * 表长度小于十,对表使用冒泡排序
 11   * 需要注意的是,本快速排序文件中的void main()与bubble_sort.c文件中的完全相同
 12   * 在void quick_sort()中调用了void bubble_sort(),该函数在bubble_sort.c中,本文件不再写出
 13   * 排序算法本体为void quick_sort(T p[],int size)
 14   * 使用测试及范例在void main()中
 15   * 
 16   ******************************************************************************
 17   */
 18 
 19 #include<iostream>
 20 #include<iomanip>
 21 
 22 using namespace std;
 23 
 24 /**
 25   * @brief  快速排序函数
 26   * @param  p: 指向待排序数据的指针
 27   * @param  size: 待排序数据的个数
 28   * @retval 分界线位置
 29   */
 30 template<class T>
 31 void quick_sort(T *p,int size)
 32 {
 33     int left,right,middle,temp;
 34     T flag;
 35     left=0;
 36     right=size-1;
 37     middle=(left+right)/2;
 38 
 39     if((p[left]>=p[right])&&(p[right]>=p[middle]))temp=right;
 40     else if((p[left]>=p[middle])&&(p[middle]>=p[right]))temp=middle;
 41     else temp=left;
 42     flag=p[temp];                                   //选取标志
 43     p[temp]=p[left];
 44     if(size>10)
 45     {
 46         while (left!=right)
 47         {
 48             while((left<right)&&(p[right]>=flag))  //逐渐减小right,直到发现p[right]<flag
 49                 right=right-1;
 50             if(left<right)
 51             {
 52                 p[left]=p[right];
 53                 left=left+1;
 54                 while ((left<right)&&(p[left]<=flag))//逐渐增大left,直到发现p[left]>flag)
 55                     left=left+1;
 56                 if(left<right)
 57                 {
 58                     p[right]=p[left];
 59                     right=right-1;
 60                 }  
 61             }
 62         }
 63         p[left]=flag;
 64         quick_sort(p,left);
 65         quick_sort(p+left+1,size-left-1);
 66     }
 67     else
 68     {
 69         bubble_sort(p,size);
 70     }
 71     
 72 }
 73 
 74 void main()
 75 {
 76     int i,j,k;
 77     double p[50];
 78     for(i=0,j=0;i<50;i++,j++)   //载入待排序序列
 79     {
 80         p[i]=j;
 81         if(j==9)j=-1;
 82     }
 83     cout<<"排序前的序列"<<endl;
 84     for(i=0,k=0;i<10;i++)
 85     {
 86         for(j=0;j<5;j++)
 87         {
 88             cout<<p[k]<<"   ";
 89             k=k+1;
 90         }
 91         cout<<endl;
 92     }
 93     cout<<endl;
 94     quick_sort(p,50);
 95     cout<<"排序后的序列"<<endl;
 96     for(i=0,k=0;i<10;i++)
 97     {
 98         for(j=0;j<5;j++)
 99         {
100             cout<<p[k]<<"   ";
101             k=k+1;
102         }
103         cout<<endl;
104     }
105     cout<<endl;
106 }

 

posted @ 2020-04-13 20:11  曲杨  阅读(173)  评论(0)    收藏  举报