1. 程式人生 > >Java中常用的排序演算法(動態演示)

Java中常用的排序演算法(動態演示)

1.前言

  • 這篇文章講解的是Java中或者面試中常用的**排序演算法**。
  • 文章中例項  [linhaojian的Github](https://github.com/linhaojian

2.複雜度

複雜度.png

  • 相關概率

穩定:如果a原本在b前面,而a=b,排序之後a仍然在b的前面。
不穩定:如果a原本在b的前面,而a=b,排序之後 a 可能會出現在 b 的後面。
時間複雜度:對排序資料的總的操作次數。反映當n變化時,操作次數呈現什麼規律。
O(N) :  for(int i=0;i<10:i++){};
O(N*N) :  for(int i=0;i<10:i++){for(int i=0;i<10:i++){}};
O(log2n) :  就是將迴圈次數/2;
O(nlog2n) :  就是迴圈資料的次數1分為2;
空間複雜度:是指演算法在計算機內執行時所需儲存空間的度量,它也是資料規模n的函式。


3.排序演算法

3.1 冒泡

  • 描述:
    1.比較集合相鄰2個元素,如果前者大於後者交換他們的位置。這一點會得出最大的元素 & 放置在集合最後
    2.持續對剩下的元素進行1的操作。
  • 演示:
    氣泡排序.gif
  • 程式碼:
 public static void bubbleSort(int[] numbers)
    {
        int temp = 0;
        int size = numbers.length;
        for(int i = 0 ; i < size-1; i ++)
        {
            for
(int j = 0 ;j < size-1-i ; j++) { if(numbers[j] > numbers[j+1]) //交換兩數位置 { temp = numbers[j]; numbers[j] = numbers[j+1]; numbers[j+1] = temp; // System.out.println(Arrays.toString(numbers));
} } // System.out.println("------------"); } }

3.2 選擇

  • 描述:
    1.在未排序序列中找到最小元素存放到排序序列的起始位置
    2.再從剩餘未排序元素中繼續尋找最小元素,然後放到排序序列起始位置。
    3.以此類推,直到所有元素均排序完畢。
  • 演示:
    選擇排序.gif
  • 程式碼:
    public static void selectSort(int[] numbers) {
        int size = numbers.length;
        int temp;
        //從零開始向後遍歷集合
        for (int i = 0; i < size; i++) {
            //將 i 賦值給k
            int k = i;
            //從集合最後一位開始向前遍歷
            for (int j = size - 1; j>i; j--)  {
                //記錄比較之後值小的位置
                if (numbers[j] < numbers[k]) {
                    k = j;
                }
            }
            // 將找出最小值與i位置的值互動,把最小值放置在集合最前
            temp = numbers[i];
            numbers[i] = numbers[k];
            numbers[k] = temp;
//            System.out.println(Arrays.toString(array));
        }
    }

3.3 插入

  • 描述:
    1.從第一個元素開始,該元素可以認為已經被排序;
    2.取出下一個元素,在已經排序的元素序列中從後向前掃描
    3.如果該元素(已排序)大於新元素,將該元素移到下一位置;
    4.重複步驟3,直到找到已排序的元素小於或者等於新元素的位置;
    5.將新元素插入到該位置後
    6.重複步驟2~5。
  • 演示:
    插入排序.gif
  • 程式碼:
private static void insertSort(int[] numbers) {
        //從1開始遞增的遍歷資料
        for (int i = 1; i < numbers.length; i++) {
            // 將 i 對應的值 賦予給 temp
            int temp = numbers[i];
            int j;
            // 從 i-1 開始遞減的遍歷
            for (j = i - 1; j >= 0; j--) {
                //判斷temp 是否小於當前j位置的值
                if (temp < numbers[j]) {
                    numbers[j + 1] = numbers[j];
                    System.out.println(Arrays.toString(numbers));
                } else {
                    break;
                }
            }
            numbers[j + 1] = temp;
            System.out.println(j+"  "+Arrays.toString(numbers));
        }
    }

3.4 快速

  • 描述:1.從數列中挑出一個元素,稱為 “基準”(pivot);
                 2.重新排序數列,所有元素比基準值小的擺放在基準前面所有元素比基準值大的擺在基準的後面(相同的數可以到任一 邊)。在這個分割槽退出之後,該基準就處於數列的中間位置。這個稱為分割槽(partition)操作;
                 3**.遞迴地**(recursive)把小於基準值元素的子數列大於基準值元素的子數列排序
    快速排序.gif
  • 程式碼:
    public static void quickSortHelp(int[] arr) {
        arr = new int[]{5,3,2,1,4,8,7,9};
        quickSort(arr,0, arr.length-1);
    }
    public static void quickSort(int[] arr,int low, int high) {
        if(low<high) {
            int partition = partition(arr,low,high);
            System.out.println("partition : "+partition+"  low : "+low+"  high : "+high+"  arr : "+Arrays.toString(arr));
            quickSort(arr,low, partition-1);
            quickSort(arr,partition+1, high);
        }
    }
    public static int partition(int[] arr,int low,int high) {
        int base = arr[low]; //用子表的第一個記錄做樞軸(分水嶺)記錄
        System.out.println("base : "+base);
        while(low<high) {
            while(arr[high]>=base&&low<high){
                high--;
            }
            Swap(arr,high,low);
            System.out.println("[high:"+high+"] "+Arrays.toString(arr));
            while(arr[low]<=base&&low<high) {
                low++;
            }
            Swap(arr,high,low);
            System.out.println("[low:"+low+"] "+Arrays.toString(arr));
        }
        System.out.println(Arrays.toString(arr));
        System.out.println("----------------------------");
        return low;
    }
    public static void Swap(int[] arr,int high,int low) {
        int temp = arr[low];
        arr[low] =arr[high];
        arr[high] = temp;
    }

4.總結

  • 到此,常用的**排序演算法**講解完畢。
  • 如果喜歡我的分享,可以點選  關注  或者  ,你們支援是我分享的最大動力 。
    linhaojian的Github

歡迎關注linhaojian_CSDN部落格或者linhaojian_簡書

不定期分享關於安卓開發的乾貨。


寫技術文章初心

  • 技術知識積累
  • 技術知識鞏固
  • 技術知識分享
  • 技術知識交流