快速排序:选择一个基数,分别从数组的左边和右边与基数比较,大的放在基数的右边,小的放在基数左边。然后,再在基数的左右选择基数排序直至最后数组排序好。快速排序右两种实现:占坑法和互换法。
占坑法:
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);
}
}
}