java 希尔排序
希爾排序(更高效的插入排序)
減少最小數(shù)在最后一位的情況下要循環(huán)的次數(shù)
思路:
把數(shù)組按增量(n/2)分組,對每一組使用插入排序去排序交換位置,然后不停地增量/2,直到其為1時(shí),結(jié)束
- 分組:如n/2=5
891723
8與3為一組
從不包含本身的數(shù)開始數(shù) - 兩種實(shí)現(xiàn)方法:
交換法(效率較低)
移動(dòng)法(效率較高)
交換法
對第一輪排序的分析
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個(gè)數(shù)據(jù)進(jìn)行了三輪排序//第一輪,將1o個(gè)數(shù)據(jù)分成了5組//遍歷每一組,共有5組for (int i = 5; i < arr.length; i++) {//遍歷各組中所有的元素(共有5組),每一組有兩個(gè)元素,步長5//int j = i-5剛好是每一組的第一個(gè)元素//j -= 5為了退出當(dāng)前循環(huán),進(jìn)行下一組交換for (int j = i - 5; j >= 0; j -= 5) {//如果當(dāng)前元素大于加上步長后的元素,說明需要交換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]代碼實(shí)現(xiàn):
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個(gè)數(shù)據(jù)進(jìn)行了三輪排序//第一輪,將1o個(gè)數(shù)據(jù)分成了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組),每一組有兩個(gè)元素,步長5//int j = i-5剛好是每一組的第一個(gè)元素//j -= 5為了退出當(dāng)前循環(huán),進(jìn)行下一組交換for (int j = i - gsp; j >= 0; j -= gsp) {//如果當(dāng)前元素大于加上步長后的元素,說明需要交換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));}} }移動(dòng)法
交換法效率低是因?yàn)榘l(fā)現(xiàn)一個(gè)就交換一個(gè)
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) {//第二種方法:移動(dòng)法//使用增量,逐步縮小增量int count = 0;for (int gap=arr.length/2;gap>0;gap/=2){//從第gap個(gè)元素開始,逐個(gè)對其所在組進(jìn)行直接插入排序//遍歷每一個(gè)組for (int i = gap; i < arr.length; i++) {int index=i;//待插入的下標(biāo),每個(gè)組的第二個(gè)元素int value=arr[index];//用臨時(shí)變量記錄要插入的數(shù)//找位置arr[index-gap]每個(gè)組第一個(gè)元素if(arr[index]<arr[index-gap]){while (index-gap>=0&&value<arr[index-gap]){//移動(dòng)arr[index]=arr[index-gap];index-=gap;}//當(dāng)退出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) { //移動(dòng)法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));} }總結(jié)
- 上一篇: 端到端测试,protractor测试的教
- 下一篇: 对编程人员我想说:多做 多实践 多写