插入排序
算法流程:
1、将一个具有n个元素的待排序数列分成两个子数列,一个有序和一个无序。
2、刚开始,我们将左边第一个元素看成一个有序数列,右边n-1个元素看成无序数列。
3、从右边无序数列中取出一个元素,在已排序数列中从后往前扫描(比较),找到相应的位置并插入,使插入后有序数列仍然有序。
4、重复第3步,直到完成整个排序过程。
import java.util.Arrays;
public class InsertSort {
public static void main(String[] args) {
int[] arr = {9, 2, 5, 1, 3, 2, 9, 5, 2, 1, 8};
int j;
System.out.println("原数组: " + Arrays.toString(arr));
//从i=1 开始,因为单独一个元素arr[0]是有序的;
for(int i=1;i<arr.length;i++) {
//从无序数列中取出一个元素赋值给tmp
int tmp = arr[i];
int j=i;
//不断往前寻找,直到找到比tmp小的值或者j-1>=0为止
while(j>=1&&arr[j-1]>tmp) {
arr[j] = arr[j-1]; //这个过程就是将牌依次移动,给tmp的值让出一个位置
j--;
}
//将tmp插空出来的位置。
arr[j] = tmp;
}
System.out.println("插入排序后的数组: " + Arrays.toString(arr));
}
}
结果为:
原数组: [9, 2, 5, 1, 3, 2, 9, 5, 2, 1, 8]
插入排序后的数组: [1, 1, 2, 2, 2, 3, 5, 5, 8, 9, 9]
(把它想象成一个抹牌的动作,其实还可以改成for循环)
时间复杂度O(n^2)
希尔排序
算法流程:
1、将一个具有n个元素的待排序数列分成两个子数列,一个有序和一个无序。
2、刚开始,我们将左边第一个元素看成一个有序数列,右边n-1个元素看成无序数列。
3、从右边无序数列中取出一个元素,在已排序数列中从后往前扫描(比较),找到相应的位置并插入,使插入后有序数列仍然有序。
4、重复第3步,直到完成整个排序过程。
import java.util.Arrays;
public class ShellSort {
public static void main(String[] args) {
int[] arr = {9, 2, 5, 1, 3, 2, 9, 5, 2, 1, 8};
System.out.println("原数组: " + Arrays.toString(arr));
//增量每次都/2
for (int step=arr.length/2;step>0;step/=2) {
//从增量那组开始进行插入排序,直至完毕
for (int i=step;i<arr.length;i++) {
int temp = arr[j];
int j = i;
// j-step 就是代表与它同组隔壁的元素
while (j-step>=0 && arr[j-step]>temp) {
arr[j] = arr[j-step];
j = j - step;
}
arr[j] = temp;
}
}
System.out.println("希尔排序后的数组: " + Arrays.toString(arr));
}
}
结果为:
原数组: [9, 2, 5, 1, 3, 2, 9, 5, 2, 1, 8]
希尔排序后的数组: [1, 1, 2, 2, 2, 3, 5, 5, 8, 9, 9]
(跟插入排序相比,就是加个for循环,然后把所有-1的地方换成了-step)