常见算法 及其 复杂度:


wKiom1QjwMXy0ijJAADx1a_3Bm0154.jpg


    下面我们看看插入排序:

    实现思想 : 插牌

    基本思想
     假设待排序的记录存放在数组R[1..n]中。初始时,R[1]自成1个有序区,无序区为R[2..n]。从i=2起直至i=n为止,依次将R[i]插入当前的有序区R[1..i-1]中,生成含n个记录的有序区。

    

 通常将一个记录R[i](i=23,…,n-1)插入到当前的有序区,使得插入后仍保证该区间里的记录是按关键字有序的操作称第i-1趟直接插入排序。

  排序过程的某一中间时刻,R被划分成两个子区间R[1..i-1](已排好序的有序区)和R[i..n](当前未排序的部分,可称无序区)。

  直接插入排序的基本操作是将当前无序区的第1个记录R[i]插人到有序区R[1..i-1]中适当的位置上,使R[1..i]变为新的有序区。因为这种方法每次使有序区增加1个记录,通常称增量法。

  插入排序与打扑克时整理手上的牌非常类似。摸来的第1张牌无须整理,此后每次从桌上的牌(无序区)中摸最上面的1张并插入左手的牌(有序区)中正确的位置上。为了找到这个正确的位置,须自左向右(或自右向左)将摸来的牌与左手中已有的牌逐一比较

    java 实现

     

package cn.edu.ytu.botao.java.sort;
/**
 * 直接插入排序
 * 算法描述 : 现在有一个待排序的数组 arr[n-1] 
 * 1) 将该待排序的数组 arr[n-1] 分成 两个数组一个为有序数组 arr[0] 和一个无序数组 arr[2...n-1]
 * 2) 令 int i = 2 再无序的数组arr[2..n-1] 依次取出元序进行和已排好序的数组 arr[0] 中的元素进行比较,将arr[i] 插入到已排好序的数组中的合适位置。
 * 3) 这样 就会形成两个数组一个 已排好序 arr[0...m] 待排序数组 arr[m+1...n-1]
 * 4) 重复执行 2) 直到所有的元素排好序为止 
 * @author botao
 *
 */
public class InsertSort {
	
	public static void main(String[] args) {
		//需要排序的数组
		int[] arr ={2 , 5, 1 , 1 , 7 , 4 };
		InsertSort insertSort = new InsertSort();
		insertSort.insertSort(arr);
		insertSort.print(arr);
	}
	
	public void print(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			if (i == arr.length-1) {
				System.out.print(arr[i]);
			}else {
				System.out.print(arr[i] + ",");
			}
		}
	}
	
	/**
	 * 
	 * @param arr  待排序的数组
 	 */
	public void insertSort(int arr[]) {
		//数组的结束下标
		int j = arr.length-1;
		/**
		 *     [2 , 5 , 1 , 7 , 4]
		 * 1)  [2 ] [5 , 1 ,7, 4]
		 * 2)  [2 , 5] [1 , 7 , 4]   //从这里开始进行排序 i = 1;
		 * 3)  [1 ,2 , 5] [7 , 4]
		 * 4)  [1 , 2 , 5 , 7] [4 ]
		 * 5)  [1 , 2 , 4 , 5 , 7]
		 */
		
		//待排序数组的开始下标  设数组的长度大于 2 
		int i = 1;
		//已排好序数组的标志位 也就是长度
		int flag = 1;
	
		for (; i < arr.length; i++) {  // i 为待排序数组的下标
			//一趟排序
			//k 为已排好序的数组的下标
			for (int k = 0; k < flag; k++) {
				//从待排序数组中取出的第一个元素比已排好序的数组中的 arr[k] 小 则将数组arr 从 k到i 的元素依次向后移动 将arr[i] 放在k位置上 
				if (arr[i] < arr[k]) {
					int temp = arr[i];
					//进行数组依次向后移动
					for (int k2 = i; k2 > k; k2--) {
						arr[k2] = arr[k2-1];
					}
					//将 arr[i] 放在数组下标 k 的位置
					arr[k] = temp;
					//已排好序的数组长度加1
					flag++;
					break;  //退出一趟循环 进行下一趟循环
				}
				//从待排序数组中取出的第一个元素比已排好序的数组中的 arr[k]大或是相等并且比arr[k+1]小 则将数组arr 从 k+1到i 的元素依次向后移动 将arr[i] 放在k+1位置上 
				if (arr[i] >= arr[k] && arr[i] < arr[k+1]) {
					int temp = arr[i];
					//对数组进行依次向后移动
					for (int l = i; l > k+1; l--) {
						arr[l] = arr[l-1];
					}
					//将 arr[i] 放到已排好数组 k+1 的位置
					arr[k+1] = temp;
					//已排好序的数组长度加1
					flag++;
					break;  //退出一趟循环 进行下一趟循环
				}
			}
		}
		
	}
}