宝哥软件园

15天快速算法系列第一天整理七经[I]

编辑:宝哥软件园 来源:互联网 时间:2021-11-14

针对现实中的排序问题,算法有七剑可以助你成功。一、排序分为四类:交换排序:包括冒泡排序和快速排序。选择性排序:包括直接选择性排序和堆排序。插入排序:包括直接插入排序和希尔排序。合并排序:合并排序。所以我们今天讨论的是交换排序。众所周知,C#类库提供的排序是快速排序。为了让今天的玩法变得有趣,我们设计了一个算法来和类库提供的快速排序竞争。为KO的对手而战。气泡排序:首先,我们将自行设计“气泡排序”。这种排序的现实例子是:如果我抓起一把沙子,它仍然进入水中,沙子会立即沉入底部,沙子上的灰尘会因为惯性暂时沉入底部,但它会像气泡一样立即浮出水面,最终真相会大白。至于冒泡的想法,我不会说这样的官方理论,也不会贴那些文字。我的想法是看图说话。那我们就照上图吧。

为了达到泡沫效应,我们必须设置一组数字。想想看,怎么泡?如何体验重沉轻浮?第一步是:我们对比40和20,发现40才是老大,没必要交换。第二步,往前推一步,就是把20和30比较,发现30是老大,就要交换。第三步:把兑换的20和10进行对比,发现你是老板,不需要兑换。第四步:用50换10,发现50才是老大。最后,在遍历之后,我们发送了数组中最小的数字。听着,我们朝着目标又迈进了一步。现在我们都知道自己的想法了,我们强烈要求和快排竞争,要么你死,要么我活。复制代码如下:使用系统;使用系统。集合。通用;使用系统。Linq使用系统。文字;使用系统。诊断;使用系统。穿线;命名空间冒泡排序{公共类程序{ static void main(string[]args){//五个比较为(int I=1;I=5;I){ Listint list=new Listint();//为(int j=0)在数组中插入2k个随机数;j 2000年;j ) {螺纹。睡眠(1);名单。添加(新的随机((整数)日期时间。现在。滴答)。Next(0,100000));}控制台。write line(' n第' I '个比较:');秒表手表=新秒表();看着。start();var结果=列表。OrderBy(single=single)。to list();看着。stop();控制台。write line(' n点击排序需要时间:'注意。elapsedmirisseconds);控制台。WriteLine('在输出之前,有十个数字: '字符串。join(',',result。以(10)为例。tolist()));看着。start();结果=起泡rt(列表);看着。stop();控制台。writeline (' nBubble排序需要时间:' watch。elapsedmirisseconds);控制台。WriteLine('在输出之前,有十个数字: '字符串。join(',',result。以(10)为例。tolist()));} }//冒泡排序算法静态Listint冒泡排序(Listint List){ int temp;//第一级循环:表示比较的次数,如list.count的次数,count-1次为(int I=0;我列举。计数-1;I) {//list.count-1:取最后一个数目的下标数据。//ji:从后到前的下标必须大于从前到后的下标,否则会被超越。for (int j=list。计数-1;j . I;j-){//如果上一个数字大于下一个数字,则交换If(list[j-1]list[j]){ temp=list[j-1];list[j-1]=list[j];list[j]=temp;} } }返回列表;} } }

呜呜,看着这两种体检报告,我的心都凉了,我的泡泡马上就要排名KO了。真的很惨。难怪有人说泡沫效率低,但事实证明tmd真的很低。快速排名:既然能摆脱冒泡的KO,马上就会引起我们的兴趣。为什么tnd快速排名这么快?我们必须仔细研究它。上图:

从图中我们可以看到:左指针、右指针和基引用号。其实思路挺简单的,就是通过第一次遍历找到数组的切割点(让左右指针重合)。第一步:首先,我们取数组左边位置的数字(20)作为基引用。第二步:从数组的右边向前看,总是找到一个小于(base)的数字。如果找到,将此数字分配到左边的位置(即分配10到20)。此时数组为10、40、50、10、60,左右指针前后各10个。第三步:从数组的左边位置向后看,总是找到一个大于(base)的数。如果找到,将此数字分配到正确的位置(即40到10)。此时数组为10、40、50、40、60,左右指针分别为40。第四步:重复“第二步、第三步”,直到左右指针重合,最后插入(base)到40的位置。此时,数组值为:10、20、50、40、60,排序完成一次。第五步:此时20已经渗入阵中,20左侧的一组数量小于20,而20右侧的一组数量大于20。以20为突破点,按照‘一、二、三、四’的步骤进行,最终完成快排。同样,我们将自己的设计与类库提供的快照进行比较。看看谁是ox x。

复制代码代码如下:使用系统;使用系统。集合。通用;使用系统Linq .使用系统。文字;使用系统。穿线;使用系统。诊断;命名空间快速排序{公共类程序{静态void Main(字符串[]参数){ //5次比较for(int I=1;I=5;I){ Listint list=new Listint();//插入200个随机数到数组中for(int j=0;j 200j){ 0螺纹。睡眠(1);名单。添加(新的随机((整数)日期时间。现在。滴答)。Next(0,10000));}控制台WriteLine('n第我次比较:');秒表手表=新秒表();看着start();定义变量结果=列表OrderBy(single=single).to list();看着stop();控制台WriteLine('n系统定义的快速排序耗费时间:'看着elapsedmirisseconds秒);控制台WriteLine(“”输出前是十个数: '字符串。连接(',',结果。以(10)为例. ToList()));看着start();新的快速分类()。快速排序(列表,0,列表计数-1);看着stop();控制台WriteLine('n俺自己写的快速排序耗费时间:'看着elapsedmirisseconds秒);控制台WriteLine(“”输出前是十个数: '字符串。加入(',',列表。以(10)为例. ToList()));} } }公共类快速分类{///摘要///分割函数////summary///param name='list '待排序的数组/param///param name='left '数组的左下标/param///param name=' right '/param///returns/returns public int Division(list int list,int left,int right) { //首先挑选一个基准元素int BaseNum=list[left];而(左右){ //从数组的右端开始向前找,一直找到比基础小的数字为止(包括基础同等数)而(左右列表[right]=BaseNum)right=right-1;//最终找到了比baseNum小的元素,要做的事情就是此元素放到基础的位置list[left]=list[right];//从数组的左端开始向后找,一直找到比基础大的数字为止(包括基础同等数)而(左右列表[left]=BaseNum)left=left 1;//最终找到了比baseNum大的元素,要做的事情就是将此元素放到最后的位置list[right]=list[left];} //最后就是把baseNum放到该左边的的位置list[left]=BaseNum;//最终,我们发现左边的位置的左侧数值部分比左边的小,左侧位置右侧数值比左边的大//至此,我们完成了第一篇排序向左返回;} public void快速排序(Listint list,int left,int right) { //左下标一定小于右下标,否则就超越了如果(左右){ //对数组进行分割,取出下次分割的基准标号int i=除法(列表,左,右);//对"基准标号"左侧的一组数值进行递归的切割,以至于将这些数值完整的排序快速排序(列表,左侧,I-1);//对"基准标号"右侧的一组数值进行递归的切割,以至于将这些数值完整的排序快速排序(列表,i 1,右);} } } } }

是的,快就是快,难怪内库要用他作为排序标准。最后,我们应该分享以下内容:冒泡的时间复杂度是0 (n 0(n)-0(n^2).快速排队的时间复杂度为33,360。平均复杂度:N(logN)最差复杂度:0 (n 2)。

更多资讯
游戏推荐
更多+