数据结构动画表示八大排序算法,一看就懂

我们平时玩扑克牌时,摸牌阶段的排序就用到了插入排序的思想

具体实现:

即一般情况下的插入,我们随机列举了一些数字,待插入的数字分为两种情况

(1)待插入的数字是在前面有序数字的中间数,直接比较将x赋值给end+1位置(2)x是最小的一个数,end就会到达-1的位置,最后直接将x赋值给end+1位置

我们一开始并不知道数组是不是有序的,所以我们控制下标,end从0开始,将end+1位置的值始终保存到x中,循环进行单趟排序即可,最后结束时end=n-2,n-1位置的数字保存到x中

总体代码:

直接插入排序总结:

最坏的情况下,每次插入一个数字,前面的数字都要挪动一下,一共需要挪动1+2+3+……+n=n(n+1)/2

③空间复杂度:O(1)

没有借助额外的空间,只用到常数个变量

例如:

①单组排序

和前面的直接插入相同,就是把原来的间隔为1,现在变为gap了,每组分别进行预排序

②多组进行排序

③整个数组进行排序(控制gap)

多次预排序(gap>1)+一次插入排序(gap==1)

(1)gap越大,预排越快,越不接近于有序

(2)gap越小,预排越慢,越接近有序

结果就是:

voidShellSort(int*a,intn){intgap=n;while(gap>1){gap/=2;for(inti=0;i=0){if(a[end]>x){a[end+gap]=a[end];end-=gap;}else{break;}}a[end+gap]=x;}}}希尔排序总结:

每次从数组中选出最大的或者最小的,存放在数组的最右边或者最左边,直到全部有序

我们这里进行了优化,一次排序中,直接同时选出最大的数(a[maxi])和最小的数(a[mini])放在最右边和最左边,这样排序效率是原来的2倍

找到最小的数字(a[mini])和最大的数字(a[maxi]),将它们放在最左边和最右边

ps:其中的begin,end保存记录左右的下标,mini,maxi记录保存最小值和最大值的下标

begin++和end--这样下次就可以排剩下的n-2个数字,再次进行单趟,如此可构成循环,直到begin小于end

整体代码:

直接选择排序总结:

具体实现:、

我们将给定的数组序列,建成一个大堆,建堆从根节点开始就需要多次的向下调整算法

堆的向下调整算法(使用前提):(1)若想将其调整为小堆,那么根结点的左右子树必须都为小堆。(2)若想将其调整为大堆,那么根结点的左右子树必须都为大堆。

向下调整算法的基本思想:

//向下调整算法//以建大堆为例voidAdJustDown(int*a,intn,intparent){intchild=parent*2+1;//默认左孩子较大while(childa[child])//如果这里右孩子存在,//且更大,那么默认较大的孩子就改为右孩子{child++;}if(a[child]>a[parent]){Swap(&a[child],&a[parent]);parent=child;child=parent*2+1;}else{break;}}}建堆思想:从倒数第一个非叶子节点开始,从后往前,依次将其作为父亲,依次向下调整,一直调整到根的位置

建堆图示:

堆排序的思想:1、建好堆之后,将堆顶的数字与最后一个数字交换2、将最后一个数字不看,剩下的n-1个数字再向下调整成堆再进行第1步3、直到最后只剩一个数停止,这样就排成有序的了

for(intend=n-1;end>0;--end){Swap(&a[end],&a[0]);AdJustDown(a,end,0);}整体代码如下:

一趟过程中,前后两个数依次比较,将较大的数字往后推,下一次只需要比较剩下的n-1个数,如此往复

//优化版本的冒泡排序voidBubbleSort(int*a,intn){intend=n-1;while(end>0){intexchange=0;for(inti=0;ia[i+1]){Swap(&a[i],&a[i+1]);exchange=1;}}if(exchange==0)//单趟过程中,若没有交换过,证明已经有序,没有必要再排序{break;}end--;}}冒泡排序总结:

递归版本

hoare的单趟思想:1、左边作key,右边先走找到比key小的值2、左边后走找到大于key的值3、然后交换left和right的值4、一直循环重复上述123步5、两者相遇时的位置,与最左边选定的key值交换这样就让key到达了正确的位置上

动图演示:

其实本质上是hoare的变形

