1. 程式人生 > >kotlin 基本排序演算法(冒泡、快排、二分....)與java對比

kotlin 基本排序演算法(冒泡、快排、二分....)與java對比

先還是把這個大神的引用地址貼上,要用到圖片 搞懂基本排序演算法 

基本演算法不管是哪種程式都會涉及,只是android用的比較少,很容易忘記,所以能掌握幾種是幾種吧!然而java和kotlin的寫法稍微有點出入。

先來看圖:

懂得理論的話,仔細看還是能看的明白的

1.第一個與第二個比較,那個大就排著後面,或者小就往後排。

2.看上面的解釋是當第一次比較完後,最後的一個是裡面最大的,這裡思維還是有點難理解,但是多想幾次就能明白,比如:第一和第二個比較,第一個大,肯定互換位置到變成第二個,然後第二個與第三個比較,如果還是第二大,互換位置,加入第二個是裡面資料最大的,肯定會被換都最後一個位置直到沒有,所以最後一個最大了。

3.每次排序最後一個最大所以就不用比了,直到沒有比的為止。

冒泡java寫法;

/**
 * @param arr 待排序陣列
 * @param n   陣列長度 arr.length 
 */
 private static void BubbleSort(int[] arr, int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 1; j < n - i; j++) {
            if (arr[j - 1] > arr[j]) {
                //交換兩個元素
                int temp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = temp;
            }
        }
    }
 }

現在已經是用kotlin寫了,然後寫的時候有點犯糊塗,不知道怎麼寫了,有點尷尬了,還是隻有百度,沒想到還真有,隨便附上

也測試過了,然後kotlin的寫法更加簡單,容易比較理解,個人覺得比java寫法理解起來容易

fun bub(arr:IntArray){
        var out = 0
        var inIndex = 0
        var temp = 0
        while (out < arr.size){
            inIndex = out +1
            while (inIndex < arr.size){
                if (arr[out] > arr[inIndex]){
                    temp = arr[out]
                    arr[out] = arr[inIndex]
                    arr[inIndex] = temp
                }
                inIndex++
            }
            out++
        }

    }

後面的直接上程式碼了,我也沒有弄得好懂,如果要看解釋,就看上面的那個網址

這裡講了快排分幾種,單路、雙路、三路

