1.js实现双指针算法,对数组进行排序
function quickSort(nums, left, right) {
if (left >= right) {
return;
}
const pivotIndex = partition(nums, left, right);
quickSort(nums, left, pivotIndex - 1);
quickSort(nums, pivotIndex + 1, right);
}
function partition(nums, left, right) {
const pivot = nums[left];
let i = left + 1;
let j = right;
while (i <= j) {
if (nums[i] < pivot && nums[j] > pivot) {
swap(nums, i++, j--);
} else if (nums[i] >= pivot) {
i++;
} else if (nums[j] <= pivot) {
j--;
}
}
swap(nums, left, j);
return j;
}
function swap(nums, i, j) {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
// 示例
const arr = [6, 3, 9, 5, 2, 8, 7, 1, 4];
quickSort(arr, 0, arr.length - 1);
console.log(arr); // 输出 [9, 8, 7, 6, 5, 4, 3, 2, 1]
在这个代码中,partition 函数用于将数组分成两部分并返回枢轴值的索引。需要注意的是,在这个函数中,左指针不是枢轴值的位置,而是其前一个位置。
时间复杂度为O(nlogn),最好情况下为 O(n),空间复杂度为O(logn)。
另外需要注意的是,虽然 JavaScript 中的 Array.prototype.sort() 方法也可以对数组进行排序,但其时间和空间的复杂度无法保证。
2.js实现快速排序算法,对数组进行排序
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
const pivot = arr[Math.floor(Math.random() * arr.length)];
const left = [];
const right = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else if (arr[i] > pivot) {
right.push(arr[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
// 示例
const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(quickSort(arr)); // [11, 12, 22, 25, 34, 64, 90]
快速排序是一种常用的高效的排序算法,可以将大问题分解成小问题逐个解决,时间复杂度为 O(nlogn)。
3.js实现搜索树算法,查找给定单词
class Node {
constructor(value) {
this.value = value;
this.children = {};
this.isCompleteWord = false;
}
}
class Trie {
constructor() {
this.root = new Node('');
}
insert(word) {
let node = this.root;
for (let i = 0; i < word.length; i++) {
const char = word.charAt(i);
if (!node.children[char]) {
node.children[char] = new Node(char);
}
node = node.children[char];
}
node.isCompleteWord = true;
}
search(word) {
let node = this.root;
for (let i = 0; i < word.length; i++) {
const char = word.charAt(i);
if (!node.children[char]) {
return false;
}
node = node.children[char];
}
return node.isCompleteWord;
}
}
// 示例
const trie = new Trie();
trie.insert('hello');
trie.insert('world');
console.log(trie.search('hello')); // 输出 true
console.log(trie.search('hi')); // 输出 false
在这个示例中,首先定义了一个 Node 类表示每个节点,包括值、子节点和标记当前节点是否为单词末尾的节点。然后定义 Trie 类表示整个搜索树,包括根节点和插入单词和查找单词的方法。
时间复杂度为 O(m),其中 m 表示单词长度。
4.js实现二分查找算法
function binarySearch(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (arr[mid] === target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
// 测试
const arr = [1, 3, 5, 7, 9];
console.log(binarySearch(arr, 3)); // 输出 1
console.log(binarySearch(arr, 8)); // 输出 -1
以上代码中,binarySearch 函数接收一个已排序的数组和要查找的目标值,返回目标值在数组中的索引。如果目标值不在数组中,则返回 -1。
函数中使用了 while 循环和双指针来实现二分查找。将左右指针分别初始化为数组的首尾元素下标,然后进入循环。每次循环先计算出中间元素的下标,然后判断中间元素是否等于目标值。如果是,则直接返回中间元素的下标;如果不是,则根据中间元素与目标值的大小比较,更新左右指针的位置。如果最终左指针大于右指针,则说明目标值不存在于数组中,返回 -1。
需要注意的是,该函数的前提条件是输入的数组已经是有序的,否则二分查找无法保证正确性。
5.js实现归并排序算法
function mergeSort(arr) {
// 递归边界,数组长度小于等于1
if (arr.length <= 1) {
return arr;
}
// 将数组一分为二,分别对左右两部分进行归并排序
const mid = Math.floor(arr.length / 2);
const leftArr = mergeSort(arr.slice(0, mid));
const rightArr = mergeSort(arr.slice(mid));
// 合并左右两部分
const result = [];
let i = 0, j = 0;
while (i < leftArr.length && j < rightArr.length) {
if (leftArr[i] <= rightArr[j]) {
result.push(leftArr[i]);
i++;
} else {
result.push(rightArr[j]);
j++;
}
}
// 将未处理完的部分直接放入结果数组中
while (i < leftArr.length) {
result.push(leftArr[i]);
i++;
}
while (j < rightArr.length) {
result.push(rightArr[j]);
j++;
}
return result;
}
// 测试
const arr = [3, 5, 1, 4, 7, 9, 2];
console.log(mergeSort(arr)); // 输出 [1, 2, 3, 4, 5, 7, 9]
以上代码中,mergeSort 函数接收一个待排序的数组,返回一个新数组,该数组是原数组的升序排列。
函数中使用了归并排序的思想。首先判断数组的长度是否小于等于 1,如果是则直接返回该数组。否则将数组一分为二,分别对左右两部分进行归并排序。接着将左右两部分进行合并,具体做法是使用两个指针依次比较左右两部分的元素,将较小的元素放入结果数组中,并将该元素所在部分的指针向右移动一位。最终把未处理完的部分直接放入结果数组中即可。
需要注意的是,在合并两个有序数组时,两个数组的元素都要按照升序排列,才能使得合并后的结果也是有序的。
6.js实现选择排序算法
function selectionSort(arr) {
const len = arr.length;
for (let i = 0; i < len - 1; i++) {
let minIndex = i;
// 找到剩余部分中最小的元素的下标
for (let j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// 将最小的元素与当前位置交换
if (minIndex !== i) {
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
}
}
return arr;
}
// 测试
const arr = [3, 5, 1, 4, 7, 9, 2];
console.log(selectionSort(arr)); // 输出 [1, 2, 3, 4, 5, 7, 9]
以上代码中,selectionSort 函数接收一个待排序的数组,返回一个新数组,该数组是原数组的升序排列。
函数中使用了选择排序的思想。首先遍历数组,从第 0 个元素开始,每次找到剩余部分中最小的元素(包括当前元素),然后将该元素与当前位置交换。依次循环,直到整个数组有序为止。
需要注意的是,选择排序的时间复杂度是 O(),不适合处理大规模数据。