java 希尔排序
希爾排序(更高效的插入排序)
減少最小數在最后一位的情況下要循環的次數
思路:
把數組按增量(n/2)分組,對每一組使用插入排序去排序交換位置,然后不停地增量/2,直到其為1時,結束
- 分組:如n/2=5
891723
8與3為一組
從不包含本身的數開始數 - 兩種實現方法:
交換法(效率較低)
移動法(效率較高)
交換法
對第一輪排序的分析
public class ShellSort {public static void main(String[] args) {int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};System.out.println("排序前---");System.out.println(Arrays.toString(arr));shellSort(arr);}public static void shellSort(int[] arr) {//第一種方式:交換法//10個數據進行了三輪排序//第一輪,將1o個數據分成了5組//遍歷每一組,共有5組for (int i = 5; i < arr.length; i++) {//遍歷各組中所有的元素(共有5組),每一組有兩個元素,步長5//int j = i-5剛好是每一組的第一個元素//j -= 5為了退出當前循環,進行下一組交換for (int j = i - 5; j >= 0; j -= 5) {//如果當前元素大于加上步長后的元素,說明需要交換if (arr[j] > arr[j + 5]) {//交換int temp = arr[j];arr[j] = arr[j + 5];arr[j + 5] = temp;}}}System.out.println("第1輪插入后---");System.out.println(Arrays.toString(arr));} }排序過程
排序前--- [8, 9, 1, 7, 2, 3, 5, 4, 6, 0] 第1輪插入后--- [3, 5, 1, 6, 0, 8, 9, 4, 7, 2] 第2輪插入后--- [0, 2, 1, 4, 3, 5, 7, 6, 9, 8] 第3輪插入后--- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]代碼實現:
public class ShellSort {public static void main(String[] args) {int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};System.out.println("排序前---");System.out.println(Arrays.toString(arr));shellSort(arr);}public static void shellSort(int[] arr) {//第一種方式:交換法//10個數據進行了三輪排序//第一輪,將1o個數據分成了5組//遍歷每一組,共有5組//gsp每一次的增量,最后為1int count = 0;for (int gsp = arr.length / 2; gsp > 0; gsp /= 2) {for (int i = gsp; i < arr.length; i++) {//遍歷各組中所有的元素(共有5組),每一組有兩個元素,步長5//int j = i-5剛好是每一組的第一個元素//j -= 5為了退出當前循環,進行下一組交換for (int j = i - gsp; j >= 0; j -= gsp) {//如果當前元素大于加上步長后的元素,說明需要交換if (arr[j] > arr[j + gsp]) {//交換int temp = arr[j];arr[j] = arr[j + gsp];arr[j + gsp] = temp;}}}System.out.println("第" + (++count) + "輪插入后---");System.out.println(Arrays.toString(arr));}} }移動法
交換法效率低是因為發現一個就交換一個
public class ShellSort {public static void main(String[] args) {int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};System.out.println("排序前---");System.out.println(Arrays.toString(arr));shellSort2(arr);}public static void shellSort2(int[] arr) {//第二種方法:移動法//使用增量,逐步縮小增量int count = 0;for (int gap=arr.length/2;gap>0;gap/=2){//從第gap個元素開始,逐個對其所在組進行直接插入排序//遍歷每一個組for (int i = gap; i < arr.length; i++) {int index=i;//待插入的下標,每個組的第二個元素int value=arr[index];//用臨時變量記錄要插入的數//找位置arr[index-gap]每個組第一個元素if(arr[index]<arr[index-gap]){while (index-gap>=0&&value<arr[index-gap]){//移動arr[index]=arr[index-gap];index-=gap;}//當退出while就找到了插入的位置arr[index]=value;}}System.out.println("第" + (++count) + "輪插入后---");System.out.println(Arrays.toString(arr));}}}無注釋版
public class TestShellSort {public static void main(String[] args) {int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};System.out.println("排序前---");System.out.println(Arrays.toString(arr));shellSort2(arr);}private static void shellSort1(int[] arr) {//交換法for (int gap = arr.length / 2; gap > 0; gap /= 2) {for (int i = gap; i < arr.length; i++) {for (int j = i - gap; j >= 0; j -= gap) {if (arr[j] > arr[j + gap]) {int temp = arr[j];arr[j] = arr[j + gap];arr[j + gap] = temp;}}}}System.out.println("排序后---");System.out.println(Arrays.toString(arr));}private static void shellSort2(int[] arr) { //移動法for (int gap = arr.length / 2; gap > 0; gap /= 2) {for (int i = gap; i < arr.length; i++) {int index=i;int value=arr[index];if (arr[index]<arr[index-gap]){while (index-gap>=0&&value<arr[index-gap]){arr[index]=arr[index-gap];index-=gap;}arr[index]=value;}}}System.out.println("排序后---");System.out.println(Arrays.toString(arr));} }總結
- 上一篇: 端到端测试,protractor测试的教
- 下一篇: 对编程人员我想说:多做 多实践 多写