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

为了更好的理解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]=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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值