插入排序

插入排序 java实现

我们玩扑克纸牌时,需要对纸牌从左到右由小到大排序,我们通常是在一部分(可以是1张或者更多)已经有序的纸牌中,把其余纸牌一张一张插入,这个过程和插入排序一样。

算法可视化网站为例:

在这里插入图片描述
插入排序:
{3,44,38,5,47,15,36,26,27,2,46,4,19,50,48}
把第一个元素(3)当作一个有序列表,然后把第二个元素(44)插入有序列表,44与3比较,44比3大,有序列表中的元素不需要移动,44直接放在元素3后面;

现在有序列表为{3,44}:要把38插入有序列表,38需要和44比较,38<44, 元素44后移一位,腾出给元素38的空间,38继续和3比较,38>3,元素3不动,38放置于3和44之间。

现在有序列表为{3,38, 44}:接下来的情况以此类推。

代码实现:

public static void main( String[] args ) {
	    int[] list = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
	    insertionSort(list);
	    for(int element:list)
	    	System.out.printf("%d ",element);
	}
	
	public static void insertionSort(int[] list) {
		for(int i=1; i<list.length; i++) {
			int currentElement = list[i];
			int j = 0;
			for(j=i-1;j>=0 && list[j]>currentElement; j--) {
				list[j+1] = list[j];
			}
			list[j+1] = currentElement;
		}
	}

对数组{3,44,38,5,47,15,36,26,27,2,46,4,19,50,48}排序后截图:
在这里插入图片描述

对于上述代码:
外层循环for(int i=1; i<list.length; i++)
i从1开始,默认把第一个元素(下标为0)当作一个有序列表,这里的i=1指从第二个元素开始遍历;

int currentElement = list[i];

获得当前要插入有序列表的元素;

for(j=i-1;j>=0 && list[j]>currentElement; j--) {
				list[j+1] = list[j];
			}

内层循环:j=i-1;将要插入有序列表的元素与有序列表中的元素一一比较(由右往左比较);
只要j没越界(为负数),并且有序列表中元素存在 > 我们要插入的元素,循环就会继续;
有序列表中大于我们要插入值得元素就会右移,给新元素腾出空间。

list[j+1] = currentElement;

新插入元素的位置,需要是j+1的位置,因为j–在最后一次内层循环后还会-1.

插入排序对部分有序的元素集合效率会更高:

  1. 元素集合中的元素离排序后的元素位置很近
  2. 在一个大的有序元素集合后继续添加一个小的元素集合
  3. 元素集合中只有几个元素位置不正确。

当问题规模为n时:
时间复杂度:
最差O(n^2):
元素集合完全逆序,比如{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
比较次数:1+2+3+4+…+(n-1) = n(n-1)/2
移动次数:1+2+3+4+…+(n-1) = n(n-1)/2

最好O(n):
元素集合完全有序,比如{2 3 4 5 15 19 26 27 36 38 44 46 47 48 50 }
比较次数是n-1
移动次数是0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值