数据结构与算法之一快速排序

    快速排序采用的是分治法,何为分治?意思是将原问题分解为若干个规模更小但结构与原问题相似的子问题,递归地解这些子问题(在程序中就是递归调用),然后将这些子问题的解组合为原问题的解。
    快速排序的基本思想:

    ①分解:
    在数组R[]中任选一个数作为基准(Pivot),习惯上把第一个数作为基准,以此基准(Pivot)将当前无序区划分为左、右两个较小的子区间R[low...pivotpos-1]和R[pivotpos+1...high],并使左边子区间中所有的数均小于等于基准,右边的子区间中所有的数均大于等于基准,而基准pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
  注意:
     划分的关键是要求出基准所在的位置pivotpos。划分的结果可以简单地表示为(注意pivot=R[pivotpos]):
     R[low..pivotpos-1](即为数组中第low个数到第pivotpos-1个数)≤R[pivotpos](基准)≤R[pivotpos+1..high]
                  其中low≤pivotpos≤high。
②求解:
     通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。
③组合:
     因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。
    快速算法:Quick_sort

     void Quick_sort(int a[],int low,int heigh) //对a[low..heigh]快速排序
{
         int pivot_pos; //划分后基准的位置
         if(low<heigh) //当区间长度大于1时才进行快速排序
      {
           pivot_pos=Partitions(a,low,heigh); //对a[low..heigh]进行划分
          Quick_sort(a,low,pivot_pos-1); //对左区间递归排序
          Quick_sort(a,pivot_pos+1,heigh); //对右区间递归排序
        }
}  

 (1) 简单的划分方法
    ① 具体做法
  第一步:(初始化)设置两个指针i和j,它们的初值分别为区间的下界和上界,即i=low,i=high;选取无序区的第一个记录R[i](即R[low])作为基准记录,并将它保存在变量pivot中;
  第二步:令j自high起向左扫描,直到找到第1个小于pivot的数R[j],将R[j])移至i所指的位置上,这相当于R[j]和基准R[i](即pivot)进行了交换,使小于基准pivot.的数移到了基准的左边,交换后R[j]中相当于是pivot;然后,令i指针自i+1位置开始向右扫描,直至找到第1个大于pivot的数R[i],将R[i]移到i所指的位置上,这相当于交换了R[i]和基准R[j],使大于基准的数移到了基准的右边,交换后R[i]中又相当于存放了pivot;接着令指针j自位置j-1开始向左扫描,如此交替改变扫描方向,从两端各自往中间靠拢,直至i=j时,i便是基准pivot最终的位置,将pivot放在此位置上就完成了一次划分。

      划分算法:Partitions
int Partitions(int a[],int i,int j)
{
         int pivot=a[i];
         while (i<j)
     {
         while(i<j&&a[j]>=pivot) j--;
         if(i<j) a[i++]=a[j];
         while(i<j&&a[i]<=pivot) i++;
         if(i<j) a[j--]=a[i];
     }
 a[i]=pivot;
 return i;
}      快速排序执行过程
     快速排序执行的全过程可用递归树来描述。

     整体程序:

#include<iostream>
using namespace std;
int Partitions(int a[],int i,int j);
void Quick_sort(int a[],int low,int heigh);
int main()
{
        int r[10],i;
        cout<<"Please input ten number: ";
        for(i=0;i<10;i++)
             cin>>r[i];
       Quick_sort(r,0,9);
       cout<<"The result of resort: ";
       for(i=0;i<10;i++)
             cout<<r[i]<<' ';
       return 0;
}
int Partitions(int a[],int i,int j)
{
         int pivot=a[i];
         while (i<j)
      {
           while(i<j&&a[j]>=pivot) j--;
           if(i<j) a[i++]=a[j];
           while(i<j&&a[i]<=pivot) i++;
           if(i<j) a[j--]=a[i];
        }
     a[i]=pivot;
     return i;
}

void Quick_sort(int a[],int low,int heigh)
{
         int pivot_pos;
         if(low<heigh)
     {
         pivot_pos=Partitions(a,low,heigh);
         Quick_sort(a,low,pivot_pos-1);
         Quick_sort(a,pivot_pos+1,heigh);
       }
}

注意:此程序最容易出错的地方是在函数的声明处,在C++的某本书中有提到,对函数进行提前声明时,可以只写函数参数表中的参数类型,不需要写参数名,但是在本程序中若在函数声明时只写参数类型,编译不通过。 

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值