1. 程式人生 > 遊戲 >重生失去兩位高管 《Apex英雄》總監和設計總監雙雙離職

重生失去兩位高管 《Apex英雄》總監和設計總監雙雙離職

一、氣泡排序

​ 原理:元素兩兩比較,交換位置,大元素往後放,經過一輪輪比較,每次都少比一次,每次最大的元素就會出現在最大索引處。

public class SortDemo01 {
    public static void main(String[] args) {
        int[] arr={10,101,20,9,901};//5個數,需要比較4輪比較
        //總共比較多少輪,5個數,需要比較4輪比較
        for (int j = 0; j < arr.length - 1; j++) {
            //每加一輪少比一次,所以每次要多減1個數j=0,1,2,3
            for (int i = 0; i < arr.length -1 -j; i++) {
                //兩兩比較
                //如果前面元素比後面的大,交換位置
                if (arr[i]>arr[i+1]){
                    int t=arr[i];
                    arr[i]=arr[i+1];
                    arr[i+1]=t;
                }
                System.out.println(Arrays.toString(arr));//輸出陣列
            }
            System.out.println("++++++++++++++++++++++++");
        }
        //System.out.println(Arrays.toString(arr));//輸出陣列
    }
}
//輸出

/*	
[10, 101, 20, 9, 901]	
[10, 20, 101, 9, 901]
[10, 20, 9, 101, 901]
[10, 20, 9, 101, 901]
++++++++++++++++++++++++
[10, 20, 9, 101, 901]
[10, 9, 20, 101, 901]
[10, 9, 20, 101, 901]
++++++++++++++++++++++++
[9, 10, 20, 101, 901]
[9, 10, 20, 101, 901]
+++++++++++++++++++++++
[9, 10, 20, 101, 901]
++++++++++++++++++++++++
*/

二、選擇排序

​ 原理:從0索引處開始,依次和後面的元素進行比較,小的元素前移

public class SortDemo02 {
    public static void main(String[] args) {
        //選擇排序
        //從索引為0處的元素依次和後面的元素進行比較,小的元素前移
        int[] arr={80,24,69,57,5};//個數為4
        //每輪比較索引+1,總共有4輪
        for (int index = 0; index < arr.length-1; index++) {
            //每輪比較將後一位和前一們進行比較,小的提前
            /*
            	第一輪:比較4次
            	第二輪:比較3次
            	第三輪:比較2次
            	第四輪:比較1次
            */
            for (int i = 1+index; i < arr.length; i++) {
                if(arr[index]>arr[i]){
                    int t=arr[index];
                    arr[index]=arr[i];
                    arr[i]=t;
                }
                System.out.println(Arrays.toString(arr));
            }
            System.out.println("+++++++++++++++++++++++++++++");
        }
    }
}
//輸出
/*
[24, 80, 69, 57, 5]
[24, 80, 69, 57, 5]
[24, 80, 69, 57, 5]
[5, 80, 69, 57, 24]
+++++++++++++++++++++++++++++
[5, 69, 80, 57, 24]
[5, 57, 80, 69, 24]
[5, 24, 80, 69, 57]
+++++++++++++++++++++++++++++
[5, 24, 69, 80, 57]
[5, 24, 57, 80, 69]
+++++++++++++++++++++++++++++
[5, 24, 57, 69, 80]
+++++++++++++++++++++++++++++
*/

三、直接插入排序

​ 原理:從索引1開始,將元素一個個插入到之前的有序表中,使之仍然有序.

​ 從索引用1開始,每個數和前面的數比較,比其小的數就插入其前面,比他大的數不變

import java.util.Arrays;