單路

 private static void quickSort(int[] arr, int l, int r) {

        if (l >= r) {
            return;
        }
        // p 為 第一次 排序完成後 v 應該在的位置,即分治的劃分點
        int p = partition(arr, l, r);

        quickSort(arr, l, p - 1);
        quickSort(arr, p + 1, r);
    }

    private static int partition(Integer[] arr, int l, int r) {

        // 為了提高效率,減少造成快速排序的遞迴樹不均勻的概率,
        // 對於一個數組,每次隨機選擇的數為當前 partition 操作中最小最大元素的可能性為 1/n 
        int randomNum = (int) (Math.random() * (r - l + 1) + l);
        swap(arr, l, randomNum);

        int v = arr[l];
        int j = l;

        for (int i = l + 1; i <= r; i++) {
            if (arr[i] < v) {
                swap(arr, j + 1, i);
                j++;
            }
        }
        swap(arr, l, j);
        return j;
    }

    private static void swap( int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

雙路

 private static void quickSort(int[] arr, int l, int r) {

        if (l >= r) {
            return;
        }
        // 這裡 p 為 小於 v 的最後一個元素,=v 的第一個元素 
        int p = partition(arr, l, r);

        quickSort(arr, l, p - 1);
        quickSort(arr, p + 1, r);
    }


    private static int partition(int[] arr, int l, int r) {
        // 為了提高效率,減少造成快速排序的遞迴樹不均勻的概率,
        // 對於一個數組,每次隨機選擇的數為當前 partition 操作中最小最大元素的可能性降低

        int randomNum = (int) (Math.random() * (r - l + 1) + l);
        swap(arr, l, randomNum);

        int v = arr[l];

        int i = l + 1;
        int j = r;

        while (true) {

            while (i <= r && arr[i] <= v) i++;
            while (j >= l + 1 && arr[j] >= v) j--;

            if (i > j) break;

            swap(arr, i, j);
            i++;
            j--;
        }
        //j 最後角標停留在 i > j 即為 比 v 小的最後一個一元素位置
        swap(arr, l, j);

        return j;
    }

三路


 private static void quickSort3(int[] num, int length) {
        quickSort(num, 0, length - 1);
    }

    private static void quickSort(int[] arr, int l, int r) {

        if (l >= r) {
            return;
        }

        // 為了提高效率,減少造成快速排序的遞迴樹不均勻的概率,
        // 對於一個數組,每次隨機選擇的數為當前 partition 操作中最小最大元素的可能性 降低 1/n!

        int randomNum = (int) (Math.random() * (r - l + 1) + l);
        swap(arr, l, randomNum);

        int v = arr[l];
        // 三路快速排序即把陣列劃分為大於 小於 等於 三部分
        //arr[l+1...lt] <v  arr[lt+1..i) =v  arr[gt...r] > v 三部分
        // 定義初始值得時候依舊可以保證這初始的時候這三部分都為空
        int lt = l;
        int gt = r;
        int i = l + 1;

        while (i < gt) {
            if (arr[i] < v) {
                swap(arr, i, lt + 1);
                i++;
                lt++;
            } else if (arr[i] == v) {
                i++;
            } else {
                swap(arr, i, gt - 1);
                gt--;
                //i++ 注意這裡 i 不需要加1 因為這次交換後 i 的值仍不等於 v 可能小於 v 也可能等於 v 所以交換完成後 i 的角標不變
            }
        }
        //迴圈結束的後 lt 所處的位置為 <v 的最後一個元素 i 肯定與 gt 重合
        //但是 最終v 要放的位置並不是 i 所指的位置 因為此時 i 為大於 v 的第一個元素 v
        //而 v 應該處的位置為 lt 位置 並不是 i-1 所處的位置(arr[i-1] = arr[l])
        swap(arr, l, lt);
    }

kotlin 

private fun quickSort(arrs: IntArray, lowStart: Int, highEnd: Int) {
       var low: Int = lowStart
       var high: Int = highEnd
       var povit: Int = arrs[low]
 
       while (low < high) {
           while (low < high && arrs[high] >= povit) {
               high--
           }
           if (low < high) {
               var temp: Int = arrs[high]
               arrs[high] = arrs[low]
               arrs[low] = temp
               low++
           }
           while (low < high && arrs[low] <= povit) {
               low++
           }
           if (low < high) {
               var temp: Int = arrs[high]
               arrs[high] = arrs[low]
               arrs[low] = temp
               high--
           }
       }
       if (low > lowStart) quickSort(arrs, lowStart, low - 1)
       if (high < highEnd) quickSort(arrs, low + 1, highEnd)
   }

選擇排序

public static void sort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n; i++) {
            int minIndex = i;
            // for 迴圈 i 之後所有的數字 找到剩餘陣列中最小值得索引
            for (int j = i + 1; j < n; j++) {
                if (arr[j]< arr[minIndex]) {
                    minIndex = j;
                }
            }
            swap(arr, i, minIndex);
        }
    }

    /**
     * 角標的形式 交換元素
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
private fun selectSort(arrs: IntArray) {
       var outIndex: Int = 0
       var inIndex: Int = 0
       var minIndex: Int = 0
       while (outIndex < arrs.size - 1) {
           inIndex = outIndex + 1
           minIndex = outIndex
           while (inIndex < arrs.size) {
               if (arrs[minIndex] > arrs[inIndex]) {
                   minIndex = inIndex
               }
               inIndex++
           }
           if (minIndex != outIndex) {
               var temp: Int = arrs[outIndex]
               arrs[outIndex] = arrs[minIndex]
               arrs[minIndex] = temp
           }
           outIndex++
       }
   }