为了更好的理解Shell's Sort, 写一个代码将Shell's Sort的每一步打印出来,使用的例子是wiki上面的例子,
1. 创建一个包含12个位数的数组
int[] list = {62, 83, 18, 53, 07, 17, 95, 86, 47, 69, 25, 28};
2. 设定增量gap=5,进行第一次排序
3. 设定gap=3,进行第二次排序
4. 设定gap=1,进行第三次排序.
以上图片出自 https://en.wikipedia.org/wiki/Shellsort
其中第一次排序(After 5-sorting)的分步细节如下,可以知道第一次循环总共有7次比较 :
java代码如下
public class Shell{
public static void main(String[] args) {
Shell obj = new Shell();
int count = 1;
int gap=1; //增量
int[] list = {62, 83, 18, 53, 07, 17, 95, 86, 47, 69, 25, 28}; //原始数列
System.out.print("原始数列=");
obj.printList(list); //打印处理前的数组
while (count<=3) {
switch (count) {
case 1:
gap = 5;
break;
case 2:
gap = 3;
break;
case 3:
gap = 1;
break;
default: {
System.out.println("超过预设次数");
}
}
obj.shellSort(list, gap); //将list和gap值带入shellSort
System.out.println("*********************第" + count + "次数循环结束********************");
count++;
}
}
private void shellSort(int[] list, int gap) { //希尔排序
int[] subList = null; //创建子序列
for (int i = 0; i< list.length-gap; i++) {
int subLength = ((list.length-(i+1))/gap+1); //计算子序列的长度
subList=new int[subLength];
int countPos=0;
for (int j = i; j < list.length; j += gap) { //将本次需要排序的数字导入子序列
subList[countPos] = list[j];
countPos++;
if(countPos>subList.length)break;
}
straightInsertionSort(subList); //调用插入法排序子序列
int subListPos=0;
for(int listPos=i;listPos<list.length;listPos+=gap){ //将排序好的子序列的值放回原来的序列 list
list[listPos]=subList[subListPos];
subListPos++;
}
subList=null; //将子序列清空
System.out.print("第"+(i+1)+"小段排序后=");
printList(list);
}
}
private void straightInsertionSort(int[] list){ //直接插入法
for(int i =1;i<list.length;i++){
if(list[i]<list[i-1]){
int banchmark=list[i];
int target=0;
int j;
for (j=i-1;j>=0 && list[j]>banchmark ;j--){
list[j+1]=list[j];
target=j;
}
list[target]=banchmark;
}
}
}
private void printList(int[] list){ //打印数组
for(int i=0;i<list.length;i++){
System.out.print(list[i]+" ");
}
System.out.println();
}
}
最后运行的结果如下:
原始数列=62 83 18 53 7 17 95 86 47 69 25 28
第1小段排序后=17 83 18 53 7 25 95 86 47 69 62 28
第2小段排序后=17 28 18 53 7 25 83 86 47 69 62 95
第3小段排序后=17 28 18 53 7 25 83 86 47 69 62 95
第4小段排序后=17 28 18 47 7 25 83 86 53 69 62 95
第5小段排序后=17 28 18 47 7 25 83 86 53 69 62 95
第6小段排序后=17 28 18 47 7 25 83 86 53 69 62 95
第7小段排序后=17 28 18 47 7 25 83 86 53 69 62 95 // (After 5-sorting, 以增量为5排序后的结果)
*********************第1次数循环结束********************
第1小段排序后=17 28 18 47 7 25 69 86 53 83 62 95
第2小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第3小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第4小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第5小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第6小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第7小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第8小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第9小段排序后=17 7 18 47 28 25 69 62 53 83 86 95 // (After 3-sorting, 以增量为3排序后的结果)
*********************第2次数循环结束********************
第1小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第2小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第3小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第4小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第5小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第6小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第7小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第8小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第9小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第10小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第11小段排序后=7 17 18 25 28 47 53 62 69 83 86 95 //(After 1-sorting, 以增量为1排序后的结果)
*********************第3次数循环结束********************
第1小段排序后=17 83 18 53 7 25 95 86 47 69 62 28
第2小段排序后=17 28 18 53 7 25 83 86 47 69 62 95
第3小段排序后=17 28 18 53 7 25 83 86 47 69 62 95
第4小段排序后=17 28 18 47 7 25 83 86 53 69 62 95
第5小段排序后=17 28 18 47 7 25 83 86 53 69 62 95
第6小段排序后=17 28 18 47 7 25 83 86 53 69 62 95
第7小段排序后=17 28 18 47 7 25 83 86 53 69 62 95 // (After 5-sorting, 以增量为5排序后的结果)
*********************第1次数循环结束********************
第1小段排序后=17 28 18 47 7 25 69 86 53 83 62 95
第2小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第3小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第4小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第5小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第6小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第7小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第8小段排序后=17 7 18 47 28 25 69 62 53 83 86 95
第9小段排序后=17 7 18 47 28 25 69 62 53 83 86 95 // (After 3-sorting, 以增量为3排序后的结果)
*********************第2次数循环结束********************
第1小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第2小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第3小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第4小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第5小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第6小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第7小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第8小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第9小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第10小段排序后=7 17 18 25 28 47 53 62 69 83 86 95
第11小段排序后=7 17 18 25 28 47 53 62 69 83 86 95 //(After 1-sorting, 以增量为1排序后的结果)
*********************第3次数循环结束********************
以下是python的代码
list=[62, 83, 18, 53, 7, 17, 95, 86, 47, 69, 25, 28]
print('原始数列=',list)
def straightInsertSort(list):
for i in range (1,len(list)):
if list[i]<list[i-1]:
banchmark=list[i]
target=0
for j in range(i-1,-1,-1):
if list[j]>banchmark:
list[j+1]=list[j]
target=j
list[target]=banchmark
def shellSort(list,gap):
subList=[]
for i in range(0,len(list)-gap):
subList.clear()
for j in range(i,len(list),gap):
subList.append(list[j])
straightInsertSort(subList)
subPos=0
for j in range(i,len(list),gap):
list[j]=subList[subPos]
subPos+=1
print("第",i+1,"小段排序后")
print(list)
count=1
while(count<=3):
if count ==1:
gap=5
elif count ==2:
gap=3
elif count ==3:
gap=1
else:
print("超过次数")
shellSort(list,gap)
print("*********************第",count,"次数循环结束********************")
count+=1