zoukankan      html  css  js  c++  java
  • 插入类排序算法

    复习八大基础排序算法。分类:
    1. 插入类(直接插入、希尔排序)
    2. 选择类(直接选择、堆排序)
    3. 交换类(冒泡排序、快速排序)
    4. 归并排序
    5. 还有外部排序(桶排序?)

    直接插入

    首先明确定义,比如插入排序如果对定义不够清楚,有可能写着写着就掺和进了选择排序(排序结果不一定错,但是过程“变质了”)。

    直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。

    设数组为a[0…n-1]。

    1. 初始时,a[0]自成1个有序区,无序区为a[1..n-1]。令i=1

    2. 将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间

    3. i++并重复第二步直到i==n-1。排序完成

    下面给出严格按照定义书写的代码(由小到大排序):

    public static void insertionSort1(Comparable[] a) {
    	for (int i = 1; i < a.length; i++) {
    		// search
    		int j;
    		for (j = i - 1; j >= 0; j--)
    			if (less(a[j], a[i]))	 break;  // a[j] < a[i]
    		// insert (shift then put)
    		if (j != i - 1) {
    			Comparable temp = a[i];
    			for (int k = i; k > j + 1; k--)
    				a[k] = a[k - 1];
    			a[j + 1] = temp;
    		}
    	}
    }
    

    这个代码比较长,可以进行改写,将搜索和数据后移两个步骤合并。即:用temp记录a[i]的值,每次a[j]都和a[i]比较,如果a[i] < a[j]说明a[0…i]也是有序的,无须调整;否则就一边将数据a[j]后移一边向前搜索,直到a[j]<a[i]才停止,并将temp放到a[j+1]处。

    public static void insertionSort2(Comparable[] a) {
    	for (int i = 1; i < a.length; i++) {
    		// insert while search
    		Comparable temp = a[i];
    		int j;
    		for (j = i - 1; j >= 0 && less(a[i], a[j]); j--) {
    			a[j + 1] = a[j];
    		}
    		a[j + 1] = temp;
    	}
    }
    

    再对将a[i]插入到前面a[0…i-1]的有序区间所用的方法进行改写,用数据交换代替数据后移。如果a[j]前一个数据a[j-1] > a[j],就交换a[j]和a[j-1],再j--直到a[j-1] <= a[j]。这样也可以实现将一个新数据新并入到有序区间。

    public static void insertionSort3(Comparable[] a) {
    	for (int i = 1; i < a.length; i++) {
    		for (int j = i - 1; j >= 0 && less(a[j+1], a[j]); j--)
    			exch(a, j, j+1);
    	}
    }
    

    希尔排序

    public static void shellSort1(Comparable[] a) {
    	int[] incs = {33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1};
    	for (int d = 0; d < incs.length; d++) {
    		int h = incs[d];
    		if (a.length > h) {
    			for (int k = 0; k < h; k++) {
    				/*
    				 * 对每一组作直接插入排序( insertionSort 只有一组,对应的 h = 1, k = 0 )
    				 */
    				for (int i = k + h; i < a.length; i += h) 
    					for (int j = i - h; j >= k && less(a[j + h], a[j]); j -= h)
    						exch(a, j + h, j);					
    			}	
    		}
    	}
    
    }
    
    
    public static void shellSort2(Comparable[] a) {
    	int[] incs = {33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1};
    	for (int d = 0; d < incs.length; d++) {
    		int h = incs[d];
    		if (a.length > h) {
    			for (int i = h; i < a.length; i++) 
    				for (int j = i - h; j >= 0 && less(a[j + h], a[j]); j -= h)
    					exch(a, j + h, j);
    		}
    	}
    
    }
    
    
  • 相关阅读:
    优秀程序设计的Kiss原则(keep it simple,stupid)
    前端模块化 (好文分享)
    sublime 常用快捷键(转)
    认识与入门 MarkDown (转Te_Lee)
    Sublime Text 3 常用插件以及安装方法(转)
    Flex 布局
    eclipse neon 离线安装插件
    mysql 自动备份命令
    java大并发数据保存方案
    基于webapi的移动互联架构
  • 原文地址:https://www.cnblogs.com/smartjune/p/5402611.html
Copyright © 2011-2022 走看看