2-路插入排序——基于折半插入排序

2019-08-08
基本思想.PNG

具体做法.PNG

排序过程.PNG

排序过程2.png

CODE.PNG

代码
/**
 * @Date: 2019/8/8 08:22
 * @Description: 2-路插入排序
 * 需要注意first指针和end指针移动时的数组越界问题
 */
public class Path2InsertionSort {
    public void path2InsertionSort(int[] arr) {
        int length = arr.length;

        int[] d = new int[length];//和arr同类型的临时数组
        d[0] = arr[0];//将arr中第一个记录作为d中已经排好序的记录

        int first = 0;//first指向数组d中排好序的记录中的第一个记录的位置
        int end = 0;//end指向数组d中排好序的记录中的最后一个记录的位置

        //依次将arr中的第二个至最后一个记录插入到d中的合适位置
        for (int i = 1; i < length; ++i) {
            //待插入记录小于d中的最小值,插入到first之前(不需要移动d数组)
            if (arr[i] < d[first]) {
                first = (first - 1 + length) % length;//first指针向前移动一位(移动至最后一位)
                d[first] = arr[i];
            }
            //待插入记录大于d中的最小值,插入到d[end]之后
            else if (arr[i] > d[end]) {
                d[++end] = arr[i];
            }
            //待插入记录大于d中最小值,小于d中最大值,插入到d的中间(需要移动d数组)
            else {
                int j = end++;//移动d尾部元素以便插入记录至合适位置。
                while (arr[i] < d[j]) {
                    //对于数组[7, 9, 3, 2, 5, 8, 6]来说,
                    //在插入5时,j指针会发生越界,所以需防止j指针越界异常
                    //即要插入的记录小于d中end指针指向的元素且插入位置在d中的第一个位置
                    //或插入位置在first指针之后的位置,如当前序列为[7, 9     2, 6]时,要插入记录5
                    d[(j + 1) % length] = d[j];//d中尾部元素后移
                    j = (j - 1 + length) % length;//d中尾部j指针前移
                }

                d[(j + 1) % length] = arr[i];
            }

        }

        //循环把d赋值给arr后输出
        for (int i = 0; i < length; i++)
            arr[i] = d[(i + first) % length];

        System.out.println(Arrays.toString(arr));
    }


    @Test
    public void testPath2InsertionSort() {
        int[] a = {35, 11, 24, 52, 77, 69, 8, 3, 6, 62};
        int[] b = {7, 9, 3, 2, 5, 8, 6};
        path2InsertionSort(a);
        path2InsertionSort(b);
    }
}
/*
Output:
[3, 6, 8, 11, 24, 35, 52, 62, 69, 77]
[2, 3, 5, 6, 7, 8, 9]
 */

总结.PNG

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值