java 中常见的排序——插入排序(直接插入排序,希尔排序)
插入排序的基本思想概述
- 直接插入排序:一个无序的序列或者一个数组,将第一个元素当做一个有序的数列,然后将后面无序数列的第一个元素与有序数列中的元素从后往前依次比较,找到合适的位置插入进去。这就好像打扑克牌,左手拿的牌总是一个有序的组合,右手抓牌,从后往前依次比较,插入合适的位置当中。
- 希尔排序: 将一个数组分为多个子序列,然后对每个序列进行直接插入排序。
插入排序图解
直接插入排序
希尔排序
代码提现
直接插入排序代码
public class InsertSortDemo {
public static void main(String[] args) {
int[] arr = { 5, 3, 1, 8, 4, 2 };
System.out.println("排序前:");
printArray(arr);
System.out.println("插入排序后:");
insertSort(arr);
printArray(arr);
}
private static void insertSort(int[] arr) {
// 控制循环的次数
for (int i = 1; i < arr.length; i++) {
/*
* 判断语句:
* j > 0 保证 j-1处索引是数组下标范围内
* arr[j] < arr[j-1] 无序序列的第一个元素与有序序列的元素,从后往前依次比较
* 当这两个条件都满足时,交换数据。
*/
for (int j = i; (j > 0) && arr[j] < arr[j - 1]; j--) {
swap(arr, j, j - 1);
}
}
}
/**
* 交换arr数组中下标x 和 y的元素位置
*
* @param arr
* @param x
* @param y
*/
private static void swap(int[] arr, int x, int y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
/**
* 输出数组arr中的元素
* @param arr
*/
private static void printArray(int[] arr) {
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
}
输出结果:
排序前:
5 3 1 8 4 2
插入排序后:
1 2 3 4 5 8
希尔排序代码提现
public class ShellSortDemo {
public static void main(String[] args) {
int[] arr = { 9, 4, 5, 0, 1, 8, 7, 3, 6, 2 };
System.out.println("排序前:");
printArray(arr);
shellSort(arr);
System.out.println("希尔排序后:");
printArray(arr);
}
private static void shellSort(int[] arr) {
int num = 0;
for (int i = arr.length/2; i >= 1; i /= 2) {
num++;
for (int j = 0; j < i; j++) {
//以不同增量值开始分组,然后对不同分组进行直接插入排序
insertSort(arr,j,i);
}
System.out.println("第"+num+"次希尔排序后:");
printArray(arr);
}
}
/**
* 以不同增量分组后进行直接插入排序
*
* @param arr 排序的数组
* @param start 初始位置
* @param grap 增量
*/
private static void insertSort(int[] arr, int start, int grap) {
for(int x = start+grap;x < arr.length;x++){
for(int y = x;(y>=grap)&&(arr[y]<arr[y-grap]);y-=grap){
swap(arr, y, y-grap);
}
}
}
/**
* 交换arr数组中下标x 和 y的元素位置
*
* @param arr
* @param x
* @param y
*/
private static void swap(int[] arr, int x, int y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
/**
* 输出数组arr中的元素
*
* @param arr
*/
private static void printArray(int[] arr) {
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
}
输出结果:
排序前:
9 4 5 0 1 8 7 3 6 2
第1次希尔排序后:
8 4 3 0 1 9 7 5 6 2
第2次希尔排序后:
1 0 3 2 6 4 7 5 8 9
第3次希尔排序后:
0 1 2 3 4 5 6 7 8 9
希尔排序后:
0 1 2 3 4 5 6 7 8 9
注意
希尔排序是一种不稳定的排序方式,当一个序列中出现重复的数据时,可能会交换了两个相同数据的位置,并不是排序的输出会有什么问题。
写的不好还望见谅,如果有什么错误请指出,谢谢!