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