Java—插入类排序(直接插入排序,希尔排序)
Tags: 排序算法
- 直接插入排序
1.算法思想:其基本操作为将第i个记录插入到前面i-1个已经排好序的记录中
2.实现代码:
/* 直接插入排序*/
/* 结果升序
- 从第二个元素开始,设为标记元素,放入temp中;
- 从标记位开始(前面都是排好序的),向前倒序遍历;
- 若遍历的值大于标记值,则将遍历的值后移(由于标记位已经被temp缓存,所以必定有空位)
- 直到遇到小于标记值得遍历值时,将标记值放在遍历值的后面。
*/
public class InsSort {
public int[] insSort(int[] array) {
int temp;
int j;
for(int i=1;i<array.length;i++) {
temp = array[i];
j = i;
while(j>0 && array[j-1]>temp) {
array[j] = array[j-1];
j--;
}
array[j] = temp;
}
return array;
}
}
3.时间空间效率 (最好情况为:顺序排列;最坏情况为:逆序排列;)
时间复杂度:
T(n)=O(n2)
空间复杂度:
S(n)=O(1)
- 希尔排序
1.算法思想:希尔排序又称为缩小增量排序,利用了直接插入排序的最佳性质。将初序列分成若干较小的子序列,对子序列进行直接插入排序。
2.代码实现:
/* 希尔排序
* 直接插入排序的增强版,运用了直接插入排序的优势。当增量d=1时,即为直接插入排序
*/
public class ShellSort {
//结果升序
public int[] shellInsertSort(int[] array,int delta) {
for(int i=delta;i<array.length;i++) { //1+delta为第一组第二个元素的下标
if(array[i-delta] > array[i]) { //如果前面的元素(i-delta)小则直接插入,如果前面大,则排序后插入
int j = i-delta;//定义j循环在本组内回退遍历寻找适当位置
int temp = array[i]; //将当前变量缓存
array[i] = array[i-delta];//因为j已经在外部回退过一次,在while循环中会少一次元素后移。
while(j>=0 && array[j]>temp) {
array[j+delta] = array[j]; //若遍历值大于缓存值,则后移
j = j-delta;
}
array[j+delta] = temp; //插入到寻找的位置
}
}
return array;
}
public int[] shellSort(int[] array,int initDelta) {
while(initDelta>=1) {
array = shellInsertSort(array,initDelta);
initDelta = initDelta/2; //delta增量的初值为数组长度的一半,每次减为上次一半
}
return array;
}
}
3.时间空间效率:
时间复杂度:
T(n)=O(n1.5)
空间复杂度:
S(n)=O(1)
**注意:希尔排序对于中等规模(n<=1000)的序列具有较高的效率。
希尔排序不稳定,反例{2,4,1,2}**
测试代码
public class Main { public static void main(String[] args) { int[] arrayIn = {12,2,32,3,9,15,56,78,34,99,21}; // InsSort ins = new InsSort(); //直接插入排序 // int[] arrayOut = ins.insSort(arrayIn); ShellSort shell = new ShellSort(); int[] arrayOut = shell.shellSort(arrayIn, arrayIn.length/2); output(arrayOut); } public static void output(int[] array) { for(int i=0;i<array.length;i++) { System.out.print(array[i] + " "); } } }