feat: 添加快速排序
This commit is contained in:
parent
86efe8d7b2
commit
7ff6821d63
150
sort/quick-sort.mjs
Normal file
150
sort/quick-sort.mjs
Normal file
@ -0,0 +1,150 @@
|
||||
import { swap } from "../util/index.mjs"
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number[]} arr
|
||||
*/
|
||||
export function quickSort(arr) {
|
||||
function QuickSort(arr, left, right) {
|
||||
if (left < right) {
|
||||
let index = partition(arr, left, right)
|
||||
QuickSort(arr, left, index-1) // index是中心轴无需参与排序,若写成index会造成堆栈益处
|
||||
QuickSort(arr, index+1, right)
|
||||
}
|
||||
}
|
||||
QuickSort(arr,0, arr.length - 1)
|
||||
return arr
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description 使用左右指针法来分数组
|
||||
* @param {number[]} arr - 需要分治的函数
|
||||
* @param {number} left - 开始的位置
|
||||
* @param {number} right - 结束的位置
|
||||
*/
|
||||
function partition(arr, left, right) {
|
||||
let pivot = arr[right] // 以right作为pivot
|
||||
let pivotIndex = right
|
||||
|
||||
while (left < right) {
|
||||
// left开始往右边找比pivot大的值
|
||||
while (left < right && arr[left] <= pivot) {
|
||||
left++
|
||||
}
|
||||
// right开始往左边找比pivot小的值
|
||||
while (left < right && arr[right] >= pivot) {
|
||||
right--
|
||||
}
|
||||
swap(arr, left, right)
|
||||
}
|
||||
swap(arr, left, pivotIndex)
|
||||
return left
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number[]} arr - 需要快速排序的数组
|
||||
*/
|
||||
export function quickSort2(arr){
|
||||
function QuickSort(arr, left, right) {
|
||||
if (left < right) {
|
||||
const pivot = partition2(arr, left, right)
|
||||
QuickSort(arr,left,pivot -1)
|
||||
QuickSort(arr, pivot+1, right)
|
||||
}
|
||||
}
|
||||
QuickSort(arr,0, arr.length-1)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 使用挖坑法来分数组
|
||||
* @param {number[]} arr - 需要分解的数组
|
||||
* @param {number} left - 开始的位置
|
||||
* @param {number} right - 结束的位置
|
||||
*/
|
||||
function partition2(arr, left, right){
|
||||
let pivot = arr[right]
|
||||
while(left < right) {
|
||||
while(left<right && arr[left] <= pivot) {
|
||||
left++
|
||||
}
|
||||
arr[right] = arr[left]
|
||||
while(left<right && arr[right] >= pivot) {
|
||||
right--
|
||||
}
|
||||
arr[left] = arr[right]
|
||||
}
|
||||
arr[left] = pivot
|
||||
return left
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 使用前后指针法分数组
|
||||
* @param {number[]} arr - 需要排序的数组
|
||||
*/
|
||||
export function quickSort3(arr) {
|
||||
function QuickSort(arr, left, right) {
|
||||
if(left < right){
|
||||
const pivot = partition4(arr, left, right)
|
||||
QuickSort(arr, left, pivot-1)
|
||||
QuickSort(arr, pivot+1, right)
|
||||
}
|
||||
}
|
||||
QuickSort(arr, 0, arr.length -1)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 使用前后指针法
|
||||
* @param {number[]} arr
|
||||
* @param {number} left - 开始的位置
|
||||
* @param {number} right - 结束的位置
|
||||
*/
|
||||
function partition3(arr, left, right){
|
||||
let cur = left
|
||||
let pre = left - 1
|
||||
const pivot = arr[right] // 选取最后一个元素作为中枢
|
||||
while(cur < right) {
|
||||
if(arr[cur]< pivot) {
|
||||
swap(arr, cur, ++pre)
|
||||
}
|
||||
cur++
|
||||
}
|
||||
/*
|
||||
循环结束之后pre所处的元素之前都是小于pivot(包含pre),右侧的元素都是大于或等于pivot的,交换cur+1和pviot的值
|
||||
*/
|
||||
swap(arr, pre +1, right)
|
||||
return pre + 1
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 使用前后指针法(优化版)
|
||||
* @param {number[]} arr
|
||||
* @param {number} left - 开始的位置
|
||||
* @param {number} right - 结束的位置
|
||||
*/
|
||||
function partition4(arr, left, right){
|
||||
let cur = left
|
||||
let pre = left - 1
|
||||
const pivot = arr[right] // 选取最后一个元素作为中枢
|
||||
while(cur < right) {
|
||||
if(arr[cur] < pivot && ++pre != cur) {
|
||||
swap(arr, pre, cur)
|
||||
}
|
||||
cur++
|
||||
}
|
||||
/*
|
||||
循环结束之后pre所处的元素之前都是小于pivot(包含pre),右侧的元素都是大于或等于pivot的,交换cur+1和pviot的值
|
||||
*/
|
||||
swap(arr, pre +1, right)
|
||||
return pre + 1
|
||||
}
|
||||
|
||||
/*
|
||||
1000000个数据测试下来发现,partition ,partition3和4基本上无区别,而且4只是减少了代码,并没有减少执行
|
||||
过程,而且使代码变得难以理解,不推荐使用,推荐使用挖坑法来分数组,
|
||||
Function execution time: 464.513192 milliseconds
|
||||
Function execution time: 418.692408 milliseconds
|
||||
Function execution time: 467.99971000000005 milliseconds
|
||||
|
||||
*/
|
Loading…
x
Reference in New Issue
Block a user