public class SortDemo04 {
    public static void main(String[] args) {
        //直接插入排序
        int[] arr={46,55,13,42,17,94,5,70};
        Sort(arr);
    }
    private static void Sort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int j=i;
            while(j>0&&arr[j]<arr[j-1]){
                int t=arr[j-1];
                arr[j-1]=arr[j];
                arr[j]=t;
                j--;
                System.out.println(Arrays.toString(arr));
            }
            System.out.println("第"+i+"輪排序最終結果"+Arrays.toString(arr));
            System.out.println("===============================");
        }
    }
}
/*
第1輪排序最終結果[46, 55, 13, 42, 17, 94, 5, 70]
===============================
[46, 13, 55, 42, 17, 94, 5, 70]
[13, 46, 55, 42, 17, 94, 5, 70]
第2輪排序最終結果[13, 46, 55, 42, 17, 94, 5, 70]
===============================
[13, 46, 42, 55, 17, 94, 5, 70]
[13, 42, 46, 55, 17, 94, 5, 70]
第3輪排序最終結果[13, 42, 46, 55, 17, 94, 5, 70]
===============================
[13, 42, 46, 17, 55, 94, 5, 70]
[13, 42, 17, 46, 55, 94, 5, 70]
[13, 17, 42, 46, 55, 94, 5, 70]
第4輪排序最終結果[13, 17, 42, 46, 55, 94, 5, 70]
===============================
第5輪排序最終結果[13, 17, 42, 46, 55, 94, 5, 70]
===============================
[13, 17, 42, 46, 55, 5, 94, 70]
[13, 17, 42, 46, 5, 55, 94, 70]
[13, 17, 42, 5, 46, 55, 94, 70]
[13, 17, 5, 42, 46, 55, 94, 70]
[13, 5, 17, 42, 46, 55, 94, 70]
[5, 13, 17, 42, 46, 55, 94, 70]
第6輪排序最終結果[5, 13, 17, 42, 46, 55, 94, 70]
===============================
[5, 13, 17, 42, 46, 55, 70, 94]
第7輪排序最終結果[5, 13, 17, 42, 46, 55, 70, 94]
===============================
*/

四、希爾排序

​ 原理:是對直接插入排序的優化,通過設定增量(步長),對相同步長間隔的元素進行比較,然後不斷縮減增量,最終使增量為1,完成排序。

​ 直接插入排序可以看成增量為1的希爾排序。

舉例:設增量從4開始縮減

import java.util.Arrays;

