二 核心思想:
三: 具体步骤
四:举例:
看以下这个例子:对7 8 9 0 4 3进行插入排序
7 8 9 0 4 3
7 8 9 0 4 3
7 8 9 0 4 3
0 7 8 9 4 3
0 4 7 8 9 3
0 3 4 7 8 9
从以上操作中我们看到插入排序会经历一个元素的比较以及元素的移动。当我们从待排序列中取一个数插入到已排序区间时,需要拿它与已排序区间的数依次进行比较,直到找到合适的位置,然后还要将插入点之后的元素进行往后移动。
五:插入排序代码实现、
package sort;
/**
* 插入排序
*/
public class InsertionSort {
/**
*
1.将数组分成已排序段和未排序段。初始化时已排序端只有一个元素
2.到未排序段取元素插入到已排序段,并保证插入后仍然有序
3.重复执行上述操作,直到未排序段元素全部加完。
*
* @param args
*/
public static void main(String[] args) {
int a[] = { 9, 8, 7, 0, 1, 3, 2 };
int n = a.length;
//这里面会有几层循环 2
//时间复杂度:n^2
//最好的情况:什么情况下:O(n); O(1)
//for(){ //分段
for(int i = 1 ; i < n;i++){ //为什么i要从1开始? 第一个不用排序,我们就把数组从i分开,0~I的认为已经排好序
int data = a[i];
int j = i -1;
for(;j>=0;j--){//从尾到头 1+2+3+4+5+...+n=>
if(a[j] > data){
a[j+1] = a[j]; // 数据往后移动
}else{ //因为前面已经是排好序的 那么找到一个比他小的就不用找了,因为前面的肯定更小
break; //O(1) 如果这个break执行的越多 那么我是不是效率就越高?
}
}
a[j+1] = data;
System.out.print("第" +i +"次的排序结果为:");
for(j = 0 ; j < n;j++){
System.out.print(a[j]+" ");
}
System.out.println();
}
}
}
六:优化 (希尔排序==>插入排序改进版)
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量 =1( < …<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
来看一个具体的过程: 按照一个增量分段:add=n/2 n=10 =>5,2,1 7 8 9 0 4 3 1 2 5 10 我们取的这个增量分别就是5 2 1 7 8 9 0 4 3 1 2 5 10:分出来的数组元素都是一样的 完成一次排序: 3 1 2 0 4 7 8 9 5 3 2 4 8 5:取增量为2的分为一组了 最后一次我们就取增量为1的分组: 就是一个完整的序列,但是时间复杂度还是O(n^2)
七:归并排序 (核心思想:递归+分治)
主要分析时间复杂度:nlogn
package sort;
import java.util.Arrays;
public class MegrSort {
public static void main(String[] args) {
int data[] = { 9, 5, 6, 8, 0, 3, 7, 1 };
//拆分
megerSort(data, 0, data.length - 1);
System.out.println(Arrays.toString(data));
//JDK里面的排序源码
}
public static void megerSort(int data[], int left, int right) { // 数组的两端
if (left < right) { // 相等了就表示只有一个数了 不用再拆了
int mid = (left + right) / 2;
//拆分从最左边到中间
megerSort(data, left, mid);
//拆分右边从中间+1到最右边
megerSort(data, mid + 1, right);
// 分完了 接下来就要进行合并,也就是我们递归里面归的过程
meger(data, left, mid, right);
}
}
public static void meger(int data[], int left, int mid, int right) {
int temp[] = new int[data.length]; //借助一个临时数组用来保存合并的数据
int point1 = left; //表示的是左边的第一个数的位置
int point2 = mid + 1; //表示的是右边的第一个数的位置
int loc = left; //表示的是我们当前已经到了哪个位置了
while(point1 <= mid && point2 <= right){
if(data[point1] < data[point2]){
temp[loc] = data[point1];
point1 ++ ;
loc ++ ;
}else{
temp[loc] = data[point2];
point2 ++;
loc ++ ;
}
}
//接下来要干嘛呢?合并排序完成 了吗?
while(point1 <= mid){
temp[loc ++] = data[point1 ++];
}
while(point2 <= right){
temp[loc ++] = data[point2 ++];
}
for(int i = left ; i <= right ; i++){
data[i] = temp[i];
}
}
}