插入排序
- 插入排序包括直接插入、折半插入、希尔排序;
- 任何一种插入排序的每趟排序都不会产生全局有序区;
排序算法的稳定性:是指如果待排序的表中存在多个关键字相同的元素,经过排序后这些元素之间的相对次序保持不变,则这种排序方法是稳定的;反之是不稳定的;
直接插入
- 时间复杂度 O(n^2) 属于稳定的排序;
- 取无序区开头元素a[ j ]插到有序区的适当位置;
- 在有序区从后往前找,凡是大于a[ j ]的均后移一个位置,直到找到一个最大的小于等于a[ j ]的元素位置,将a[ j ]插入到它后面;
private static void directInsertSort1(int[] a) {
//从第二个元素开始,将元素插入到已排好的数组中
for (int i = 1; i < a.length; i++) {
int key = a[i];//要插入的值
int j = i - 1;//从已排好序的数组的最后一个元素向左开始比较
while (a[j] > key && j >= 0) {//找到最大的小于等于key的值的位置j,并将大于key的值后移
a[j + 1] = a[j];
j--;
}
//此时的j代表着插入位置的左边位置下标,即有序区中最大的小于等于key的值的位置;
a[j + 1] = key;
}
}复制代码
以下为参考链接,大佬在文章里面有直接插入排序的动图演示,建议看一下
折半插入
- 时间复杂度 O(n^2) 属于稳定的排序;
- 用折半查找方法先在有序区找到插入位置,再通过移动元素进行插入;
private static void binaryInsertSort(int arr[]) {
int i, j, half, low,high,key;
int length=arr.length;
for (i = 1; i < length; i++) {//从第二个元素开始遍历
low = 0;
high = i - 1;//有序区的最后一个元素下标
key = arr[i];//要插入的元素
//折半查找插入位置
while (low <= high) {//跳出循环时low-high==1
half = (low + high) / 2;
if (arr[half] > key) {
high = half - 1;
} else {
low = half + 1;
}
}
/*此时,因为最终导致low>high的原因是:
在两者相遇之后low在half的基础上增加1或者high在half的基础上减少1,
所以low-high==1;
倒回循环中:
对high的最后一次操作后,half在high右边,且arr[half]>key,故arr[high+1]>key;
对low的最后一次操作后,half在low的左边,且arr[half]<=key,故arr[low-1]<=key;
又因为low=high+1,所以a[low]>key且a[high]<=key
所以low即为插入位置*/
for (j = i - 1; j >= low; j--) {//移动插入位置之后的元素
arr[j + 1] = arr[j];
}
//插入元素
arr[low] = key;
}
}复制代码
希尔排序
- 时间复杂度 O(n) 属于不稳定的排序;
- 通过某个增量gap,每隔gap取一个数组元素分到一个组,然后在组内进行插入排序,随后逐步缩小增量,继续按组进行插入排序操作;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
//希尔排序 针对有序序列在插入时采用交换法
private static void sort(int[] arr) {
//1.逐步缩小增量gap
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
//2.从第gap个元素,逐个对其所在组进行直接插入排序操作
for (int i = gap; i < arr.length; i++) {
int j = i;
//3.交换,插入排序采用交换法
while (j - gap >= 0 && arr[j] < arr[j - gap]) {
swap(arr, j, j - gap);
j -= gap;
}
}
}
}
//交换数组元素,注意这个交换函数没有用临时变量!!!
private static void swap(int[] arr, int a, int b) {
arr[a] = arr[a] + arr[b];
arr[b] = arr[a] - arr[b];
arr[a] = arr[a] - arr[b];
}复制代码
以下为参考文章,大佬讲的也比较详细,而且还列举了希尔排序的另一种实现方法,建议看一下:
参考:www.cnblogs.com/chengxiao/p…