直接插入排序与缩小增量插入排序(希尔排序ShellSort)
- 直接插入排序
要理解shell排序,首先要把直接插入排序的基础打扎实。
学习资料:白话经典算法系列之二 直接插入排序的三种实现、直接插入排序
根据我的思路,直接插入排序设置3重循环。
循环1:对 i=【无序序列】∈[ 1 , length ) 进行遍历。
循环2:对 j=【有序序列】∈[ 0 , i ) 进行遍历。
比较:nums [ i ] < nums [ j ] (发现有序序列中有元素不符合降序原则、即无序序列中有元素比有序序列还要小)
循环3:将 index= i 的元素插入到 j 的位置,[ j , i ) 的元素依次向后移动。
java代码:
1 class InsertSort{ 2 int [] sortAns; 3 InsertSort(int[] nums){ 4 int len=nums.length; 5 int i,j,k; 6 for(i=1;i<len;i++){//i代表已排序元素的个数,在【无序序列】中遍历 7 //在【 i , len 】的范围内,将无序元素插入到有序序列中 8 for(j=0;j<i;j++){//对【有序序列】进行遍历 9 if(nums[j]>nums[i]){//如果【有序序列】中的元素大于【无序序列】首元素 10 int tmp=nums[i];//临时保存【无序】 11 for(k=i;k>j;k--){//右移 12 nums[k]=nums[k-1]; 13 } 14 nums[j]=tmp; 15 } 16 } 17 } 18 sortAns=nums; 19 } 20 public String toString(){ 21 int i; 22 String str=new String(""); 23 for(i=0;i<sortAns.length;i++) str+=String.valueOf(sortAns[i])+" "; 24 str+="\n"; 25 return str; 26 } 27 }
- Shell排序
shell排序使用了缩小增量的思想,具体原理不再赘述。引用学习链接:
算法篇---Shell排序(希尔)算法、八大排序算法-shell 排序
不同的资料上有不同的实现方法。但具体思想是一致的。根据我的理解,我设计了5重循环:
循环1:用i表示增量,循环递减。(为保证最后一次循环的增量为1,应增设控制语句)
循环2:用j表示首元素的位置。j∈[0,length-i)
循环3:用k表示【无序序列】中各元素的下标。
循环4:用m表示【有序序列】中各元素的下标。
循环5:用n表示循环右移中的下标。
Java代码:
1 class ShellSort{ 2 int [] sortAns; 3 ShellSort(int[] nums){ 4 int len=nums.length; 5 int i,j,k,m,n; 6 boolean ok=false; 7 for(i=len/2;i>=-1;i-=2){//第一层循环:增量递减 8 if(i<=0){i=1;ok=true;} 9 for(j=0;j+i<len;j++){//第二层循环:首元素步增 10 for(k=j+i;k<len;k+=i){//第三层循环:首元素加增量。对k【无序序列】进行遍历 11 for(m=j;m<k;m+=i){//第四层循环,对m【有序序列】进行遍历 12 if(nums[m]>nums[k]){//如果【有序】>【无序】(破坏了DESC规则) 13 int tmp=nums[k];//将【无序】插入到【有序】位置。保存临时变量【有序】 14 for(n=k;n>m;n-=i){ 15 nums[n]=nums[n-i];//循环右移 16 } 17 nums[m]=tmp; 18 } 19 } 20 } 21 } 22 if(ok) break; 23 } 24 sortAns=nums; 25 } 26 public String toString(){ 27 int i; 28 String str=new String(""); 29 for(i=0;i<sortAns.length;i++) str+=String.valueOf(sortAns[i])+" "; 30 str+="\n"; 31 return str; 32 } 33 }