1.快速排序
核心思想:1.找一个关键元素(pivote),循环比较数组中的元素与关键元素的大小,小的放左边,大的放右边。将左右两边两个小数组再递归以上操作,知道拆分的小数组中的元素小于2个,退出递归。2.在指定关键元素的时候可以简单的指定每次数组的最后一个元素,或者可以使用随机(可以达到期望值最佳,时间复杂度的期望值能达到O(nlogn))。
function quick_sort(nums) {
random_partition(nums);
return nums;
}
function random_partition(nums, l, r) {
if(l >= r) return;
let m = Math.floor(Math.random() *(r-l+1))+1;
swap(nums, m, r);
partition(nums, l, r);
}
function partition(nums, l, r) {
let pivote = nums[r];
let i = l -1;
for(let j = l; j < r; ++j) {
if(nums[j] <= pivote) {
swap(nums, ++i, j);
}
}
swap(nums, ++i, r);
random_partition(nums, l, i-1);
random_partition(nums, i+1, r);
}
function swap(nums, i, j) {
let tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
2.堆排序
核心思想:使用最小堆,每次将堆顶元素弹出,循环此操作,最终得到一个升序数组。这个方法需要先将输入的数组元素创建一个最小堆,并在每次弹出堆顶元素后需要做一次重建堆的操作,来维持最小堆的性质。时间复杂度为O(nlogn)
function stack_sort(nums) {
let minStack = new min_stack(nums);
return minStack.min_sort();
}
class min_stack {
construct(nums) {
this.stack = nums;
this.size = this.stack.length;
this.build();
}
build() {
for(let i = Math.floor(n/2) -1; i > -1; --i) {
this.siftdown(i);
}
}
siftdown(i) {
let j = i*2+1;
while(j < this.size) {
if(j+1 < this.size && this.stack[j] > this.stack[j+1]) ++j;
if(this.stack[i] > this.stack[j]) {
let tmp = this.stack[i];
this.stack[i] = this.stack[j];
this.stack[j] = tmp;
}
i = j;
j = i*2+1;
}
}
min_sort() {
let ret = [];
for(let i = this.size -1; i >= 0; --i) {
ret.push(this.stack[0]);
this.stack[0] = this.stack[i];
this.size -= 1;
this.siftdown(0);
}
return ret;
}
}
3.归并排序
核心思想:将数组递归拆分成左右两边,分别做排序后在合并两边有序数组;最终达到这个数组有序排列。整体分为拆分和合并,合并过程与合并两个有序数组一样, 时间复杂度O(nlogn)
function merge_sort(nums, l, r) {
if(l >= r) return;
let mid = Math.floor((r-l)/2);
merge_sort(nums, l, mid);
merge_sort(nums, mid+1, r);
let i = l, j = mid+1;
let tmp = [];
while(i <= mid && j <= r) {
if(nums[i] < nums[j]) {
tmp.push(nums[i++])
} else {
tmp.push(nums[j++])
}
}
while(i <= mid) {
tmp.push(nums[i++])
}
while(j <= r) {
tmp.push(nums[j++])
}
for(let k = 0; k < r-l+1; ++k) {
nums[k+l] = tmp[k];
}
}
functon sort(nums) {
merge_sort(nums, 0, nums.length-1);
return nums;
}