快速排序的两种具体实现方式
- 单方向遍历(从小到大)
- 从左到右单方向遍历
- 按照排列,在遇到比pivot大的数之前,小于pivot的保留当前的位置;遇到之后,小于pivot的数会与大于pivot的数进行交换
- 如数组{47,29,20,71,99,78,19,24,48}在进行第一次交换后,变为{47,29,20,19,24,78,71,99,48}
- 然后再将pivot与此时index处的数进行交换,得到{24,29,20,19,47,78,71,99,48},满足47之前的数字都比47小,47后的数字都比47大
public void quickSort1(int[] arr,int low,int high){
int pivot,index,i,temp;
if (low < high){
index = low;
pivot = arr[index];
for (i = low + 1;i <= high;i ++){
if (arr[i] <= pivot){
index ++;
temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
}
}
temp = arr[low];
arr[low] = arr[index];
arr[index] = temp;
quickSort2(arr,low,index - 1);
quickSort2(arr,index + 1,high);
}
}
- 双向遍历,双指针(从小到大)
- 分别有从左到右的指针l,与从右到左的指针r,在遇到比piovt大的数(比pivot小的数)之前分别递增(递减)
- 相遇时进行交换
- 然后与单方向遍历类似,交换pivot与arr[r]
- 尤其要注意递归时的判断条件,否则会出现下标越界异常
- 循环中对于arr[r]>=pivot与arr[l]<=pivot的先后顺序,影响后面是交换pivot与arr[r],还是交换pivot与arr[l]
public void quickSort2(int[] arr,int low,int high){
int pivot = arr[low];
int l = low;
int r = high;
int temp;
while(l < r){
while(l < r && arr[r] >= pivot){
r --;
}
while(l < r && arr[l] <= pivot){
l ++;
}
if (l < r){
temp = arr[r];
arr[r] = arr[l];
arr[l] = temp;
}
}
temp = arr[r];
arr[r] = arr[low];
arr[low] = temp;
if(low < r - 1){
quickSort3(arr,low,r - 1);
}
if (r + 1 < high){
quickSort3(arr,r + 1,high);
}
}