一个喜欢插队的算法:直接插入排序(Java实现)

Posted procedurebear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个喜欢插队的算法:直接插入排序(Java实现)相关的知识,希望对你有一定的参考价值。

一、排序思路

将原有的数组看为两块,一块是已经排好序的(我们叫有序区),一块是待排序的(我们叫无序区),不断地从无序区中取出其第一个元素,搜寻该元素应该放在有序区的哪个位置,并将该元素放入该位置,完成这个步骤后,有序区长度+1,无序区长度-1,直至无序区长度为0,即无序区中不再有元素,排序就完成啦。

二、有序区和无序区的选取

把输入的数组的第一个元素定义为有序区(只有一个元素,怎么放都有序),其余的元素都定义在无序区中。

三、搜寻合适位置

不难发现,排好序的数组除头尾之外,某个元素的后一个元素一定大于或者等于该元素,该元素的前一个元素一定小于等于该元素。从这个想法中可以提炼出来搜寻合适位置存放插入元素的方法,我们可以从有序区的最后一个元素,即已排序的最大元素,开始与插入元素比较,若插入元素比该元素小,那么插入元素的插入位置一定在最后一个元素之前,紧接着再将插入元素与有序区的倒数第二个元素比较,若插入元素比倒数第二个元素小,那么插入元素插入的位置将在倒数第二个元素之前......依次类推,当插入元素比与之比较的元素小的时候,停止比较,插入元素的位置则在此元素之后。

四、插入元素

找到合适的位置之后,我们将有序区内该位置及该位置之后的元素都往右移一位,这样就将该位置空出来了,再将插入元素插入其中。

五、图形说明

文字表述较为抽象,我们用图形来说明一下直接插入排序的过程,下面将对数组{8,3,2,7,4,5}进行排序:

首先确定有序区和无序区,由于一个元素无论如何排放都可以看做有序的,那么我们将第一个元素作为有序区,其余的作为无序区

技术分享图片

接着,我们开始进行插入操作,每次插入都是选用无序区的第一个元素,如上图,确定好有序区和无序区后,即可确定即将插入的元素,即是原有数组的第二个元素,现将插入元素放入有序区,再搜寻合适位置

            技术分享图片

技术分享图片

可以发现插入的元素“3”比有序区中最后一个元素“8”小,故元素“3”放在元素“8”之前,比较结束之后,元素“3”之前再无元素,可以看做元素“3”之前的元素比其小,结束比较,将元素“8”往右移一位,并将元素“3”插入搜寻到的位置,第一轮插入结束,是不是感觉很简单?我们继续往下看

再取出无序区中第一个元素“2”,将其放去有序区中与有序区的各个元素进行比较,下图中线的左边代表有序区,右边代表无序区,由于上图中给出了,以下的图就不明确说明啦!!

 技术分享图片

这里值得注意的是,插入排序中插入元素搜寻合适位置并不是遇到一个比插入元素小的元素就进行交换,而是记录该位置,并在接下来的比较中更新记录

技术分享图片

 

 显而易见,元素“2”比元素“8”小,所以插入位置会暂时停留在元素“3”与元素"8"之间,并记录下来,元素“2”再往下继续比较,元素“2”比元素“3”小,且元素“3”之前不再有元素,所以元素“2”插入位置最终定在元素“3”之前,将元素“3”和元素“8”都往右移一位,将元素“2”插入搜寻到的位置,第二轮插入结束。

技术分享图片

接下来的几步插入类似就不一一列出来了,下面让我们一起来看看Java代码是如何实现的。

六、代码实现

 1 /**
 2      * 直接插入排序的方法
 3      * @param a 需要排序的数组
 4      */
 5     public void insertSort(int[] a) {
 6         //遍历除了第一个元素外的所有元素,即将初始无序区内的元素一一插入有序区
 7         for (int i = 1; i < a.length; i++) {
 8             //存放插入元素
 9             int temp = a[i];
10             //定义j变量,并初始化,j变量用于插入位置的定位
11             int j = 0;
12             //搜寻插入位置
13             for (j = i - 1; j >= 0; j--) {
14                 //从有序区最后一个元素开始比较,若比较的元素比插入的元素大则比较的元素往右移一位
15                 if (temp < a[j]) {
16                     a[j + 1] = a[j];
17                 }
18                 //若比较的元素比插入元素小,结束比较
19                 if(temp > a[j]) {
20                     break;
21                 }
22             }
23             //将插入元素插入到搜寻到的合适位置
24             a[j + 1] = temp;
25             //查看每一步插入的情况
26             System.out.println(Arrays.toString(a));
27         }
28     }

对数组{8, 3, 2, 7, 4, 5}进行排序,每一步插入的过程如下:

技术分享图片

最后一行即排完序的最终结果。

 

本文为原创,转载请注明!

以上是关于一个喜欢插队的算法:直接插入排序(Java实现)的主要内容,如果未能解决你的问题,请参考以下文章

Java算法 直接插入排序 -- 直接插入排序算法的非递归和递归形式实现

排序系列 之 直接插入排序算法 —— Java实现

排序系列 之 折半插入排序算法 —— Java实现

排序算法之插入排序Java实现

排序算法--Java实现直接插入排序

排序算法--Java实现直接插入排序