public class SortDemo04 {
    public static void main(String[] args) {
        //希爾排序
        int[] arr={46,55,13,42,17,94,5,70};
        shellSort(arr);
    }
    //希爾排序是對直接插入排序的優化,通過設定增量(步長),
    //對相同步長間隔的元素進行比較,然後不斷縮減增量,最終使增量為1,完成排序。
    //直接插入排序可以看成增量為1的希爾排序。
    private static void shellSort(int[] arr) {
        int h=4;//增量
        System.out.println("增量:4");
        for (int i = h; i < arr.length; i++) {
            int j=i;
            while(j>h-1&&arr[j]<arr[j-h]){
                int t=arr[j-h];
                arr[j-h]=arr[j];
                arr[j]=t;
                j-=h;
                System.out.println(Arrays.toString(arr));
            }
            System.out.println("第"+(i-h+1)+"輪排序最終結果"+Arrays.toString(arr));
            System.out.println("===============================");
        }
        System.out.println("**");
        System.out.println("**");
        System.out.println("**");    
        System.out.println("**");
        System.out.println("**");
        h=2;//增量
        System.out.println("增量:2");
        for (int i = h; i < arr.length; i++) {
            int j=i;
            while(j>h-1&&arr[j]<arr[j-h]){
                int t=arr[j-h];
                arr[j-h]=arr[j];
                arr[j]=t;
                j-=h;
                System.out.println(Arrays.toString(arr));
            }
            System.out.println("第"+(i-h+1)+"輪排序最終結果"+Arrays.toString(arr));
            System.out.println("===============================");
        }
        System.out.println("**");
        System.out.println("**");
        System.out.println("**");
        System.out.println("**");
        System.out.println("**");
        h=1;//增量
        System.out.println("增量:1");
        for (int i = h; i < arr.length; i++) {
            int j=i;
            while(j>h-1&&arr[j]<arr[j-h]){
                int t=arr[j-h];
                arr[j-h]=arr[j];
                arr[j]=t;
                j-=h;
                System.out.println(Arrays.toString(arr));
            }
            System.out.println("第"+(i-h+1)+"輪排序最終結果"+Arrays.toString(arr));
            System.out.println("===============================");
        }
    }
}
/*
增量:4
[17, 55, 13, 42, 46, 94, 5, 70]
第1輪排序最終結果[17, 55, 13, 42, 46, 94, 5, 70]
===============================
第2輪排序最終結果[17, 55, 13, 42, 46, 94, 5, 70]
===============================
[17, 55, 5, 42, 46, 94, 13, 70]
第3輪排序最終結果[17, 55, 5, 42, 46, 94, 13, 70]
===============================
第4輪排序最終結果[17, 55, 5, 42, 46, 94, 13, 70]
===============================
**
**
**
**
**
增量:2
[5, 55, 17, 42, 46, 94, 13, 70]
第1輪排序最終結果[5, 55, 17, 42, 46, 94, 13, 70]
===============================
[5, 42, 17, 55, 46, 94, 13, 70]
第2輪排序最終結果[5, 42, 17, 55, 46, 94, 13, 70]
===============================
第3輪排序最終結果[5, 42, 17, 55, 46, 94, 13, 70]
===============================
第4輪排序最終結果[5, 42, 17, 55, 46, 94, 13, 70]
===============================
[5, 42, 17, 55, 13, 94, 46, 70]
[5, 42, 13, 55, 17, 94, 46, 70]
第5輪排序最終結果[5, 42, 13, 55, 17, 94, 46, 70]
===============================
[5, 42, 13, 55, 17, 70, 46, 94]
第6輪排序最終結果[5, 42, 13, 55, 17, 70, 46, 94]
===============================
**
**
**
**
**
增量:1
第1輪排序最終結果[5, 42, 13, 55, 17, 70, 46, 94]
===============================
[5, 13, 42, 55, 17, 70, 46, 94]
第2輪排序最終結果[5, 13, 42, 55, 17, 70, 46, 94]
===============================
第3輪排序最終結果[5, 13, 42, 55, 17, 70, 46, 94]
===============================
[5, 13, 42, 17, 55, 70, 46, 94]
[5, 13, 17, 42, 55, 70, 46, 94]
第4輪排序最終結果[5, 13, 17, 42, 55, 70, 46, 94]
===============================
第5輪排序最終結果[5, 13, 17, 42, 55, 70, 46, 94]
===============================
[5, 13, 17, 42, 55, 46, 70, 94]
[5, 13, 17, 42, 46, 55, 70, 94]
第6輪排序最終結果[5, 13, 17, 42, 46, 55, 70, 94]
===============================
第7輪排序最終結果[5, 13, 17, 42, 46, 55, 70, 94]
===============================
*/

簡化:可以取陣列長度的一半來做為增量

import java.util.Arrays;

