算法__快速排序

快速排序:選擇一個基數,分別從數組的左邊和右邊與基數比較,大的放在基數的右邊,小的放在基數左邊。然後,再在基數的左右選擇基數排序直至最後數組排序好。快速排序右兩種實現:佔坑法互換法

佔坑法:

4 7 3 5 2 6 1 8

選擇基數(我們一般選擇第一個數位基數)  pivote=4,兩個指針 left =>4,right =>8。

            1. 8和4比較,8比4大,不交換,right指針左移   right =>1;

            2. 1和4比較,1比4小,數組的座標0等於1,left右移 left =>7,pivote=4;

1 7 3 5 2 6 1 8

            3. left指向了7,7和4比較,7比4大,數組是right等於7,right左移;

1 7 3 5 2 6 7 8

            4. right指向6,6和4比較,6大於4,right左移;

            5. right指向2,2和4比較,2小於4,2就賦值到left的指向位置,left右移;

1 2 3 5 2 6 7 8

            6. left指向的3,3和4比較,3小於4,left右移;

            7. left指向的5,5和4比較,5大於4,right指向的位置被賦值爲5,right左移;

1 2 3 5 5 6 7 8

            8. right左移後,left==right,將left指向的位置賦值基數(pivote)爲4;

1 2 3 4 5 6 7 8

 哈哈哈!例子沒有選擇好,一輪排好序了。不過第二輪,會在把數組從4分開。分別以1和5作爲基數,將兩個數組排序。直至數   組不能再分。

  

    public void QuckSort(int array[], int startIndex, int endIndex) {
        if (startIndex >= endIndex)
            return;

        int provite = quckSort(array, startIndex, endIndex);
        QuckSort(array, startIndex, provite - 1);
        QuckSort(array, provite + 1, endIndex);
    }

    //挖坑法
    private int quckSort(int arry[], int startIndex, int endIndex) {
        int provite = arry[startIndex];
        int leftIndex = startIndex, rightIndex = endIndex;

        while (leftIndex < rightIndex) {

            while (leftIndex < rightIndex) {
                if (arry[rightIndex] < provite) {
                    arry[leftIndex] = arry[rightIndex];
                    leftIndex++;
                    break;
                }
                rightIndex--;
            }

            while (leftIndex < rightIndex) {
                if (arry[leftIndex] > provite) {
                    arry[rightIndex] = arry[leftIndex];
                    rightIndex--;
                    break;
                }
                leftIndex++;
            }
        }

        arry[leftIndex] = provite;
        return leftIndex;
   }

互換法:從數組的右邊的指針向左移動,選擇比基數小的數字,左邊的指針向右選擇比基數大的數字,然後兩個數互換。直到左右指針相等的時候,將指針指的數和基數互換。然後,從基數兩邊分成兩個數組,再交換。

4 6 3 8 1 2 7 5

1. left 指向 6,right指向 5,5比4大,right左移;

2. right 指向 7,7比4大,right左移;

3. right 指向 2,然後找left;

4. left 指向 6,6大於4,left和right指向的值互換

4 2 3 8 1 6 7 5

5. right 左移指向 1 ,1比4小,找left的值;

6. left指向 3,3比4小,left右移;

7. left指向 8,8比4大,8和1互換;1

4 2 3 1 8 6 7 5

8. right右移 right==left; 4和1交換;

1 2 3 4 8 6 7 5

9. 從4的左右分爲兩個數組,選擇1和8爲基數,繼續交換。

    public void QuckSort(int array[], int startIndex, int endIndex) {
        if (startIndex >= endIndex)
            return;

        int provite = parent(array, startIndex, endIndex);
        QuckSort(array, startIndex, provite - 1);
        QuckSort(array, provite + 1, endIndex);
    }

    //交換法
    private int parent(int arry[], int startIndex, int endIndex) {
        int privote = arry[startIndex];
        int leftIndex = startIndex, rightIndex = endIndex;

        while (leftIndex != rightIndex) {

            while (leftIndex < rightIndex && arry[rightIndex] > privote)
                rightIndex--;
            while (leftIndex < rightIndex && arry[leftIndex] <= privote)
                leftIndex++;

            if (leftIndex < rightIndex) {
                arry[leftIndex] ^= arry[rightIndex];
                arry[rightIndex] ^= arry[leftIndex];
                arry[leftIndex] ^= arry[rightIndex];
            }
        }

        arry[leftIndex] ^= arry[startIndex];
        arry[startIndex] ^= arry[leftIndex];
        arry[leftIndex] ^= arry[startIndex];
        return leftIndex;
    }

這兩個方法都是用遞歸實現了快速排序。一般,我們的遞歸可以用棧來實現。

 

棧的實現:

private void StackSort(int arry[], int startIndex, int endIndex) {
        Stack<Map<String, Integer>> stacks = new Stack<Map<String, Integer>>();
        Map maps = new HashMap();
        maps.put("startIndex", startIndex);
        maps.put("endIndex", endIndex);
        stacks.push(maps);

        while (!stacks.isEmpty()) {
            Map<String, Integer> map = stacks.pop();
            int provite = parent(arry, map.get("startIndex"), map.get("endIndex"));
            if (map.get("startIndex") < provite - 1) {
                Map<String, Integer> map1 = new HashMap();
                map1.put("startIndex", map.get("startIndex"));
                map1.put("endIndex", provite - 1);
                stacks.push(map1);
            }

            if (map.get("endIndex") > provite + 1) {
                Map<String, Integer> map1 = new HashMap();
                map1.put("startIndex", provite + 1);
                map1.put("endIndex", map.get("endIndex"));
                stacks.push(map1);
            }
        }
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章