快速排序(Java版)
听名字就很diao,直接上干货。
快排一定要思路清晰,没事多写几遍,要不容易忘。这个程序是从小到大排序!!!
对于一个数组对它进行排序,快排的思想就是交换交换再交换,我们先选择一个支点 int pivot,这个支点的作用是,我们要将一个什么都不是的数组,经过第一遍快排,以这个支点就是数组中的某一个元素(一般以数组的第一个元素选择为支点)为分界线,这个支点的左边都比它小,右边都比它大,于是我们的数组经过第一遍快排,分为了三部分,比支点小的数----支点----比支点大的数。实现的方法就是元素之间进行交换
这是一个没排序的数组,我们选取4为支点(一般都选取数组的第一个元素),必不可少的还有左右边界的元素的下标,因为交换肯定要知道至少两个元素的下标,我们先把4和right指向的元素进行比较,4<6,我们从小到大排序,所以不用交换,因为大的数肯定在右边。所以right–,向下走看看有没有比4小的。得到下面的图:
此时我们发现4<5,所以right–。得到下图:
到这一步我们发现4>2,按照快排的规则,我们交换两个数,因为小的数一定要在支点的左边。于是得到下图:
我们交换结束后,此时注意,轮到left指针了,left指向2,2<4,满足小的数在支点的左边,所以left++,去寻找比支点大的数进行交换,得到下图:
1<4,满足条件,所以left++寻找比支点大的数,得到下图:
3<4,满足条件,所以left++寻找比支点大的数,得到下图:
到这一步,8>4,所以8应该去支点的右边,得到下图:
此时,又该right指针移动,8>4,满足条件,所以right–,得到下图:
此时7>4也满足条件,所以right–,得到下图:
这就是循环终止的条件,left==right,此时我们可以发现,在支点4的左边,全部比4小,右边比4大,所以这就是快排的一趟,主要是把数组分开,那么下一步该怎么做呢,其实可以用递归,这时候,4左边的数可以构成一个数组,右边也可以构成一个数组,对这两边的内容再进行上面的步骤,最后呈现出来的,就是从小到大的完整数组,如下图:
到这里就不继续向下说了,就是把上面的流程又走一遍。
总结一下就是,选取第一个元素作为支点,从right指向的值与支点比较,如果支点的值小于right指向的值,right–,直到遇到支点的值大于right指向的值,那么交换right的值和privot的值,一旦一交换,立刻开始比较left与支点的值,left比支点小,left++,否则交换,然后再用right的值与支点比较…一旦交换元素,就要切换比较的对象,right变left,left变right…
直接上代码
递归
/**
*
* @author Coding6
* 快速排序递归
*/
public class QuickSortDemo {
public void sort(int []arr, int left, int right) {
int privot;
if(left<right) {
privot = QuickSort(arr, left, right);
sort(arr, left, privot-1);
sort(arr, privot+1, right);
}
}
public int QuickSort(int []arr, int left, int right) {
int pivot = arr[left];
while(left < right){
while(left < right && pivot >= arr[right]){
right--;
}
arr[left] = arr[right];
while(left < right && pivot <= arr[left]){
left++;
}
arr[right] = arr[left];
}
arr[left] = pivot;
return left;
}
public static void main(String[] args) {
QuickSortDemo q = new QuickSortDemo();
int arr[] = {5,3,6,7,2,4,1,32,67,10,45};
q.sort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
QuickSort函数,表示的就是一趟的快排
非递归
用到栈
import java.util.Stack;
/**
* @author Coding6
* 快速排序非递归
*/
public class QuickSortStack {
public void sort(int []arr, int left, int right) {
int privot, top, last;
Stack<Integer> s = new Stack<Integer>();
last=0;
top=0;
privot=QuickSort(arr, left, right);
if(privot>left+1) {
s.push(left);
s.push(privot-1);
}
if(privot<right-1) {
s.push(privot+1);
s.push(right);
}
while(!s.empty()) {
top = s.pop();
last = s.pop();
privot = QuickSort(arr, last, top);
if(privot>last+1) {
s.push(last);
s.push(privot-1);
}
if(privot<top-1) {
//System.out.println(top);
s.push(privot+1);
s.push(top);
}
}
}
public int QuickSort(int []arr, int left, int right) {
int privot = left;
while(left<right) {
while((arr[privot]<=arr[right])&left<right) {
right--;
}
int temp = arr[privot];
arr[privot] = arr[right];
arr[right] = temp;
privot = right;
while((arr[privot]>=arr[left])&left<right) {
left++;
}
temp = arr[privot];
arr[privot] = arr[left];
arr[left] = temp;
privot = left;
}
return privot;
}
public static void main(String[] args) {
QuickSortStack q = new QuickSortStack();
int arr[] = {5,3,6,7,2,4,1,32,67,10,45};
q.sort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}