public class SortDemo04 {
    public static void main(String[] args) {
        //希爾排序
        int[] arr={46,55,13,42,17,94,5,70};
        shellSort(arr);
    }
    //希爾排序是對直接插入排序的優化,通過設定增量(步長),
    //對相同步長間隔的元素進行比較,然後不斷縮減增量,最終使增量為1,完成排序。
    //直接插入排序可以看成增量為1的希爾排序。
    private static void shellSort(int[] arr) {
        for (int h = arr.length/2; h > 0; h/=2) {
            System.out.println("增量:"+h);
            for (int i = h; i < arr.length; i++) {
                int j=i;
                while(j>h-1&&arr[j]<arr[j-h]){
                    int t=arr[j-h];
                    arr[j-h]=arr[j];
                    arr[j]=t;
                    j-=h;
                    System.out.println(Arrays.toString(arr));
                }
                System.out.println("第"+(i-h+1)+"輪排序最終結果"+Arrays.toString(arr));
                System.out.println("===============================");
            }
            System.out.println("**");
            System.out.println("**");
            System.out.println("**");
            System.out.println("**");
            System.out.println("**");
        }
    }
}
/*
增量:4
[17, 55, 13, 42, 46, 94, 5, 70]
第1輪排序最終結果[17, 55, 13, 42, 46, 94, 5, 70]
===============================
第2輪排序最終結果[17, 55, 13, 42, 46, 94, 5, 70]
===============================
[17, 55, 5, 42, 46, 94, 13, 70]
第3輪排序最終結果[17, 55, 5, 42, 46, 94, 13, 70]
===============================
第4輪排序最終結果[17, 55, 5, 42, 46, 94, 13, 70]
===============================
**
**
**
**
**
增量:2
[5, 55, 17, 42, 46, 94, 13, 70]
第1輪排序最終結果[5, 55, 17, 42, 46, 94, 13, 70]
===============================
[5, 42, 17, 55, 46, 94, 13, 70]
第2輪排序最終結果[5, 42, 17, 55, 46, 94, 13, 70]
===============================
第3輪排序最終結果[5, 42, 17, 55, 46, 94, 13, 70]
===============================
第4輪排序最終結果[5, 42, 17, 55, 46, 94, 13, 70]
===============================
[5, 42, 17, 55, 13, 94, 46, 70]
[5, 42, 13, 55, 17, 94, 46, 70]
第5輪排序最終結果[5, 42, 13, 55, 17, 94, 46, 70]
===============================
[5, 42, 13, 55, 17, 70, 46, 94]
第6輪排序最終結果[5, 42, 13, 55, 17, 70, 46, 94]
===============================
**
**
**
**
**
增量:1
第1輪排序最終結果[5, 42, 13, 55, 17, 70, 46, 94]
===============================
[5, 13, 42, 55, 17, 70, 46, 94]
第2輪排序最終結果[5, 13, 42, 55, 17, 70, 46, 94]
===============================
第3輪排序最終結果[5, 13, 42, 55, 17, 70, 46, 94]
===============================
[5, 13, 42, 17, 55, 70, 46, 94]
[5, 13, 17, 42, 55, 70, 46, 94]
第4輪排序最終結果[5, 13, 17, 42, 55, 70, 46, 94]
===============================
第5輪排序最終結果[5, 13, 17, 42, 55, 70, 46, 94]
===============================
[5, 13, 17, 42, 55, 46, 70, 94]
[5, 13, 17, 42, 46, 55, 70, 94]
第6輪排序最終結果[5, 13, 17, 42, 46, 55, 70, 94]
===============================
第7輪排序最終結果[5, 13, 17, 42, 46, 55, 70, 94]
===============================
*/

最終版:常常採用克努特(Kunth)間隔數列來計算最佳增量。

克努特(Kunth)間隔數列:h=3h+1--->1、4、13、40、121、364...

融合到希爾排序中,即選取h=3h+1的最大取值為增量,每次不斷縮減h=(h-1)/3--->...364、121、40、13、4、1

import java.util.Arrays;

