排序(插入排序)

插入排序(Insertion Sorting)的基本思想

把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。

说通俗一点,如果你玩过斗地主(扑克),那么你理牌的过程就是插入排序。发给你的牌是一个无序表(设为A),你手中的牌是一个有序表(设为B)。你从A中拿起一张牌,会在B中找一个合适的位置,这个位置后面的点数大于这张牌,这个位置前面的点数小于这张牌,找到位置后就将这张牌插入B,最终B中的牌都是有序的。

代码实现
public class InsertSort {
    public static void main(String[] args) {
        int[] nums = new int[]{10, 2, 11, 56, 0, 8, 90, 22, 1, 66};
        for (int num : nums) {
            System.out.print(num + "\t");
        }
        System.out.println();
        insertSort(nums);
        for (int num : nums) {
            System.out.print(num + "\t");
        }
        System.out.println();
    }
    // 升序排序
     public static void insertSort(int[] nums) {
        // 外层循环从第二个数开始遍历,nums[i]表示待插入的数
        for (int i = 1; i < nums.length; i++) {
            int j = i;
            // 用临时变量保存这个待插入的数
            int temp = nums[i];
            // 如果待插入的数小于它的前一个数就要进行移位,否则不操作
            if (temp < nums[j - 1]) {
                // 一直进行移位操作,直到temp找到合适的位置,这个位置的索引就是while循环结束后的j
                while (j - 1 >= 0 && temp < nums[j - 1]) {
                    nums[j] = nums[j - 1];
                    j -= 1;
                }
                // 插入
                nums[j] = temp;
            }
        }
    }
}
结果
10	2	11	56	0	8	90	22	1	66	
0	1	2	8	10	11	22	56	66	90	
时间复杂度为O(n^2)
测试耗时
   // 创建随机数
    public static int[] createNum(int size, long seed) {
        int[] nums = new int[size];
        Random random = new Random(seed);
        for (int i = 0; i < nums.length; i++) {
            nums[i] = random.nextInt(1000);
        }
        return nums;
    }

    // 测试5轮
    public static void testTime(int size) {
        // 使用不同的种子,使每一轮测试的随机数不一样
        // 种子也可以用于其他排序,因为Random是个伪随机数类,
        // 只要种子相同,两个Random对象产生的随机数也一样,
        // 利用这个特点在测试其他排序时,使用种子一样,他们排序的数据
        // 也一样
        int[] seeds = new int[]{9999, 8888, 7777, 6666, 5555};

        int[] nums = createNum(size, seeds[0]);
        long start = System.currentTimeMillis();
        insertSort(nums);
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "ms");

        nums = createNum(size, seeds[1]);
        start = System.currentTimeMillis();
        insertSort(nums);
        end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "ms");

        nums = createNum(size, seeds[2]);
        start = System.currentTimeMillis();
        insertSort(nums);
        end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "ms");

        nums = createNum(size, seeds[3]);
        start = System.currentTimeMillis();
        insertSort(nums);
        end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "ms");

        nums = createNum(size, seeds[4]);
        start = System.currentTimeMillis();
        insertSort(nums);
        end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "ms");
    }

结果如下:

耗时:13452ms
耗时:10161ms
耗时:9972ms
耗时:10000ms
耗时:9800ms

#####注意:当被插入的数较小时,数组元素后移的次数会明显增多,对效率有影响。
如:2 3 4 5 6 7 8 1
当1被插入时,前面所有的元素都会向后移动一位,如果数据量较大,这种情况出现的频率也较大,那么就会对效率造成较大影响。
解决办法:请看下一篇:希尔排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值