用java 和 python将希尔排序Shell's Sort 的每一步打印出来(每次的增量没有固定规则)

来源:互联网 发布:java 线程调用service 编辑:程序博客网 时间:2024/06/11 05:32

为了更好的理解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次数循环结束********************

以下是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]=banchmarkdef 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=1while(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