zoukankan      html  css  js  c++  java
  • 简单算法之插入排序(二)

    一、思路

    假设有8个数字未被排序。
    默认第一位数为已排序数字a,从剩余的7个未排序数字中拿出第一个数b,b与a进行比较,如果b小于a,则将b插入到a位置前边。
    

    二、案例分析

    待排序数据:8 6 2 3 1 5 7 4
    第一轮排序:
        默认数字8已排序,剩余7个未排序数字中,数字6为未排序集合中的第一个数字,6与8进行比较大小。6小于8,因此6插入到8前边,得到如下结果:
        6 8 2 3 1 5 7 4
        前2个数字已经排序,剩余6个数字未排序。
        
    第二轮排序:
        剩余6个未排序数字中,数字2为未排序集合中的第一个数字,2与8进行比较大小,2小于8,因此2插入到8前边,得到如下结果:
        6 2 8 3 1 5 7 4
        2前边还有一个已排序的数字,2与6进行比较大小,2小于6,因此2插入到6的前边,得到如下结果:
        2 6 8 3 1 5 7 4
        前3个数字已经排序,剩余5个数字未排序。
    ......
    

    三、编码

    public class InsertionSort {
    
    	// 我们的算法类不允许产生任何实例
    	private InsertionSort() {
    	}
    
    	public static void sort(int[] arr) {
    
    		int n = arr.length;
    		for (int i = 1; i < n; i++) {
    
    			// 寻找元素arr[i]合适的插入位置
    
    			// 写法1
    //			for (int j = i; j > 0; j--) {
    //				if (arr[j] < arr[j - 1]) {
    //					swap(arr, j, j - 1);
    //				} else {
    //					break;
    //				}
    //
    //			}
    
    			// 写法2
    			 for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
    				 swap(arr, j, j - 1);
    			 }
    
    		}
    	}
    
    	private static void swap(int[] arr, int i, int j) {
    		int t = arr[i];
    		arr[i] = arr[j];
    		arr[j] = t;
    	}
    
    	// 测试InsertionSort
    	public static void main(String[] args) {
    
    		int[] arr = { 8, 6, 2, 3, 1, 5, 7, 4 };
    		InsertionSort.sort(arr);
    		for (int i = 0; i < arr.length; i++) {
    			System.out.print(arr[i]);
    			System.out.print(' ');
    		}
    		System.out.println();
    	}
    }
    

    四、优化思路

    上述算法思路中,第N轮排序,至多要进行N次数据的位置交换(swap方法中3个赋值操作),这个过程非常耗时,因此需要优化。
    优化思路:
        假设有8个数字未被排序。
        默认第一位数为已排序数字a,从剩余的7个未排序数字中将第一个数b复制一份数据b。副本b与前一个数进行比较大小,如果b小于a,则a移入到b的位置,b插入到a的位置。
    

    五、优化案例分析

    待排序数据:8 6 2 3 1 5 7 4
    第一轮排序:
         默认数字8已排序,剩余7个未排序集合中,数字6为未排序集合中的第一个数字,将其复制一份数据。6与8比较大小,6小于8,8移入到6的位置,6插入到8的位置。得到如下结果:
         6 8 2 3 1 5 7 4
    第二轮排序:
        假设前2数字已排序,剩余6个未排序的集合中,数字2为未排序集合的第一个数字,将其复制一个数据。2与8比较大小,2小于8,8移入到2的位置,2再与6比较大小,2小于6,6移入到8之前的位置,2插入到6的位置。得到如下结果:
        2 6 8 3 1 5 7 4
    ......
    

    六、优化编码

    public static void sortAdvance(int[] arr) {
    	int n = arr.length;
    	for (int i = 1; i < n; i++) {
    		// 拷贝数据
    		int e = arr[i];
    		// j保存元素e应该插入的位置
    		int j;
    		for (j = i; j > 0 && arr[j - 1] > e; j--) {
    			arr[j] = arr[j - 1];
    		}
    		arr[j] = e;
    	}
    }
    
  • 相关阅读:
    core.net 创建coreclass 项目出现一些问题
    【BZOJ4144】[AMPPZ2014]Petrol 最短路+离线+最小生成树
    【BZOJ4774/4006】修路/[JLOI2015]管道连接 斯坦纳树
    【BZOJ2595】[Wc2008]游览计划 斯坦纳树
    【BZOJ4149】[AMPPZ2014]Global Warming 单调栈+RMQ+二分
    【BZOJ4764】弹飞大爷 LCT
    【BZOJ3529】[Sdoi2014]数表 莫比乌斯反演+树状数组
    【BZOJ5008】方师傅的房子 三角剖分
    【BZOJ4282】慎二的随机数列 乱搞
    【BZOJ1568】[JSOI2008]Blue Mary开公司 线段树
  • 原文地址:https://www.cnblogs.com/moonlightL/p/7400822.html
Copyright © 2011-2022 走看看