常见算法 及其 复杂度:
下面我们看看插入排序:
实现思想 : 插牌
基本思想
假设待排序的记录存放在数组R[1..n]中。初始时,R[1]自成1个有序区,无序区为R[2..n]。从i=2起直至i=n为止,依次将R[i]插入当前的有序区R[1..i-1]中,生成含n个记录的有序区。
通常将一个记录R[i](i=2,3,…,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; //退出一趟循环 进行下一趟循环
}
}
}
}
}
转载于:https://blog.51cto.com/botao900422/1558226