排序算法之交换排序(冒泡排序和快速排序)

本文详细介绍了交换排序的基本思想和实现,包括冒泡排序和快速排序两种典型的交换排序算法。冒泡排序是稳定的排序,通过每轮比较使大元素逐渐后移。快速排序则是通过一趟排序将序列划分为两部分,再对两部分递归排序,效率高于冒泡排序。文章通过实例解析了快速排序的过程,展示了排序步骤。
摘要由CSDN通过智能技术生成

交换排序的核心思想是:根据序列中两条记录键值的比较结果,判断是否需要交换记录在排序中的位置。其特点是将键值较大(或较小)的记录向序列的前端移动,将键值较小(或较大)的记录向序列的后端移动。

基本排序算法实现:

    void Sort (int arr[],int n)
    {
        int i,j;
        int k;
        for(i=0;i<n-1;i++)  //n-1轮循环
        {
            for(j=i+1;j<n;j++)
            {
                if(arr[i]<arr[j])   //比较判断
                {
                    swap(&arr[i],&arr[j]);  //位置交换
                }
            }
        }
    }

冒泡排序

冒泡排序的基本原则是:比较两两相邻的记录的关键字,使不满足序列要求的记录交换位置,直到n-1轮循环结束。冒泡排序算法是稳定的。

冒泡排序动图演示:

 第一轮排序,注意观察,可以看到两两比较,小的往右移动,大的往左移动,第一轮排序结束可以看到“0”已排好序,已经排在了最右边的对应位置,后面几轮排序“0”也不再移动了。


第二轮可以看到又一次确定了“1”的位置,后面几轮排序,“1”也不会再移动了。 


 依此类推,第三轮把“2”放在对应的位置,“2”后面排序也不会再移动了。后面还有第四轮、第五轮直到第n-1轮就能排序结束。

排序完成效果:


快速排序

快速排序是对冒泡排序的改进,快速排序的基本思想是:通过一趟排序,将序列中的数据分割为两个部分,其中一部分的所有数值都比另一个部分的小;然后按照此种方法,对两部分数据分别进行快速排序,直到参与排序的两个部分都有序为止。

一开始需要设置一个参考值,(通常选用序列中第一个记录的键值作为参数),通过与参考值的比较来划分数据,把序列划分成上述的两个部分。快速排序是不稳定的排序算法。

举个升序的例子

 第一层排序关键字(参考值)key=5,第一层快速排序过程如下:

首先把序列的头和尾位置看作“i”和“j”双方,双方好像下跳棋一样,“i”移动的依据i++直到所在位置的值大于key值就停止++,“j”移动的依据j--是所在位置的值小于key值就停止“j”--,当一方停止就更换对方来进行移动的操作,直到双方往中间位置移动到“i”=“j”就代表以本层key值划分的排序结束。

第一轮,“i”先操作,“i”位置的值5为参考值,所以先让参考值的位置视为空值,“i”结束操作,换“j”操作。

第二轮,“j”操作,“j”位置的值5去和key值5比较,相等无法移动;所以“j”往前移动一格,到值为7的位置(如下图),用值7去和key值5比较,发现7大于5,也无法移动;所以“j”往前再移动一格,到值为3的位置(如下图),用值3和key值5比较,发现3小于5,所以把值3移动到“i”空值的位置去(如下图),“j”成功移动就结束操作,换“i”操作。

 第三轮,“i”操作,“i”前进一格到值为0的位置(如下图),用0和key值5去比较发现,0小于5,不移动;所以“i”前进一格,到值为9的位置(如下图),9和key值5比较,9大于5,所以把9移动到“j”空值的位置去(如下图),“i”成功移动结束操作,换“j”进行操作。

 第四轮,“j”操作,“j”前进一格到值为6的位置(如下图),用6和key值去比较,6大于5,不移动;继续前进一格,到值为 4的位置(如下图),用4和key值去比较,4小于5,把4移动到“i”空值的位置去(如下图);“j”成功移动,换“i”操作。

 第五轮,“i”操作,“i”前进一格,到值为8的位置(如下图),用8和key值5比较,8大于5,所以把8移动到“j”空值的位置(如下图),“i”结束操作,换“j”操作。

 第六轮,“j”操作,“j”前进一格,到值为1的位置(如下图),用1和key值5去比较,1小于5,所以把1移动到“i”空值的位置去(如下图),“j”操作结束,换“i”操作。

 第七轮,“i”操作,前进一格,发现“i”和“j”重合了(如下图),开始下跳棋之前,我们就规定了当i=j的时候代表本层排序结束。接下来把key值放到重合的位置,本层结束排序结果为(如下图)3041586975。

 从上图可以很直观的看出来key值5的左边都是不大于5的数值,右边都是不小于5的值。成功的划分出来两个部分。


接下来两个部分内部通过递归调用进行排序,排序也是和上面的跳棋举例一样的方式,第一个位置的值设置为key值,“i”位置为空,“j”先操作,“i”依次交替操作,直到二者重合。每一层递归操作之后位置变动如下图。

二层排序如下图:

 三层排序如下图,直接把三层排序过后产生的单个数字为一部分的4和9排除在外,不需要排序了:

 四层排序如下图:

 最终排序结果为:


如果对您有帮助的话,请留下小脚印再离开吧!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

super码力

么么哒,夏天来块儿冰西瓜!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值