public class SortDemo04 {
    public static void main(String[] args) {
        //希爾排序
        int[] arr={46,55,13,42,17,94,5,70,15,14,2,4,13,89};
        shellSort(arr);
    }
    //希爾排序是對直接插入排序的優化,通過設定增量(步長),
    //對相同步長間隔的元素進行比較,然後不斷縮減增量,最終使增量為1,完成排序。
    //直接插入排序可以看成增量為1的希爾排序。
    private static void shellSort(int[] arr) {
        int interval=1;//通過克努特數列來計算最佳增量取值
        while(interval*3+1<=arr.length){
            interval=interval*3+1;

        }
        for (int h = interval; h > 0; h=(h-1)/3) {
            System.out.println("增量:"+h);
            for (int i = h; i < arr.length; i++) {
                int j=i;
                while(j>h-1&&arr[j]<arr[j-h]){
                    int t=arr[j-h];
                    arr[j-h]=arr[j];
                    arr[j]=t;
                    j-=h;
                    System.out.println(Arrays.toString(arr));
                }
                System.out.println("第"+(i-h+1)+"輪排序最終結果"+Arrays.toString(arr));
                System.out.println("===============================");
            }
            System.out.println("**");
            System.out.println("**");
            System.out.println("**");
            System.out.println("**");
            System.out.println("**");
        }
    }
}
/*
增量:13
**
**
**
**
**
增量:4
[17, 55, 13, 42, 46, 94, 5, 70]
第1輪排序最終結果[17, 55, 13, 42, 46, 94, 5, 70]
===============================
第2輪排序最終結果[17, 55, 13, 42, 46, 94, 5, 70]
===============================
[17, 55, 5, 42, 46, 94, 13, 70]
第3輪排序最終結果[17, 55, 5, 42, 46, 94, 13, 70]
===============================
第4輪排序最終結果[17, 55, 5, 42, 46, 94, 13, 70]
===============================
**
**
**
**
**
增量:2
[5, 55, 17, 42, 46, 94, 13, 70]
第1輪排序最終結果[5, 55, 17, 42, 46, 94, 13, 70]
===============================
[5, 42, 17, 55, 46, 94, 13, 70]
第2輪排序最終結果[5, 42, 17, 55, 46, 94, 13, 70]
===============================
第3輪排序最終結果[5, 42, 17, 55, 46, 94, 13, 70]
===============================
第4輪排序最終結果[5, 42, 17, 55, 46, 94, 13, 70]
===============================
[5, 42, 17, 55, 13, 94, 46, 70]
[5, 42, 13, 55, 17, 94, 46, 70]
第5輪排序最終結果[5, 42, 13, 55, 17, 94, 46, 70]
===============================
[5, 42, 13, 55, 17, 70, 46, 94]
第6輪排序最終結果[5, 42, 13, 55, 17, 70, 46, 94]
===============================
**
**
**
**
**
增量:1
第1輪排序最終結果[5, 42, 13, 55, 17, 70, 46, 94]
===============================
[5, 13, 42, 55, 17, 70, 46, 94]
第2輪排序最終結果[5, 13, 42, 55, 17, 70, 46, 94]
===============================
第3輪排序最終結果[5, 13, 42, 55, 17, 70, 46, 94]
===============================
[5, 13, 42, 17, 55, 70, 46, 94]
[5, 13, 17, 42, 55, 70, 46, 94]
第4輪排序最終結果[5, 13, 17, 42, 55, 70, 46, 94]
===============================
第5輪排序最終結果[5, 13, 17, 42, 55, 70, 46, 94]
===============================
[5, 13, 17, 42, 55, 46, 70, 94]
[5, 13, 17, 42, 46, 55, 70, 94]
第6輪排序最終結果[5, 13, 17, 42, 46, 55, 70, 94]
===============================
第7輪排序最終結果[5, 13, 17, 42, 46, 55, 70, 94]
===============================
*/

經測試,並不是所有的陣列最佳排序演算法都是用克努特序列,其步長的選擇有時並不一定是最佳的,但大多數是迴圈呼叫次數最少的,相比於直接插入排序,呼叫少了太多,自行測試吧

五、快速排序

​ 原理:分治法,再分割槽。

​ 1.先取一個基準數,在通過基準數來進行比較

​ 2.將比這個數大的放右邊,將比這個數小的放左邊

​ 3.不斷重複

實現:

​ 1.採用挖坑填數的思想

​ 2.先找一個基準數,一般取第一個元素

​ 3.將這個基準數挖出,從右往左,如果遇到比基準數小的,將這個數挖出放入前一個坑中,此時坑已經變了,再變換方向

​ 4.從左往右,如果遇到比基準數大的,將這個數挖出放入前一個坑中,此時坑已經變了,再變換方向到第二步,如此迴圈下去,直到坑位與上一個坑位重合,最後將基準數填入最後一個坑中

​ 5.重選基準數,直到排序完成(通過回撥的方式實現)

