快速排序 C++实现

快速排序

思想:运用递归将数据以大化小,将排序看成是让每个元素大于左边,小于右边。
算法:选取数据区段内一个元素作为基准,对数据从左右分别向中间扫描,将左边大于基准的值依次放到右边,将右边小于基准的值依次放到左边,将基准放在最后左右指针相遇的位置,这样该基准将这个区段划分为左右两个子区间,基准相对于左右子区间是有序的。对基准左边和右边迭代该算法, 直到原始数据的每个元素都轮到作为基准,便实现每个元素都有序,都大左小右。
代码:(C++实现)
1
void QuickSork(SeqList R, int low, int high)
2
{
3
    int pivotpos;   // 划分之后的基准的位置变量
4
    if(low < high)    // 迭代的出口是low=high,即当区间长度=high-low+1=1时,便已完成排序,无需再划分子区间:每条记录都大左小右
5
        pivotpos=Partition(R, low, high);         // 若区间长度大于1,则对该区间继续划分子区间,划分结果是左区间均小于                                                // 基准(选R[low]),右区间均大于基准,并返回基准位置
6
    QuickSork(R, low, pivotpos-1);   // 对左区间递归排序
7
    QuickSork(R, pivotpos+1, high);   // 对右区间递归排休 (左右子区间都不包含基准,因为基准已经有序:大于左区间,小于右区间)
8
}
9
10
int Partition(SepList R, int i, int j)
11
{
12
    ReceType pivot=R[i];    // 用区间的第一个记录作为基准,这样第一个位置便为空,即可以存放换序过来的小于基准的记录
13
    while(i<j)           // 从区间两端向中间扫描,直到i=j为止
14
    {
15
        while(i<j&&R[j].key>=pivot.key)   // R[j]从后向前扫描,直到遇到第一个小于pivot的记录
16
            j--;
17
        if(i<j)    // 该条件为避免上面的循环结束时,i=j,即两指针之间的所有记录都比pivot大,便不用交换顺序
18
        {
19
            R[i]=R[j];      // 把R[j]放在R[i]的位置,此时R[j]位置为空,可以存放换序过来的大于pivot的记录
20
            i++          // R[i]已完成扫描并存入新纪录,i指针右移一位,等待参与下一轮向右扫描
21
        }
22
        while(i<j&&R[i].key<=pivot.key)     // R[i]从前面向后面扫描,直到遇到第一个大于pivot的记录。条件i<j,为保证两指针没有重叠,即尚有未扫描到的记录
23
            i++;
24
        if(i<j)    // 该条件为避免上面的循环结束时,i=j,即两指针之间的所有记录都比pivot小
25
        {
26
            R[j]=R[i];     // 把R[i]放在前面空出来的R[j]的位置上,此时R[i]为空,可以存放换序过来的小于pivot的记录
27
            j--;          // R[j]已完成扫描并存入新纪录,j指针左移一位,等待参与下一轮向左扫描
28
        }
29
    }
30
    R[i]=pivot.key;    // 区间内所有记录都扫描完后,即i=j,将基准记录存放在最后空出来的R[i]位置处
31
    return i;        // 返回基准的位置,此时该区间完成调序,使得基准大于左边记录,小于右边记录
32
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值