摘要:快速排序是冒泡排序的一种改进;在冒泡排序中,元素的比较和交换是在相邻元素之间进行的,元素每次交换只能移动一个位置,所以比较和移动的次数多,效率低;然而,在快速排序中,是先选择基准元素,元素的比较和交换是从两边向中间进行的,将右边小于基准元素的值往左移,左边大于基准元素的值往右移,所以每一躺都可确定基准元素的位置;进行多次这样的排序就可得到有序的结果;这样的比较和交换次数都大大减小,效率相对更高;
代码:
核心代码的实现,选择基准元素,左右两指针向中间扫描,注意如果基元素从左边选取的,那么扫描时从右边开始,这里考虑的是保证最后一次循环能正确;
// 单躺排序函数
function test(arr, left, right) {
let key = left; //取基准元素
while (left < right) {
while (left < right && arr[right] >= arr[key]) right--; //从右边开始定位小于key的元素
while (left < right && arr[left] <= arr[key]) left++; //从左边开始定位大于key的元素
swap(arr,left,right);
}
//当左右指针重合时,交换key值和重合指针标记位置的元素
swap(arr,key,left)
return left;
}
//交换函数
function swap(arr,i,j){
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
以上代码可以进行第一次排序:
保证基准元素key左边的值都小于基准元素key
保证基准元素key右边的值都大于基准元素key
代码:
演示单次排序过程,基准元素选择4,最终结果为:4左边的元素都小于4,4右边的元素都大于4;
const arr = [4, 1, 6, 5, 7, 2, 3]
// 单躺排序函数
function test(arr, left, right) {
let key = left; //取基准元素
while (left < right) {
while (left < right && arr[right] >= arr[key]) right--; //从右边开始定位小于key的元素
while (left < right && arr[left] <= arr[key]) left++; //从左边开始定位大于key的元素
swap(arr,left,right);
//打印交换过程
console.log(arr)
}
//当左右指针重合时,交换key值和重合指针标记位置的元素
swap(arr,key,left)
return left;
}
//交换函数
function swap(arr,i,j){
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
test(arr,0,arr.length-1)
console.log(arr)
为了实现完整排序,需对左边和右边分别进行排,划分数组后递归调用即可,完整代码:
// 单躺排序函数
function test(arr, left, right) {
let key = left; //取基准元素
while (left < right) {
while (left < right && arr[right] >= arr[key]) right--; //从右边开始定位小于key的元素
while (left < right && arr[left] <= arr[key]) left++; //从左边开始定位大于key的元素
swap(arr,left,right);
//打印交换过程
console.log(arr)
}
//当左右指针重合时,交换key值和重合指针标记位置的元素
swap(arr,key,left)
return left;
}
//交换函数
function swap(arr,i,j){
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function quickSort(arr,left,right){
if(left>=right)return
let key = test(arr, left, right);
quickSort(arr,left,key-1);
quickSort(arr,key+1,right);
}
//排序主程序
const arr = [4, 1, 6, 5, 7, 2, 3]
quickSort(arr,0,arr.length-1);
console.log(arr)
完整排序过程: