折半插入排序和2-路插入排序

折半插入排序在直接插入排序的基础上,运用折半查找的思想来寻找待插入数据在已排序列中合适的位置,可以减少比较次数。

public class Insert2 {
    public static void main(String[] args) {
        int[] m = {3, 1, 5, -2, 9, 7, 4};
        int t = 0;          // 监视哨
        int low = 0;        // 低位
        int height = 0;     // 高位
        int i = 1;
        // 折半查找思想比较数据
        for (; i < m.length; i++) {
            t = m[i];
            low = 0;
            height = i - 1;
            while (low <= height) {
                int mid = (low + height) / 2;
                if (t >= m[mid])
                    low = mid + 1;
                else
                    height = mid - 1;
            }
            // 将找到位置后的元素后移
            int j = i - 1;
            // 最后mid == height、所以控制用height更好
            for (; j >= height + 1; j--) {
                m[j + 1] = m[j];
            }
            m[j + 1] = t;      // 找到了m[i]的合适位置、插入
        }
        System.out.println(java.util.Arrays.toString(m));
    }
}
2-路插入排序是在折半插入排序的基础上再改进之,其目的是减少排序过程中移动记录的次数,但为此需要n个记录的辅助空间。

public class Insert3 {
    public static void main(String[] args) {
        int[] m = {3, 1, 5, -2, 9, 7, 4};
        int[] temp = new int[m.length];
        int rear , first, k;
        rear = first = 0;
        temp[rear] = m[0];
        for (int i = 1; i < m.length; i++) {
            if (m[i] > temp[rear]) {    // 比rear的数据大的,取代之rear指向它
                rear = (rear + 1) % m.length;
                temp[rear] = m[i];
            } else if (m[i] < temp[first]) {    // 比first的数据大的,取代之first指向它
                first = (first - 1 + m.length) % m.length;
                temp[first] = m[i];
            } else {    // 比rear小但比first大、理解成一个循环链表与每个元素比较后插入合适位置
                k = (rear - 1 + m.length) % m.length; // 从rear的后一个数据元素开始比较起
                temp[rear + 1] = temp[rear];
                while (temp[k] > m[i]) {
                    temp[(k + 1) % m.length] = temp[k % m.length];
                    k = (k - 1 + m.length) % m.length;
                }
                temp[(k + 1) % m.length] = m[i];
                rear = (rear + 1) % m.length;
            }
            System.out.println(java.util.Arrays.toString(temp));
        }
        // 将temp数组排序记录赋给m
        for (int i = 0; i < m.length; i++) {
            m[i] = temp[(i + rear + 1) % m.length];
        }
        System.out.println(java.util.Arrays.toString(m));
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值