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