经典算法(三)----插入排序----图解法让你快速入门
引言
只要设计到数据,就会涉及到数据的排序问题,比如给你随机给你五个整数 3,1,5,2,4 。让你从小到大进行排序,那我们该怎样才是实现对这些整数的排序呢 ?
答案是多种多样的,比如用插入排序、选择排序、堆排序、归并排序、快速排序等等,这些排序方法都可以实现对整数排序,而这篇文章要讲的就是插入排序
本文将从以下几个问题对插入排序进行分析和讲解:
- 什么是插入排序?
- 插入排序的大概过程是什么?
- 怎样用代码实现插入排序?
- 插入排序的代码详解。
什么是插入排序?
下面看百度百科对插入排序的定义:插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动 。
简单来说:就是在想有序的数组中插入一个值,并且插入之后的数组仍然是有效的,进行一次次的插入,知道最后排好序。
下面看一个动图:
插入排序的大概过程是什么?
下面拿一个例子说明选择排序的大概过程。
插入排序的基本思想就是:往有序的序列中一次次插入值,直到排序完成
下面来说用插入排序对3,1,5,2,4进行排序(从小到大排序)
- 首先选定第一个数3为有序序列,拿着第二个数1往前面那个有序序列中插入值,插入的方法是用要插入的1依次和有序序列的值比较(从有序序列的后面依次往前比较),知道发现一个数比这个要插入的1小或者要插入的数走到了有序序列的头部为止。
- 经比较发现发现1<3,那就把有序序列的3后移一个位置(注意不是1和3这俩数)。这时候走到了头,那就把数字1放到头部。这时候数组元素为1,3,5,2,4
- 继续拿着5去有序序列中比较,发现5>3,那就不用继续比较了,因为3前面的数肯定比3小。 这时候数组元素为1,3,5,2,4
- 继续拿着2去和有序序列比较,首先发现2<5,那就把5后移一个位置(注意是后移)。再用2和3比较,发现2<3,那就把3后移一个位置,继续用2和1比较,发现1<2。那就找到了放2的位置,把2在1后面就可以了。 只是后数组元素为1,2,3,5,4
- 按照上面的方法,用4去一一比较即可,最后得到的结果就是1,2,3,4,5
总结:假设有n个数需要排序,我们可以默认第一数是有序的,那就只需n-1轮就可以排序完成。每轮就是拿着元素去有序序列从后往前比较,这可以写一个while循环实现,循环结束的条件就是比较到头了或者找了比这个数要小的数,
扩展:这个扩展对后面理解希尔排序特别有用, 如果暂时不理解这个扩展的也没事。
- 就上我们上面第3步结束后,数组元素为1,3,5,2,4,前三个元素为有序序列,后两个还未比较,这时候我们需要拿着2去比较,等比较结束,发现3和5都后移了一个位置,所以一共后移了两个位置。
- 再看我们上面的的第4步结束后,数组 元素为1,2,3,5,4。这时候还剩一个元素4没有排序,排序后,发现5后移了一个位置,所以一共后移了一次。
- 一个是后移了两次,一个是后移了一次,那么时间复杂度肯定是不同的,后移一次的肯定更省时一些,而且后移的次数时候数组元素的 “ 相对有序 ” 有关。
- 相对有序的意思就是相对来说小元素在前面,大元素在后面,只要有这个意识就可以了,其他的就不再多赘述了。至于怎样利用这个相对有序来减少排序的时间,就是后面希尔排序的事情了。
怎样用代码实现插入排序?
通过上面对3,1,5,2,4的排序过程讲解,我们需要明确已知的三个条件
- 我们要排序的数组有哪些数?数组长度为多少?
- 我们要进行几轮插入操作?
- 每轮插入,哪些元素需要后移?
搞清楚了上面三个条件,我们下面我们动图数据排序的实现代码:
#include<iostream> using namespace std; //插入排序函数 稳定 void InsertionSort(int arr[],int len) { int temp; for(int i=1;i<len;i++) { int index=i-1;//前i-1个数已经排序好了 int current=arr[i]; while(index>=0&&arr[index]>current) { arr[index+1]=arr[index]; index--; } arr[index+1]=current; } } //输出数组的值 void printf(int arr[],int len) { for(int i=0;i<len;i++) cout<<arr[i]<<" "; cout<<endl; } int main() { //要排序的数组 int arr[]={3, 44,38, 5,47,15,36,26,27,2 ,46,4 ,19,50,48}; int len=15;//要排序的数组长度 //排序 InsertionSort(arr,len); //输出 printf(arr,len); return 0; }
运行结果:
插入排序的代码详解
- 上面代码写了两个函数,一个是printf函数,这个是输出排序后的数组。
- 另一个函数就InsertionSort函数,在这个函数里面有一个二重循环,外层循环的的次数就是要查找的次数,内层循环的次数的就是要比较的次数,刚好对应上面说的(这里数组下标是从0开始的)。如果对上面代码有疑问,自己可以按照前面的过程,模拟一边对3,1,4,5,2的排序过程,就知道代码是怎样执行的了 。
本文参考以及引用:
上一篇: springmvc实现简单的拦截器
下一篇: JavaWeb_MVC架构_:)