import java.util.Arrays;
public class SortDemo05 {
    static int flag=0;
    public static void main(String[] args) {
        //快速排序
        //1.先取一個基準數,在通過基準數來進行比較
        //2.將比這個數大的放右邊,將比這個數小的放左邊
        //3.不斷重複
        int[] arr={4,9,8,7,6,5,342,523};
        System.out.println("原始陣列"+Arrays.toString(arr));
        sort(arr,0,arr.length-1);
        System.out.println("最終排序結果"+Arrays.toString(arr));
    }
    private static void sort(int[] arr, int start, int end) {
        if (start<end){
            int index=getIndex(arr,start,end);
            sort(arr,start,index-1);
            sort(arr,index+1,end);
        }
    }
    private static int getIndex(int[] arr, int start, int end) {
        int i=start;
        int j=end;
        int x=arr[i];//基準數
        flag++;//標誌位++
        while(i<j){
            //從右往左,如果遇到比基準數小的,將這個數挖出放入前一個坑中,此時坑已經變了,再變換方向
            while(i<j&&arr[j]>=x){
                j--;//遇不到,則把j--,與前一個數繼續比較
            }
            if (i < j) {
                arr[i]=arr[j];
                System.out.println("第"+flag+"輪while1"+Arrays.toString(arr));
                i++;//從左邊的下一位開始比,因此要++
            }
            //從左往右,如果遇到比基準數大的,將這個數挖出放入前一個坑中,此時坑已經變了,再變換方向
            while(i<j&&arr[i]<x){
                i++;
            }
            if (i < j) {
                arr[j]=arr[i];
                System.out.println("第"+flag+"輪while2"+Arrays.toString(arr));
                j--;//從右邊的下一位開始比,因此要++
            }
        }
        arr[i]=x;//將基準數放到最後一個坑中
        System.out.println("第"+flag+"輪"+Arrays.toString(arr));
        System.out.println("index="+i);
        return i;//返回最終的索引,通過+1,-1來進行回撥
    }
}
/*
輸出結果:
原始陣列[4, 9, 8, 7, 6, 5, 342, 523]
第1輪[4, 9, 8, 7, 6, 5, 342, 523]
index=0
第2輪while1[4, 5, 8, 7, 6, 5, 342, 523]
第2輪[4, 5, 8, 7, 6, 9, 342, 523]
index=5
第3輪[4, 5, 8, 7, 6, 9, 342, 523]
index=1
第4輪while1[4, 5, 6, 7, 6, 9, 342, 523]
第4輪[4, 5, 6, 7, 8, 9, 342, 523]
index=4
第5輪[4, 5, 6, 7, 8, 9, 342, 523]
index=2
第6輪[4, 5, 6, 7, 8, 9, 342, 523]
index=6
最終排序結果[4, 5, 6, 7, 8, 9, 342, 523]
*/

六、歸併排序

原理:

  1. 先分成長度為1的子序列
  2. 將陣列的每個元素看成是一個有序的子序列,兩兩歸併,再兩兩歸併,直到長度與陣列長度相等,這個排序稱為2路並歸排序。

​ 先分後治:分是對半分

實現思路:

  1. 先拆分:用遞迴的方式通過取中間索引不斷的進行拆分,直到其長度為1,無法在拆分,
  2. 在拆分的最後呼叫歸併函式,因為遞迴是層層呼叫後返回到上一層,在每次拆分到最後時進行歸併,並不斷的向上歸併
  3. 歸併需要建立一個臨時陣列,用來存放歸併後的元素
