* 希 尔 排 序(Shell Sort)*
关键思想
将序列划分成若干组,每一组内部各自进行直接插入排序,最后对整个序列进行直接插入排序。
时间复杂度
Time Complexity | Value |
---|---|
最优时间复杂度 | O ( n ) O(n) O(n) |
最差时间复杂度 | O ( n 2 ) O(n^{2}) O(n2) |
平均时间复杂度 | O ( n 1.3 ) O(n^{1.3}) O(n1.3) |
空间复杂度
Space Complexity | Value |
---|---|
空间复杂度 | O ( 1 ) O(1) O(1) |
稳定性 ×
解析:
不稳定性:若原序列中数 i i i位于数 j j j前面,且 i = j i=j i=j,整个排序过程结束之后数 i i i可能位于数 j j j后面。
实例:[100 8 20 16 14 7 105 50 78 9](Java)
public static void main(String[] args) {
// TODO 自动生成的方法存根
System.out.println("请键盘输入整数序列[例如:100 8 20 16 14 7 105 50 78 9 end]"); // 从键盘接收输入信息
Scanner List = new Scanner(System.in);
ArrayList<Integer> inputArray = new ArrayList<Integer>();
while (List.hasNextInt()) {
inputArray.add(List.nextInt());
}
List.close();
System.out.println("输入:" + inputArray);
Shell_Sort(inputArray);
}
public static void Shell_Sort(ArrayList<Integer> inputArray) {
int i = 1;
int distance = inputArray.size() / 2; // 分组每隔distance距离取下一个元素
while(distance > 0) {
System.out.print("第" + i + "轮希尔排序");
System.out.println("(Distance:" + distance + " / Number:" + inputArray.size() / distance + ")");
for (int k = 0; k < distance; k++) {
ArrayList<Integer> subArray = new ArrayList<Integer>(); // 存储分组序列元素
for (int j = k; j < inputArray.size(); j = j + distance) {
subArray.add(inputArray.get(j));
}
System.out.println("第" + (k + 1) + "分组:" + subArray);
DirectInsertSort(subArray);
int num = 0; // num指subArray序列中的元素地址
for (int j = k; j < inputArray.size(); j = j + distance) {
inputArray.set(j, subArray.get(num));
num += 1;
}
}
System.out.println("End:" + inputArray);
i += 1;
distance = distance / 2;
}
}
public static void DirectInsertSort(ArrayList<Integer> subArray) { // 直接插入排序算法
for (int i = 1; i < subArray.size(); i++) {
int key = subArray.get(i);
for (int j = i - 1; j >= 0; j--) {
if (subArray.get(j) > key) { // 当有序区中某一个元素值大于关键值(无序区中最左边的元素)
System.out.print(key + "<" + subArray.get(j) + " → 交换 → ");
subArray.set(j + 1, subArray.get(j));
subArray.set(j, key);
System.out.println(subArray);
}
else {
if (subArray.get(j) < key)
System.out.println(key + ">" + subArray.get(j) + " → 不交换 → " + subArray);
if (subArray.get(j) == key)
System.out.println(key + "=" + subArray.get(j) + " → 不交换 → " + subArray);
break;
}
}
}
}