一,前言
系统学习算法,就找北大y总。不得不说,得到了y总的真传,这算法题岂不是道道都能ac啊?在此,本算法小宝总结最近两天刚看的快排和归排。(有不足之处的地方请大佬指正,谢谢)
二,排列
排列在之前语法题中也经常遇见,大多都是用暴力直接做,那样的效率并不高,由此为大家带来两种较为简便的方法供大家参考。
1.快速排序
a.概述
顾名思义,能很快的完成排序。其本质是利用数组把数字存储起来,然后在数组的首尾各设一个指针来指向首尾两个元素,再设置一个参考值(即用一个新的指针来指向首,尾,中三个位置的任意一个{一般我都指向中间元素,这样不容易TLE})。
为了完成排序我们需要一个两重循环。第一个循环的条件是第一个指针的位置小于第二个指针,两指针一旦相遇则循环停止
先从首元素开始循环比较,由于是在数组前端,为了排序,我们需要当指针指向的值小于参考值,则指针向右移动一位,直到遇到大于参考值时指针停止移动, 二重循环停止。
然后从尾元素开始循环比较,由于是反方向移动,因此这里的条件就会变成指针指向的值大于参考值时左移指针。遇到比参考值小的指针就停止移动,二重循环停止。
若此时左右两个指针还未相遇,则通过swap来交换两个指针指向的数值,这样才能继续移动,直到两个指针相遇,循环停止。
基本的步骤已经完成,接下来通过递归,使整个数组变得有序即可。
b.例题讲解
这道题首先确定数据范围在[1, 100000],因此用int就足够了。
头文件准备充分,格式完整,定义不变的N来表示数组元素个数,多写的目的是为了防止溢出,然后全局变量n和q[N]。
接下来定义快排函数(四步走大法)
第一步:判断两指针的位置。当 l >= r 时,即数组中只有一个数或没有数时,就不用排序,直接返回即可。
第二步:判断得出数组中有两个即以上的数字时,就可以确定首尾指针以及中间的参考值。
第三步:两重循环,遇到满足条件时即可移动相应指针。
第四步:两个范围的递归。
接下来就回到主函数中来完成对各数据的输入输出。
这样做完以后就可以得出结果:
这样快速排序就完成了啦。
c.总结
上面的函数部分就是快速排序的精华,作为算法初学者,重点是先把模板记住,这样才能铺好结实的基础,因此我的建议是大家可以拿同一道题多练几次,对模板达到十分熟练。
2.归并排序
a.概述
归并排序,即通过将一个数组分成两个小数组进行递归以使两个小数组按从小到大顺序排序。再对两个小数组的每次各拿一个元素进行循环比较,将两者中的较小者拿出来放在一个新的数组中。当一个小数组循环完毕,另一个数组就顺次排在新数组的尾部。之后,将新数组的值重新对应赋给原数组,输出原数组即可。
b.例题讲解
根据数据范围可得出数据类型用“ int ”即可
然后直接进入归并函数部分:(五步)
(归并排序和快速排序的区别:快排后递归,归并是先递归, 归并还需要开辟一个新的暂存数组来存储数据)
第一步:判断数组的元素个数,小于等于1就直接返回。(条件语句实现)
第二步:确定数组中点指针,同时根据中点来将原指针分为两个排好序的数组。(递归实现)
第三步:确定暂存数组的起点指针,确定两个小数组的起点指针,并且从起点出发将指针对应的元素进行大小比较,将较小者依次存入暂存数组,同时将其移动到下一位再进行比较(循环实现)
第四步:若一个小数组的数值全部存储而另一个还没有存储完毕,则直接将该数组的值依次从暂存数组的尾部存入。
第五步:将暂存数组的数据依次对应覆盖存入原数组。
然后进入主函数:
依次完成即可。
c.总结
和快速排序一样,一定要在学完之后多加温习!
三,小结
本人刚入算法,深知菜就多练这一道理,因此我会将算法系列持续更新的,谢谢各位大佬的观看。
最后,如果有您的点赞加关注那么就更好了,谢谢!