import java.util.Arrays;
public class SortDemo {
    public static void main(String[] args) {
        //原始陣列
        int[] arr={10,30,2,1,0,8,7,5};
        //歸併測試陣列,從中間分開
        //int[] arr={4,5,7,8,1,2,3,6};
        //拆分
        charFen(arr,0,arr.length-1);
        //歸併測試
        //guiBing(arr,0,arr.length/2-1,arr.length-1);//3為中間索引
        System.out.println((Arrays.toString(arr)));
    }
	//是chaifen。。,打錯
    private static void charFen(int[] arr, int startIndex, int endIndex) {
        int centerIndex=(startIndex+endIndex)/2;
        if (startIndex<endIndex){
            //10,30,2,1,0,8,7,5,19,29
            charFen(arr,startIndex,centerIndex);
            charFen(arr,centerIndex+1,endIndex);
            guiBing(arr,startIndex,centerIndex,endIndex);      
        }
    }
    private static void guiBing(int[] arr, int startIndex, int centerIndex, int endIndex) {//001
        //定義一個臨時陣列,要動態的定義陣列長度,不能寫死
        int[] tempArr=new int[endIndex-startIndex+1];
        //定義左起始索引
        int i=startIndex;
        //定義右陣列起始索引
        int j=centerIndex+1;
        int index=0;//臨時陣列的起始索引
        //比較左右兩個陣列的元素大小,往臨時數組裡放
        while(i<=centerIndex && j<=endIndex){
            if (arr[i]<=arr[j]){
                 tempArr[index]=arr[i];
                 i++;
                System.out.println("1."+Arrays.toString(tempArr));
                System.out.println("---------------------------------");
            }else{
                tempArr[index]=arr[j];
                j++;
                System.out.println("2."+Arrays.toString(tempArr));
                System.out.println("---------------------------------");
            }
            index++;
        }
        //處理剩餘元素
        while(i<=centerIndex){
            tempArr[index]=arr[i];
            i++;
            index++;
            System.out.println("3."+Arrays.toString(tempArr));
            System.out.println("---------------------------------");
        }
        while(j<=endIndex){
            tempArr[index]=arr[j];
            j++;
            index++;
            System.out.println("4."+Arrays.toString(tempArr));
            System.out.println("---------------------------------");
        }
        //將臨時陣列的元素賦值到arr中
        for (int k = 0; k < tempArr.length; k++) {
            arr[k+startIndex]=tempArr[k];
        }
    }
}
//如果有3個數,剛好兩個條件的迴圈會不滿足,因為不對稱,會呼叫單個條件的迴圈如呼叫3.
/*
輸出
1.[10, 0]
---------------------------------
4.[10, 30]
---------------------------------
2.[2, 0, 0]
---------------------------------
3.[2, 10, 0]
---------------------------------
3.[2, 10, 30]
---------------------------------
2.[0, 0]
---------------------------------
3.[0, 1]
---------------------------------
2.[0, 0, 0, 0, 0]
---------------------------------
2.[0, 1, 0, 0, 0]
---------------------------------
3.[0, 1, 2, 0, 0]
---------------------------------
3.[0, 1, 2, 10, 0]
---------------------------------
3.[0, 1, 2, 10, 30]
---------------------------------
2.[7, 0]
---------------------------------
3.[7, 8]
---------------------------------
1.[5, 0]
---------------------------------
4.[5, 5]
---------------------------------
2.[5, 0, 0, 0]
---------------------------------
2.[5, 5, 0, 0]
---------------------------------
3.[5, 5, 7, 0]
---------------------------------
3.[5, 5, 7, 8]
---------------------------------
1.[0, 0, 0, 0, 0, 0, 0, 0, 0]
---------------------------------
1.[0, 1, 0, 0, 0, 0, 0, 0, 0]
---------------------------------
1.[0, 1, 2, 0, 0, 0, 0, 0, 0]
---------------------------------
2.[0, 1, 2, 5, 0, 0, 0, 0, 0]
---------------------------------
2.[0, 1, 2, 5, 5, 0, 0, 0, 0]
---------------------------------
2.[0, 1, 2, 5, 5, 7, 0, 0, 0]
---------------------------------
2.[0, 1, 2, 5, 5, 7, 8, 0, 0]
---------------------------------
3.[0, 1, 2, 5, 5, 7, 8, 10, 0]
---------------------------------
3.[0, 1, 2, 5, 5, 7, 8, 10, 30]
---------------------------------
[0, 1, 2, 5, 5, 7, 8, 10, 30]
*/

七、基數排序

   原理:通過分配再收集的方式來進行資料排序

​ 實現:假設有10個桶,按照最大數的位數來確定需要進行幾輪排序

​ 1.第一輪:按照個位數來將元素分別裝入到每個桶中,按從前往後、從上往下的方法再取出組成新的陣列

​ 2.第二輪:按照十位數來將元素分別裝入到每個桶中,按從前往後、從上往下的方法再取出組成新的陣列

​ 3.第三輪:按照百位數來將元素分別裝入到每個桶中,按從前往後、從上往下的方法再取出組成新的陣列

​ 4....不斷進行排序

圖解第一輪的實現方式:

  1. 可以假設有10個桶
  1. 每個桶中放個位數相同的數
  1. 放好之後再按桶的位置和數的位置取出來組成一個新的陣列
