2.1直接插入
原理:
2.1.1 直接插入排序
思路:由第二个元素开始,从前向后遍历,如若当前元素比前一个元素小,则将
当前元素设为哨兵元素,保存当前元素,从当前位置向前扫描,寻找哨兵元素应该插入的位置,
前面的元素依次后移,找到直接插入。然后继续上述过程
2.1.2
折半查找
原理:
对有序数列进行查找,分成两块,去掉待查找数字不存在的另一块,直到待查找数字等于中间数字。
主方法:
public static void main(String[] args) {
int[] array=new int[]{1,2,32,45,78,96,32,54,55};
insert(array);//插入排序
int num=search(array,32,0,8);//折半查找
System.out.println();
System.out.println("num的下标为:"+num);
}
直接插入排序方法代码:
//进行直接插入排序
public static void insert(int[] array){
// 进行length-1次循环
for (int i = 0; i < array.length-1; i++) {
// 从待排序数据前一位向前比较
int pos=i;
// 待排序数据
int temp=array[i+1];
for(;pos>=0&&array[pos]>temp;pos--){
//满足条件进行移位操作(由于array已经存到temp里,所以不存在覆盖问题)
array[pos+1]=array[pos];
}
//这里for循环结束会有一个pos--操作使 pos=-1,要先执行++pos使之成为0;
array[++pos]=temp;
}
for (int i:array) {
System.out.print(i+" ");
}
}
折半查询方法代码:
/**
* 在已经排序的数组中查询num的位置
* @param array 已经排序的数组
* @param num 待查询的数据
* @return 查询数据在数组所在的索引,如果查询的数据不存在,返回-1
* @left 数组的左边界
* @right 数组的右边界
*/
public static int search(int[] array,int num,int left,int right){
if(left>right)return -1;
//求出数组中间下标
int mid=(left+right)/2;
//中间下标下的数据和你要查的数据相同
if(array[mid]==num)return mid;
//进一步缩小查询的范围(缩小一半)
if(array[mid]>num){
return search(array,num,left,mid-1);
}else{
return search(array,num,mid+1,right);
}
}
运行结果:
1 2 32 32 45 54 55 78 96
num的下标为:2
Process finished with exit code 0
2.2 希尔排序
原理:
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
简单插入排序很循规蹈矩,不管数组分布是怎么样的,依然一步一步的对元素进行比较,移动,插入,比如[5,4,3,2,1,0]这种倒序序列,数组末端的0要回到首位置很是费劲,比较和移动元素均需n-1次。而希尔排序在数组中采用跳跃式分组的策略,通过某个增量将数组元素划分为若干组,然后分组进行插入排序,随后逐步缩小增量,继续按组进行插入排序操作,直至增量为1。希尔排序通过这种策略使得整个数组在初始阶段达到从宏观上看基本有序,小的基本在前,大的基本在后。然后缩小增量,到增量为1时,其实多数情况下只需微调即可,不会涉及过多的数据移动。
希尔排序代码:
public static void main(String []args){
int []arr ={1,4,2,7,9,8,3,6};
sort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 希尔排序 针对有序序列在插入时采用移动法。
* @param arr
*/
public static void sort1(int []arr){
//增量gap,并逐步缩小增量
for(int gap=arr.length/2;gap>0;gap/=2){
//从第gap个元素,逐个对其所在组进行直接插入排序操作
for(int i=gap;i<arr.length;i++){
int j = i;
int temp = arr[j];
//每隔一个gap是一个组
if(arr[j]<arr[j-gap]){
while(j-gap>=0 && temp<arr[j-gap]){
//移动法
arr[j] = arr[j-gap];
j-=gap;
}
arr[j] = temp;
}
}
}
}