插入排序三种:
直接插入的原理:
把某一数值(arr[i])插入到已经排列好的数据中去,将目标值 arr[i] 与顺序组进行比较,从最后一个比较,如果大于则让其后移,继续比较下去;然后此时的i位置=目标值;
中间插入原理:
直接定位到准确的点,将目标值与lo 和h比较(lo<=h);
从准确位置开始到i全部往后移动;
中间排序不再是一步步的比较,而是先快速找到位置,通过lo hi ,mind找到之后,在往后移动
希尔排序 :
与前两者差别较大,但核心原理还是一样的,希尔通过一个宽度变量把所有的数据分割成一列列的小数据,然后在进行直接排序,不断的缩小这个宽度变量。
其最主要的效果就是:对于原本顺序特别乱的数据,能够快速形成基本顺序,就像8,1,4,7,5,3,9,2,6
快速变成5,1,4,3,2,6,8,9,7.可以让大的基本上都靠后,小的基本上都靠前;
最后当宽度变量是1的时候,就是对整体数组直接排序,因为直接排序对于顺序不乱的是有优势的,交换的次数少一些相对来说。
这个https://www.cnblogs.com/youzhibing/p/4889037.html,讲的比较透彻;
一句话就是,吧整体分成多个小数组进行直接排序,通过的是一个h变量来决定的,并且h是不断缩小的,h初始值最好是h=arr.lengh/3;经过实践这个时比较不错的取值。
适用: 希尔排序适用于乱的数据,比较多的数据;
/**
* Copyright (C), 2015-2019, XXX有限公司
* FileName: zhijie
* Author: Administrator
* Date: 2019/6/10 0010 上午 11:15
* Description: 直接插入
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
package algo.charu;
public class zhijie {
public static void main(String[] args) {
int[] arr={5,3,7,9,1,6,4,8,2};
System.out.println("初始化: ");
for (int i = 0; i < arr.length; i++) {
int i1 = arr[i];
System.out.print(" " + i1);
}
insertMindSort(arr);
}
/**
* 直接插入
* @param arr
*/
public static void merge(int[] arr){
int temp=0; // 交换用
for (int i = 1; i < arr.length; i++) {
temp=arr[i];
while(i>0 && temp < arr[i-1]){ // 把大于temp的全部往后移动
arr[i] =arr[i-1];
i--;
}
arr[i] =temp;//将temp插入到合适的地方
System.out.println(" ");
for (int x = 0; x < arr.length; x++) {
int i1 = arr[x];
System.out.print(" "+i1);
}
}
}
/**
* @version:1.0.1
* @name 插入排序3_折半插入
* @Description: 先找到确定位置 然后在移动
* @author: whx
* @time:2019年5月16日 下午5:19:55
*/
public static void insertMindSort(int[] arr) {
int temp = 0; //
int hi = arr.length; //右侧
int low = 0; //左侧
int mind = 0; //中间
for (int i = 1; i < arr.length; i++) {
hi = i - 1;
low = 0;
// 确定准确位置
while (low <= hi) {
mind = (low + hi) / 2;
if (arr[mind] > arr[i]) {
hi = mind - 1;
} else
low = mind + 1;
}
temp = arr[i];
// 往后挪一位
for (int j = i; j > hi + 1; j--) {
arr[j] = arr[j - 1];
}
arr[hi + 1] = temp;
System.out.println(" ");
for (int x : arr) {
System.out.print(" " + x);
}
}
}
/**
* 希尔排序
*/
public static void mergeXier(int[]arr){
int temp=0; //暂存值
int h =arr.length/3;
while(h >=1){
for (int i = 0; i < arr.length-h; i++) {
//直接排序
while (i >= 0 && arr[i] > arr[i + h]) {
temp = arr[i];
arr[i] = arr[i+h];
arr[i+h] = temp;
i = i - h;
}
}
System.out.println(" ");
for (int i = 0; i < arr.length; i++) {
int i1 = arr[i];
System.out.print(" " + i1);
}
h--;
}
}
}