import java.util.Arrays;
public class SortDemo01 {
    public static void main(String[] args) {
        //基礎排序:通過分配再收集的方式進行資料的排序
        int[] arr={2,1,5,21,31,444,23,33,47,10,903,124,987,100};

        //確定排序輪次
        //獲取最大值
       // int turn= Max(arr);
        sortArray(arr);
        System.out.println(Arrays.toString(arr));
    }
    private static void sortArray(int[] arr) {
        //定義一個二維陣列,來模擬10個桶
        int[][] tempArray=new int[10][arr.length];//用arr.length來代表1級陣列的極限長度(個位數全為1時,則全加到一個一維陣列中)
        //定義一個統計陣列,用來存放每個桶存放了幾個數,預設為0
        int[] counts=new int[10];
        int max=Max(arr);
        int len=String.valueOf(max).length();//返回最大值的長度,valueof:將其他型別轉換成字串型別
        //System.out.println(len);//3,進行3次迴圈
        //迴圈輪數
        for (int i = 0,n=1; i < len; i++,n*=10) {
            //第一輪:按個位數來進行分配
            //第二輪:按十位數來進行分配
            //第三輪:按百位數來進行分配
            for (int j = 0; j < arr.length; j++) {
                //對原陣列進行遍歷
                //獲取每個位上的數字             
                int ys=arr[j]/n%10;
                //System.out.println(ys);
                tempArray[ys][counts[ys]++]=arr[j];
            }
            int index=0;//定義一個索引
            //取出桶中元素
            for (int k = 0; k < counts.length; k++) {
                if (counts[k]!=0){
                    for (int h = 0; h < counts[k]; h++) {
                        arr[index]=tempArray[k][h];
                        index++;
                    }
                    counts[k]=0;//清除上次的統計
                }
            }

        }
    }
    //獲取最大值
    private static int Max(int[] arr) {
        int max=arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (max<arr[i]){
                max=arr[i];
            }
        }
        return max;
    }
}

八、堆排序

​ 原理:將陣列按完全二叉樹的結構排列,從最後一個非葉子節點開始轉,轉成大頂堆,將根節點的元素和最後一個元素進行交換,重新轉成大頂堆,如此往復

​ 堆排序 是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序。

基本實現:

  1. 將待排序的數列構造成一個大頂堆,此時,整個序列的最大值就是堆頂的根節點。
  2. 將其與末尾元素進行交換,此時末尾就是最大值
  3. 然後剩餘n-1個元素重新構造成一人上大頂堆,這樣就會得到n個元素的次大值
  4. 反覆執行,最終可以排序為有序序列
import java.util.Arrays;
public class SortDemo02 {
    public static void main(String[] args) {
        int[] arr={1,0,6,7,2,3,4};
        //調整為大頂堆
        //toMaxHeap(arr,arr.length,1);
        //sortArray(arr,);
        //定義開始調整的位置
        int startIndex=(arr.length-1)/2;
        //迴圈開始調
        for (int i=startIndex;i>=0;i--){
            toMaxHeap(arr,arr.length,i);
        }

        //以上已完成大頂堆的操作,接下來需要把根元素和最後一個元素進行調換
        for (int i = arr.length-1; i >0 ; i--) {
            //調換
            int t=arr[0];
            arr[0]=arr[i];
            arr[i]=t;
            //換完之後,再把剩餘元素調成大頂堆
            toMaxHeap(arr,i,0);
        }
        System.out.println(Arrays.toString(arr));
    }
    /**
     *
     * @param arr 要排序的陣列
     * @param size  調整元素的個數
     * @param index 從哪裡開始調整
     */
    private static void toMaxHeap(int[] arr, int size, int index) {
        //獲取左右子節點的索引
        int leftNodeIndex=index*2+1;
        int rightNodeIndex=index*2+2;
        //查詢最大節點所對應的索引
        int maxIndex=index;
        if (leftNodeIndex<size  &&  arr[leftNodeIndex]>arr[maxIndex]){
            maxIndex=leftNodeIndex;
        }
        if (rightNodeIndex<size &&  arr[rightNodeIndex]>arr[maxIndex]){
            maxIndex=rightNodeIndex;
        }
        //調換位置,最大值節點索引變了,則說明需要進行交換
        if (maxIndex!=index){
            int t=arr[maxIndex];
            arr[maxIndex]=arr[index];
            arr[index]=t;
            //考慮到對後面的影響,需要重新進行大頂堆的構造
            toMaxHeap(arr,size,maxIndex);
        }
        System.out.println(Arrays.toString(arr));
    }
}