快速排序的思想:
快速排序首先在数组中确定1个枢纽项(比如数组中的第一个元素),将大于该枢纽项的元素放到右侧,小于该枢纽项的元素放到左侧,这样枢纽项将数组划分成两部分。接着继续对划分之后的子数组继续划分,依次类推,直到子数组为1个有序的数组为止。
划分实现思路:
1、枢纽定义为最左侧的位置,j表示枢纽应该指向的位置,i指向当前要和枢纽比较的元素。
2、第1次循环:比较2<5,此时成立,比枢纽5小的元素新增了一个,j++。如果i和j不相等,这时需要交换i位置和j位置的元素。此次循环后的结果如下
2、第2次循环:比较8<5,此时不成立,i++,此次循环后的结果如下
3、第3次循环:比较 3<5 ,此时成立,那么j++,交换8和3的位置。i++, 此次循环后的结果如下
依次循环,直到i指向最后一个元素,循环结束,这时候要将枢纽5与j指向的元素进行交换位置,这样就将一个数组划分成了大于枢纽5和小于枢纽5的两部分。
划分代码:
/**
* 对arr[left...right]部分进行partition操作返回p,使得arr[left...p-1] < arr[p];
* arr[p+1...right] > arr[p]
* @param arr 数组
* @param left 左侧的索引
* @param right 右侧的索引
* @return
*/
int __partition(int arr[], int left, int right) {
int v = arr[left];//枢纽设置成最左侧的元素
//arr[left+1...j] < v ; arr[j+1...i) > v
int j = left;//j表示枢纽应该指向的位置
for (int i = left + 1; i <= right; i++){
if (arr[i] < v) {
j++;//如果arr[i]比枢纽小,这时比v小的元素新增了一个,此时j要向右移动1位
if (i != j)//如果i和j不相等,需要交换i位置和j位置的元素
swap(arr, j, i);//交换两个元素
}
}
//循环结束后,需要将枢纽v放到j的位置上
swap(arr, left, j);
return j;
}
快速排序代码:
/**
* 递归实现快速排序
* @param arr
* @param left
* @param right
*/
void __quickSort(int arr[], int left, int right){
if( left >= right )//递归的终止条件,只剩下1个元素
return;
int p = __partition(arr, left, right);//划分
__quickSort(arr, left, p-1 );//对左侧的数据继续划分
__quickSort(arr, p+1, right);//对右侧的数据继续划分
}