【排序算法】-快速排序(QuickSort)

简介

  快速排序算法又称划分交换排序(Partition-Exchange Sort)最早由东尼·霍尔(C. A. R. Hoare)-图灵奖得主于1960年提出的。常见的排序算法大概七八种,其中快速排序是使用很广泛、速度也较快的一种算法,其名“快速”就能看出它的特点。

思想

  快速排序采用了“分治法”策略,把一个序列划分为两个子序列。

  • 在待排序列中,选择一个元素作为“基准”(Pivot)。

  • 所有小于“基准”的元素,都移动到“基准”前面,所有大于“基准”的元素,都移动到“基准”后面(相同的数可以到任一边)。此为“分区”(partition)操作。

  • 分别对“基准”两边的序列,不断重复一、二步,直至所有子集只剩下一个元素。

分析

  现有一数列:


这里写图片描述

  对此数列进行快速排序。选择第一个元素 45 作为第一趟排序的“基准”(基准值可以任意选择)。

  第一趟:将元素 45 拿出来,分别从数列的两端开始探测

  • 首先从右向左开始,找到第一个小于 45 的元素为 25,然后将 25 放置到第一个元素 45 的位置上。此时数列变为:


    这里写图片描述

  • 然后从左向右开始,找到第一个大于 45 的元素为 66 ,然后将 66 放置到原先元素 25的位置上。此时数列变为:


    这里写图片描述

  • 继续从右向左开始,找到第二个小于 45 的元素为 10 ,然后将 10 放置到原先元素 66的位置上,此时数列变为:


    这里写图片描述

  • 继续从左向右开始,找到第二个大于 45 的元素为 90 ,然后将 90 放置到原先元素 10的位置上,此时数列变为:


    这里写图片描述

  • 继续从右向左开始,此时发现左右碰面,因此将“基准”45 放置到原先元素 90 的位置上,此时数列变为:


    这里写图片描述

  至此,第一轮结束,“基准”45 左侧为小数区,右侧为大数区。同样的分别对小数区和大数区应用此方法直至完成排序。

实现(C++)

快速排序核心算法:

//每一轮的快速排序
int QuickPartition (int a[],int low,int high)
{
    int temp = a[low];//选择数组a的第一个元素作为“基准”
    while(low < high)
    {
        while(low < high && a[high] >= temp )//从右向左查找第一个小于“基准”的数
        {
            high--;
        }
        if (low < high)
        {
            a[low] = a[high];//将第一个找到的大于“基准”的数移动到low处
            low++;
        }

        while(low < high && a[low] <= temp)//从左向右查找第一个大于“基准”的数
        {
            low++;
        }
        if(low < high)
        {
            a[high] = a[low];//将第一个找到的小于“基准”的数移动到high处
            high--;
        }

        a[low] = temp;//将“基准”填到最终位置
    }
    return low;//返回“基准”的位置,用于下一轮排序。
}

递归调用QuickSort(分治法):

//快速排序-递归算法
void QuickSort (int a[],int low,int high)
{
    if(low < high)
    {
        int temp = QuickPartition(a,low,high);//找出每一趟排序选择的“基准”位置
        QuickSort(a,low,temp-1);//递归调用QuickSort,对“基准”左侧数列排序
        QuickSort(a,temp+1,high);//对“基准”右侧数列排序
    }
}

主函数调用

void main()
{
    int a[8]={45,38,66,90,88,10,25,45};//初始化数组a
    QuickSort(a,0,7);

    cout<<endl<<"排序后:";
    for(int i = 0;i <= 7;i++)
    {
        cout<<a[i]<<" ";
    }
    getchar();
}

排序后结果:


这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值