排序
冒泡排序
比较相邻的两个元素,如果前一个比后一个大,则交换位置。
第一轮把最大的元素放到了最后面。
由于每次排序最后一个都是最大的,所以之后按照步骤1排序最后一个元素不用比
function bubble_sort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0, temp; j < arr.length - i - 1; j++) {
if (arr[j + 1] < arr[j]) {
temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp;
}
}
}
console.log(arr);
}
bubble_sort([3, 8, 8, 4, 5, 2, 1, 1]);
插入排序
过程类似于将牌桌上的牌拿到手中的过程(手中的牌始终保持升序)
function insert_sort(arr) {
// [0, i-1] 是手中的牌,[i, arr.length-1]是牌桌上的牌
// 一开始手中有一张牌 arr[0]
for (let i = 1; i < arr.length; i++) { // 始终保证 [0, i-1]的元素是升序
let val = arr[i]; // 从牌桌上拿一张牌
let right = i - 1;
// 将其插入到手中牌的适当位置(手中较大的牌整体右移一位,如果手中牌均小,则不移动)
while (right >= 0 && arr[right] > val) {
arr[right + 1] = arr[right];
right--;
}
arr[right + 1] = val;
}
console.log(arr);
}
insert_sort([3, 8, 8, 4, 5, 2, 1, 1]);
快速排序
核心就在递归
1. 划分: arr[i...j](包括arr[i] 和 arr[j])排序,随意取[i,j]中的一点p(如 p = (i + j) /2)则 将其划分为三段:arr[i...p-1] arr[p] arr[p+1...j]
2. 递归排序:将arr[i...p-1]中所有大于arr[p]的元素变换到 arr[p+1...j] 中,将 arr[p+1...j]中所有小于 arr[p]的元素变换到 arr[i...p-1]
function quick(arr, i, j) { // 范围 [i, j]
if (i < j) {
let q = split(arr, i, j); // 确保 范围 [i, q) 的值小于等于arr[q] 范围 [q+1, j]的值大于arr[q]
quick(arr, i, q - 1);
quick(arr, q + 1, j);
}
}
function split(arr, i, j) { // 范围 [i, j]
let val = arr[j], temp;
let minAreaRight = i - 1; // 区域[i, minAreaRight]的值均小于等于val
for (let k = i; k < j; k++) { // 遍历完成后区域 [minAreaRight+1, k] 的值均大于val
if (arr[k] <= val) {
minAreaRight++;
temp = arr[k]; arr[k] = arr[minAreaRight]; arr[minAreaRight] = temp;
}
}
minAreaRight++;
temp = arr[j]; arr[j] = arr[minAreaRight]; arr[minAreaRight] = temp;
return minAreaRight;
}
quick([3, 8, 8, 4, 5, 2, 1, 1], 0, arr.length - 1);
归并排序
1. 划分:将数组从中间划分为两部分,分别调用自身进行排序
2. 合并:将两段排好序的数组合并为一个排好序的数组
function merge_sort(arr, i, j) { // [i, j]
if (i < j) {
const mid = Math.floor(i + (j - i) / 2);
merge_sort(arr, i, mid);
merge_sort(arr, mid + 1, j);
merge(arr, i, mid, j);
}
}
function merge(arr, i, mid, j) { // [i, mid] 和 [mid+1, j] 分别已是升序
const leftArr = arr.slice(i, mid + 1), leftIndex = 0;
const rightArr = arr.slice(mid + 1, j + 1), rightIndex = 0;
leftArr.push(Number.MAX_SAFE_INTEGER);
rightArr.push(Number.MAX_SAFE_INTEGER);
for (let k = i; k <= j; k++) {
if(leftArr[leftIndex] <= rightArr[rightIndex]){
arr[k] = leftArr[leftIndex];
leftIndex++;
}else{
arr[k] = rightArr[rightIndex];
rightIndex++;
}
}
}
let arr = [3, 8, 8, 4, 5, 2, 1, 1];
merge_sort(arr, 0, arr.length - 1);
console.log(arr);
aa
aa

浙公网安备 33010602011771号