挖坑法单趟思想:1、先将最左边第一个数据存放在临时变量key中,形成一个坑位2、右边先出发找到小于key的值,然后将该值丢到坑中去,此时形成一个新坑位3、左边后出发找到大于key的值,将该值丢入坑中去,此时又形成一个新的坑位4、一直循环重复123步5、直到两边相遇时,形成一个新的坑,最后将key值丢进去这样key就到达了正确的位置上了

//挖坑法intpartion2(int*a,intleft,intright){intkey=a[left];intpit=left;while(left=key){right--;}a[pit]=a[right];//填坑pit=right;while(left=right)return;intkeyi=partion2(a,left,right);//[left,keyi-1]keyi[keyi+1,right]QuickSort(a,left,keyi-1);QuickSort(a,keyi+1,right);}3、前后指针法(推荐这种写法)前后指针的思想:

1、初始时选定prev为序列的开始,cur指针指向prev的后一个位置,同样选择最左边的第一个数字作为key2、cur先走,找到小于key的值,找到就停下来3、++prev4、交换prev和cur为下标的值5、一直循环重复234步,停下来后,最后交换key和prev为下标的值

intpartion3(int*a,intleft,intright){intprev=left;intcur=left+1;intkeyi=left;while(cur<=right){if(a[cur]=right)return;intkeyi=partion3(a,left,right);//[left,keyi-1]keyi[keyi+1,right]QuickSort(a,left,keyi-1);QuickSort(a,keyi+1,right);}

递归展开图

1、三数取中法

但是这是理想情况,当我们面对一组极端情况下的序列,就是有序的数组,选择左边作为key值的话,那么就会退化为O(N^2)的复杂度,所以此时我们选择首位置,尾位置,中间位置的数分别作为三数,选出中间位置的数,放到最左边,这样选key还是从左边开始,这样优化后,全部都变成了理想情况

//快排的优化//三数取中法intGetMidIndex(int*a,intleft,intright){intmid=(left+right)/2;if(a[left]a[right]){returnright;}else{returnleft;}}else{if(a[mid]>a[left]){returnleft;}elseif(a[mid]

我们可以当划分区间长度小于10的时候,用插入排序对剩下的数进行排序

递归的算法主要是在划分子区间,如果要非递归实现快排,只要使用一个栈来保存区间就可以了。一般将递归程序改成非递归首先想到的就是使用栈,因为递归本身就是一个压栈的过程。

非递归的基本思想:1.申请一个栈,存放排序数组的起始位置和终点位置。2.将整个数组的起始位置和终点位置入栈。3.由于栈的特性是:后进先出,right后进栈,所以right先出栈。定义一个end接收栈顶元素,出栈操作、定义一个begin接收栈顶元素,出栈操作。4.对数组进行一次单趟排序,返回key关键值的下标。5.这时候需要排基准值key左边的序列。如果只将基准值key左边序列的起始位置和终点位置存入栈中,等左边排序完将找不到后边的区间。所以先将右边序列的起始位置和终点位置存入栈中,再将左边的起始位置和终点位置后存入栈中。6.判断栈是否为空,若不为空重复4、5步、若为空则排序完成。

voidQuickSortNonR(int*a,intleft,intright){Stackst;StackInit(&st);StackPush(&st,left);StackPush(&st,right);while(!StackEmpty(&st)){intend=StackTop(&st);StackPop(&st);intbegin=StackTop(&st);StackPop(&st);intkeyi=partion5(a,begin,end);//区间被成两部分了[begin,keyi-1]keyi[keyi+1,end]if(keyi+1begin){StackPush(&st,begin);StackPush(&st,keyi-1);}}StackDestroy(&st);}快速排序的总结:

归并排序的基本思想(分治思想):

从思想上来说和二叉树很相似,所以我们可以用递归的方法来实现归并排序

代码如下:

我们知道,递归实现的缺点就是会一直调用栈,而栈内存往往是很小的。所以,我们尝试着用循环的办法去实现

由于我们操纵的是数组的下标,所以我们需要借助数组,来帮我们存储上面递归得到的数组下标,和递归的区别就是,递归要将区间一直细分,要将左区间一直递归划分完了,再递归划分右区间,而借助数组的非递归是一次性就将数据处理完毕,并且每次都将下标拷贝回原数组

归并排序的基本思路是将待排序序列a[0…n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列;如此反复进行下去,最后得到一个长度为n的有序序列。

但是我们这是理想情况下(偶数个),还有特殊的边界控制,当数据个数不是偶数个时,我们所分的gap组,势必会有越界的地方

第一种情况:

第二种情况:

voidMergeSortNonR(int*a,intn){int*tmp=(int*)malloc(sizeof(int)*n);if(tmp==NULL){printf('mallocfail\n');exit(-1);}intgap=1;while(gap=n||begin2>=n){break;}//end2越界,需要归并,修正end2if(end2>=n){end2=n-1;}intindex=i;while(begin1<=end1&&begin2<=end2){if(a[begin1]

又叫非比较排序,又称为鸽巢原理,是对哈希直接定址法的变形应用

基本思想:

对于给定的任意数组a,我们需要开辟一个计数数组count,a[i]是几,就对count数组下标是几++

这里我们用到了绝对映射,即a[i]中的数组元素是几,我们就在count数组下标是几的位置++,但是对于数据比较聚集,不是从较小的数字开始,例如1001,1002,1003,1004这样的数据,我们就可以用到相对映射的方法,以免开辟数组空间的浪费,count数组的空间大小我们可以用a数组中最大值减去最小值+1来确定(即:range=max-min+1),我们可以得到count数组下标j=a[i]-min

count[j]中数据是几,说明该数出现了几次,是0就不用拷贝

计数排序总结:

稳定的排序有:直接插入排序、冒泡排序、归并排序

不稳定的排序有:希尔排序、选择排序、堆排序、快速排序、计数排序

THE END
1.这到底该如何排列怎么组合?看起来不难做起来难!但也有方法不会做的别直接跳过,好方法,降幂也能轻松算出答案 三乐大掌柜 23跟贴 初中数学:求x,y的值,这道题有点难度,许多人都做错了 三乐大掌柜 5跟贴 上交附中期末题:因式分解题,先观察再说 三乐大掌柜 10跟贴 初中期末考试,解方程,平方外再平方,别直接去括号 三乐大掌柜 13跟贴 a-2=√a,b2=4,求√abhttps://m.163.com/v/video/VAIJNG2GH.html
2.优选算法九大排序算法(插入排序,希尔排序,选择排序,堆排序,冒泡文章浏览阅读1.3w次,点赞53次,收藏354次。【优选算法】九大排序算法(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序,计数排序,基数排序)_排序算法https://blog.csdn.net/zty857016148/article/details/129149170
3.用最简单的方式帮你记住程序员都必须知道的排序算法1.5万 1 0:36 App 五种经典的机器学习算法 #计算机 #编程 #程序员 #大数据 2047 -- 0:18 App 阿里大神算法刷题笔记,看完秒杀大厂算法题 61 -- 0:26 App 前端小白必备入门小游戏 4.5万 3 0:12 App 95%的算法都是基于这6种算法思想 57 -- 0:16 App 错过后悔一辈子的程序员宝藏网站 1.9https://m.bilibili.com/video/BV1nT411978m/
4.十大经典排序算法动画演示AlgorithmMan,一套免费的算法演示神器,附带GitHub开源下载地址。 1、Sorting Algorithms Animations 2、算法的分类 3、时间复杂度 算法 1、冒泡排序 它重复地访问要排序的元素列,一次比较两个相邻的元素,如果他们的顺序不符合预期就把他们交换过来。访问元素的工作是重复地进行直到没有相邻元素需要交换时为止。 https://www.jianshu.com/p/e9cfc2cc869c
5.JavaScript排序算法动画演示效果的实现方法javascript技巧下面小编就为大家带来一篇JavaScript排序算法动画演示效果的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧所以让JavaScript排序慢来来还是没有实现。另一种让JavaScript暂停下来的思路:写这个文章的时候又想到一种方法来让JavaScript停下来。 那就是AJAX的同步请求,https://www.jb51.net/article/94968.htm
6.排序算法动画演示冒泡法教育视频小狐狸151613关注https://tv.sohu.com/v/dXMvMTUxNjEzLzE4NzIzNzI4OS5zaHRtbA==.html
7.十大经典排序算法动画,看我就够了!Tip为了演示更加清楚,本文中所有的动画都放慢了速度,因此GIF大小对比之前会有所增大,图片加载速度会变慢,如果你想获取所有的超清动画,在公主号 五分钟学算法 回复github可获得全部资料。 在前面的章节中详细的讲解分析了十大经典排序算法,本文将进行一个大总结同时分析它们的时间复杂度与稳定性。 https://www.imooc.com/article/266110
8.数据结构和算法Flash动画演示一些算法的 flash动画演示:B树的删除,B树的生长过程,三元组表的转置,中序线索化二叉树,串的顺序存储,二分查找,二叉排序树的删除,二叉排序树的生成,二叉树的建立,克鲁斯卡尔算法构造最小生成树,冒泡排序,分块查找,单链表结点的删除,单链表结点的插入,图的深度优先遍历,基数排序,堆排序,头插法建单链表,寻找中序线https://www.iteye.com/resource/ziqin1984-4949849
9.算法动画图解app下载算法动画图解中文版下载v1.4.0编程中我们需要学习各种算法,可是仅凭借想象和动手画图是非常难理解的。所以小编带来了算法动画图解app,这是一款非常专业和高效的编程算法学习应用,适合安卓手机和平板使用,它将难懂和抽象的算法转变成动画演示的形式,可以让用户轻松理解各种算法,从容应对编程中遇到的问题。同时软件提供了冒泡排序、插入排序、选择性排序、https://www.ddooo.com/softdown/159933.htm
10.吴师兄学算法的个人主页十大经典排序算法动画演示视频,看我就够了——堆排序 1207次观看2019年01月18日 00:23 十大经典排序算法动画演示视频,看我就够了——快速排序 862次观看2019年01月18日 00:21 十大经典排序算法动画演示视频,看我就够了——插入排序 734次观看2019年01月18日 https://m.ixigua.com/user/10500480991
11.动画图解一冒泡排序算法algviz假设算法从左向右扫描?,每次将相邻两个元素中较大的元素放到后面,那么经过该轮扫描之后,扫描过的序列中的最大值将会跑到扫描序列最右边的位置,重复执行扫描过程直到所有元素都被排序即可。 算法实现 下面是冒泡排序算法的代码运行过程演示: 算法特点 冒泡排序算法同样属于基于比较的排序算法,排序结果具有稳定性,但无https://leetcode.cn/circle/discuss/Ao6lpm/
12.GitHub最近在学习基础的排序算法,发现仅凭算法的定义公式,即使结合代码在IDE下debug查看数组变化,也依然不是很好的理解,于是就在网上搜索排序算法动画,果然已经有人实现了排序演示,有java实现的,有JS实现,但很想在android手机上看简单演示,最终找到了,ukhanoff/AndroidSortAnimation,一个国际友人,用android实现了基础的冒泡排https://github.com/54wall/SortAnimation
13.高中信息技术课程标准(2)经历用自然语言、流程图或伪代码等方法描述算法的过程。 (3)在使用计算机解决实际问题的过程中,通过观看演示、模仿、探究、实践等环节,了解顺序、选择、循环三种基本结构及其重要作用,掌握计算机程序的基本概念,能解释计算机程序执行的基本过程。 (4)了解程序设计语言、编辑程序、编译程序、连接程序以及程序开发环境等https://www.fqkhzx.cn/index/article/view/id/94.html
14.经典排序算法之冒泡排序(Bubblesort)代码static void Main(string args) int x = 6, 2, 4, 1, 5, 9 ; bubble_sort(x); foreach (var item in x) Console.WriteLine(item); Console.ReadLine(); 冒泡排序动画演示 以上所述是小编给大家介绍的经典排序算法之冒泡排序(Bubble sort)的代码,希望对大家有所帮助!https://www.xiuzhanwang.com/a1/C_jiaocheng/6471.html
15.SortingAlgorithmsAnimationsToptal?Animation, code, analysis, and discussion of 8 sorting algorithms on 4 initial conditions.http://www.sorting-algorithms.com/
16.漫画七种最常见的排序算法(动图版)腾讯云开发者社区动画演示 python代码实现如下: 三、插入排序 插入排序英文称为Insertion Sort,它通过构建有序序列,对于未排序的数据序列,在已排序序列中从后向前扫描,找到相应的位置并插入,类似打扑克牌时的码牌。插入排序有一种优化的算法,可以进行拆半插入。 基本思路是先将待排序序列的第一个元素看做一个有序序列,把第二个元https://cloud.tencent.com/developer/article/1505445