一、排序原理
- 把所有的元素分为两组,已经排序的和末排序的;
- 找到未排序的组中的第一个元素,向已经排序的组中进行插入;
- 倒叙遍历已经排序的元索,依次和待插入的元索进行比较,直到找到一个元索小于等于待插入元索,那么就把待插入元素放到这个位置,其他的元索向后移动一位;
二、API设计
三、代码实现
【Insertion .java】
package cn.Da_xiong.algorithm.Demo4.sort;
//插入排序
public class Insertion {
//第一个函数:对数组a中的元素进行排序
public static void sort(Comparable[] a){
//第一个索引处元素默认排好了,从第二个开始比较,插入;因此i从1开始,一直比到数组索引最大处即a.length-1处.
for(int i=1;i<a.length;i++){
//从i处往前遍历,所以j=i;与前面每一个元素比较,直到前面元素小于当前元素
//这里不能写成j>=0,若j=0,0索引处前面就没有数了,会报错,出现数组索引越界异常
for(int j=i;j>0;j--){
//比较所以j处的值和索引j-1处的值,如果索引j-1处的值比索引j处的值大,则交换;
// 若j-1处的值不大于j处的值,则已经找到合适的位置了,退出循环!
if(greater(a[j-1],a[j])){
exch(a,j-1,j);
}else{
break;
}
}
}
}
//第二个函数:比较元素v是否大于w
private static boolean greater(Comparable v,Comparable w){
return v.compareTo(w)>0;
}
//第三个元素:数组元素i与j交换位置
private static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
【InsertionTest .java】
package cn.Da_xiong.algorithm.Demo4.test;
//插入排序
import cn.Da_xiong.algorithm.Demo4.sort.Insertion;
import java.util.Arrays;
public class InsertionTest {
public static void main(String[] args) {
Integer[] a = {4,3,2,10,12,1,5,6};
Insertion.sort(a);
System.out.println(Arrays.toString(a));
}
}
【运行结果】
四、时间复杂度分析
插入排序使用了双层for循环,内层循环的循环体是真正完成排序的代码,我们主要分析内层循环体的执行次数。
最坏情况:
待排序的数组元索为{12,10,6,5,4,3,2,1}
最坏情况下每一次比较都需要交换元素,也就是比较次数与交换次数相等
第一次从第二个开始比,往前比一次;
第二次从第三个开始比,往前比两次
一直比到最后一个,每次循环比较次数为元素个数-1,即n-1
元素比较总次数为:
1+2+3+...+(n-2)+(n-1) = ((N-1)+1)*(N-1)/2=N^2/2-N/2
元素交换总次数 为:
((N-1)+1)*(N-1)/2=N^2/2-N/2
(= 元素比较总次数)
算法总执行次数为=元素比较总次数+元素总执行次数
=(N^2 -N) /2+(N^2 -N) /2
=N^2-N
根据大0推导法则,插入排序的时间复杂度为0(N^2)
ps:插入排序与冒泡排序、选择排序复杂度其实是一样的
喜欢的话记得点赞收藏哟😊
数据结构与算法—博文专栏持续更新!