目录
插入排序(原始版)、插入排序(二分查找版)、插入排序(多元素插入优化版)
1、插入排序概述
一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动 。
基本思想:
每一步将一个待排序的数据插入到前面已经排好序的有序序列中,直到插完所有元素为止。
时间复杂度:
最坏情况下为O(N*N),此时待排序列为逆序,
最好情况下为O(N),此时待排序列为升序
空间复杂度:O(1)
2、插入排序分类
插入排序(原始版)、插入排序(二分查找版)、插入排序(多元素插入优化版)
3、代码展示及运行结果
public static void main(String[] args) {
long starttime1=System.nanoTime();
System.out.println("插入排序原始版");
int[] nums=new int[]{4,4,6,77,33,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43};
sort(nums);//7456200ns
long endtime1=System.nanoTime();//200ns
System.out.println("程序运行时间:"+(endtime1-starttime1)+"ns");
long starttime=System.nanoTime();
System.out.println("插入排序二分查找版");
int[] nums1=new int[]{4,4,6,77,33,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43};
sort1(nums1);//6954100ns
long endtime=System.nanoTime();//200ns
System.out.println("程序运行时间:"+(endtime-starttime)+"ns");
/*System.out.println("插入排序多元素插入版");
int[] nums2=new int[]{4,4,6,77,33,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43};
sort2(nums2);//6954100ns*/
}
插入排序(原始版)
代码:
public static void sort(int[] num){
if(num.length<2)return;
int index;//标志即将插入元素
int count=0;
for (int i = 1; i <num.length ; i++) {//开始逐个插入
index=num[i];//给index赋值操作
int j;
for ( j=i-1; j >=0; j--) {//在有序序列中倒序查找比较
count++;
if(num[j]<=index)break;//查找到index插入位置
num[j+1]=num[j];//后移空出新的位置
}
num[j+1]=index;//插入index
for (int m = 0; m < num.length; m++) {
System.out.print(num[m]+",");
}
System.out.println();
}
System.out.println("循环次数:"+count);
}
运行结果:
插入排序原始版
4,4,6,77,33,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,77,33,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,77,33,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,33,77,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,33,45,77,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,33,45,55,77,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,33,45,55,77,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,30,33,45,55,77,90,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,30,33,45,55,67,77,90,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
3,4,4,6,30,33,45,55,67,77,90,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
1,3,4,4,6,30,33,45,55,67,77,90,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,4,4,6,30,33,45,55,67,77,90,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,6,30,33,45,55,67,77,90,4,5,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,6,30,33,45,55,67,77,90,5,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,30,33,45,55,67,77,90,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,77,90,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,68,77,90,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,68,77,90,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,68,77,90,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,68,76,77,90,98,99,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,65,67,68,76,77,90,98,99,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,65,66,67,68,76,77,90,98,99,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,33,45,55,65,66,67,68,76,77,90,98,99,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,33,43,45,55,65,66,67,68,76,77,90,98,99,32,43,
1,2,3,3,4,4,4,5,6,6,30,32,33,33,43,45,55,65,66,67,68,76,77,90,98,99,43,
1,2,3,3,4,4,4,5,6,6,30,32,33,33,43,43,45,55,65,66,67,68,76,77,90,98,99,
循环次数:166
程序运行时间:6775400ns
插入排序(二分查找版)
代码:
public static void sort1(int[] num){
if(num.length<2)return;
int index;//标志即将插入元素
int count=0;
for (int i = 1; i <num.length ; i++) {//开始逐个插入
index=num[i];//给index赋值操作
int j=i-1;
int left=0;
int right=i-1;
int middle=(left+right)/2;
//最大值直接插入最后
if(index>=num[right]&&left!=right){num[j+1]=index;}
//最小值直接插入最前
if(index<=num[left]){
for ( j=i-1; j >=0; j--) {
count++;
num[j+1]=num[j];
}
num[0]=index;
}
//中间值采用二分查找
if(num[left]<index&&index<num[right]){
while (left<right) {
if (index < num[middle]) {
right = middle;
middle = (left + right) / 2;
}
if (index >= num[middle]) {
left = middle;
middle = (left + right) / 2;
}
if (left == middle) {
for (j = i - 1; j >= right; j--) {
count++;
num[j + 1] = num[j];
}
num[right] = index;
break;
}
}
}
//遍历打印
for (int m = 0; m < num.length; m++) {
System.out.print(num[m]+",");
}
System.out.println();
}
System.out.println("循环次数:"+count);
}
运行结果:
插入排序二分查找版
4,4,6,77,33,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,77,33,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,77,33,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,33,77,45,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,33,45,77,55,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,33,45,55,77,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,33,45,55,77,90,30,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,30,33,45,55,77,90,67,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
4,4,6,30,33,45,55,67,77,90,3,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
3,4,4,6,30,33,45,55,67,77,90,1,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
1,3,4,4,6,30,33,45,55,67,77,90,2,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,4,4,6,30,33,45,55,67,77,90,3,4,5,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,6,30,33,45,55,67,77,90,4,5,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,6,30,33,45,55,67,77,90,5,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,30,33,45,55,67,77,90,6,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,77,90,68,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,68,77,90,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,68,77,90,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,68,77,90,98,99,76,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,67,68,76,77,90,98,99,65,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,65,67,68,76,77,90,98,99,66,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,45,55,65,66,67,68,76,77,90,98,99,33,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,33,45,55,65,66,67,68,76,77,90,98,99,43,32,43,
1,2,3,3,4,4,4,5,6,6,30,33,33,43,45,55,65,66,67,68,76,77,90,98,99,32,43,
1,2,3,3,4,4,4,5,6,6,30,32,33,33,43,45,55,65,66,67,68,76,77,90,98,99,43,
1,2,3,3,4,4,4,5,6,6,30,32,33,33,43,43,45,55,65,66,67,68,76,77,90,98,99,
循环次数:143
程序运行时间:3456700ns
插入排序(多元素插入优化版)
代码调试未完成,半成品如下:
代码:
public static void sort2(int[] num){
if(num.length<2)return;
int[] index=new int[3];//标志即将插入元素
int count=0;
for (int i = 1; i <num.length-2 ; i+=3) {//开始逐个插入
//给index赋值操作
int max,min;
max= Math.max(num[i], num[i + 1]);
max= Math.max(max, num[i + 2]);
min=num[i]<num[i+1]?num[i]:num[i+1];
min=min<num[i+2]?min:num[i+2];
index[0]=min;
index[1]=num[i]+num[i+1]+num[i+2]-max-min;
index[2]=max;
int j;
for ( j=i-1; j >=0; j--) {//在有序序列中倒序查找比较
count++;
if(num[j]<=index[2]){//插入index
num[j+3]=index[2];
num[j+2]=index[1];
num[j+1]=index[0];
for (int k = j; k >=0; k--) {
if(num[k]<=index[1]){
num[k+2]=index[1];
num[k+1]=index[0];
for (int l = k; l >=0 ; l--) {
if(num[l]<=index[0]){
num[l+1]=index[0];
}
num[l+1]=num[l];
}
}
num[k+2]=num[k];
}
}//查找到index插入位置
num[j+3]=num[j];//后移空出新的位置
}
for (int m = 0; m < num.length; m++) {
System.out.print(num[m]+",");
}
System.out.println();
}
System.out.println("循环次数:"+count);
}
有时间必定补全。