折半插入排序在直接插入排序的基础上,运用折半查找的思想来寻找待插入数据在已排序列中合适的位置,可以减少比较次数。
public class Insert2 {
public static void main(String[] args) {
int[] m = {3, 1, 5, -2, 9, 7, 4};
int t = 0; // 监视哨
int low = 0; // 低位
int height = 0; // 高位
int i = 1;
// 折半查找思想比较数据
for (; i < m.length; i++) {
t = m[i];
low = 0;
height = i - 1;
while (low <= height) {
int mid = (low + height) / 2;
if (t >= m[mid])
low = mid + 1;
else
height = mid - 1;
}
// 将找到位置后的元素后移
int j = i - 1;
// 最后mid == height、所以控制用height更好
for (; j >= height + 1; j--) {
m[j + 1] = m[j];
}
m[j + 1] = t; // 找到了m[i]的合适位置、插入
}
System.out.println(java.util.Arrays.toString(m));
}
}
2-路插入排序是在折半插入排序的基础上再改进之,其目的是减少排序过程中移动记录的次数,但为此需要n个记录的辅助空间。
public class Insert3 {
public static void main(String[] args) {
int[] m = {3, 1, 5, -2, 9, 7, 4};
int[] temp = new int[m.length];
int rear , first, k;
rear = first = 0;
temp[rear] = m[0];
for (int i = 1; i < m.length; i++) {
if (m[i] > temp[rear]) { // 比rear的数据大的,取代之rear指向它
rear = (rear + 1) % m.length;
temp[rear] = m[i];
} else if (m[i] < temp[first]) { // 比first的数据大的,取代之first指向它
first = (first - 1 + m.length) % m.length;
temp[first] = m[i];
} else { // 比rear小但比first大、理解成一个循环链表与每个元素比较后插入合适位置
k = (rear - 1 + m.length) % m.length; // 从rear的后一个数据元素开始比较起
temp[rear + 1] = temp[rear];
while (temp[k] > m[i]) {
temp[(k + 1) % m.length] = temp[k % m.length];
k = (k - 1 + m.length) % m.length;
}
temp[(k + 1) % m.length] = m[i];
rear = (rear + 1) % m.length;
}
System.out.println(java.util.Arrays.toString(temp));
}
// 将temp数组排序记录赋给m
for (int i = 0; i < m.length; i++) {
m[i] = temp[(i + rear + 1) % m.length];
}
System.out.println(java.util.Arrays.toString(m));
}
}