前言 |
内容 |
宏观
算法种类很多,主要介绍用于比较的排序
言归正传,开始介绍
就按照图上的顺序来吧
1.插入类排序–(直接插入,折半插入,希尔排序) 这是插入排序的一个顺序,图有些丑,
直接插入排序
代码
public class sort {
public static void main(String[] args){
int[] r = {0,2,3,1,5,4,6,8,9,10,7};
sort sort1= new sort();
sort1.insertSort(r,0 ,7);
for (int i : r) {
System.out.print(i+",");
}
}
public void insertSort(int[] r, int low, int high) {
// 从小到大
for (int i = low + 1; i < r.length ; i++) {
if (r[i] < r[i - 1]) {
int temp = r[i];
r[i] = r[i - 1];
int j = i - 2;
for (;j >= low && temp < r[j]; j--) {
r[j + 1] = r[j]; // 记录后移
}
// while (j > low && temp < r[j]) {
// r[j + 1] = r[j];
// j--;
// }
r[j + 1] = temp;
// 插入到正确位置
}
}
}
}
代码强调以下问题
1.边界
外层循环:假设为十个数则循环9次
内层循环 从第二个数开始比较
2.时间复杂度
O(n²)
3.原理,
为插入算法,其原理是一种位置移动,而不是相互交换位置,(向有序区中插入值,插入值之后的数依次后移一位)
折半插入算法
代码(没写注释,~~不懂可以问,可以要求加注释)
public class BinaryInsertion {
public static void main(String[] args) {
int[] r = {0,2,3,1,9,10,7};
BinaryInsertion binary = new BinaryInsertion();
binary.binaryInsertion(r,0,7);
for (int i : r) {
System.out.print(i+",");
}
}
public void binaryInsertion(int[] r, int low, int high) {
for (int i = low + 1; i < r.length; i++) {
int temp = r[i];
int hi = i - 1;
int lo = low;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (temp < r[mid]) {
hi = mid - 1;
} else {
lo = mid + 1;
}
}
for (int j = i - 1; j >= lo; j--) {
r[j + 1] = r[j];
}
r[hi + 1] = temp;
}
}
}
代码强调以下问题
1.边界
1.比较过程中lo会是high的后一位
2.外层循环时不能等于数组长度,会溢出
3.中间值一般是向下取整的
2.时间复杂度 : O(n²)
3.原理,
折半插入之后会缩小比较的范围,插入时依然需要插入点之后的数值依次后移 ?
希尔排序
代码(直接插入的升级版,步长可以自定义)
public class shellsort {
public static void main(String[] args){
int[] r = {0,5,2,3,1,10,6,4,7,8};
// 自定义了一个数组,5为第一次的步长,1为第二次的步长
int[] delta = {5,1};
shellsort shell2=new shellsort();
shell2.shell(r,0,9,delta);
for (int i : r) {
System.out.print(i+",");
}
}
public void shell(int[] r, int low, int high, int[] delta){
for(int k=0 ;k<delta.length;k++){
shellInsert(r, low, high, delta[k]); //一趟步长为 delta[k]的直接插入排序
}
}
private void shellInsert(int[] r ,int low, int high, int deltaK){
for (int i=low+deltaK; i<=high; i++) {
if (r[i] < r[i - deltaK]) { //小于时,需将 r[i] 插入有序表
int temp = r[i];
int j = i - deltaK;
for (; j >= low && temp< r[j]; j = j - deltaK) {
r[j + deltaK] = r[j]; //记录后移
}
r[j + deltaK] = temp; //插入到正确位置
}
}
}
}
代码强调以下问题
1.边界
待定
2.时间复杂度 : 待定
3.原理,
简单地说,除了步长不一样和直接插入是一样的哦, ?,在复杂一点点的话,就是,会按步长分组,每组内都是直接插入排序,直到按照步长为1的排完序就可以得到最终结果.
小结 |