Implement commonly used algorithms with js

1.js realizes the double pointer algorithm and sorts the array

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]

In this code, the partition function is used to split the array into two and return the index of the pivot value. It should be noted that in this function, the left pointer is not the position of the pivot value, but its previous position.

Time complexity is O(nlogn), best case O(n), space complexity is O(logn).

In addition, it should be noted that although the Array.prototype.sort() method in JavaScript can also sort the array, its time and space complexity cannot be guaranteed.

2.js implements the quick sort algorithm and sorts the array

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]

Quick sort is a commonly used and efficient sorting algorithm, which can decompose large problems into small problems and solve them one by one, with a time complexity of O(nlogn).

3.js implements the search tree algorithm to find a given word

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

In this example, a Node class is first defined to represent each node, including the value, child nodes and the node that marks whether the current node is the end of a word. Then define the Trie class to represent the entire search tree, including the root node and methods for inserting words and finding words.

The time complexity is O(m), where m is the word length.

4.js implements binary search algorithm

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

In the above code, the binarySearch function receives a sorted array and the target value to be searched, and returns the index of the target value in the array. Returns -1 if the target value is not in the array.

The function uses while loop and double pointer to realize binary search. Initialize the left and right pointers as the subscripts of the first and last elements of the array, and then enter the loop. Each cycle first calculates the subscript of the middle element, and then judges whether the middle element is equal to the target value. If yes, directly return the subscript of the middle element; if not, update the position of the left and right pointers according to the size comparison between the middle element and the target value. If the final left pointer is greater than the right pointer, it means that the target value does not exist in the array, and return -1.

It should be noted that the precondition of this function is that the input array is already ordered, otherwise the binary search cannot guarantee the correctness.

5.js implements merge sort algorithm

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]

In the above code, the mergeSort function receives an array to be sorted and returns a new array, which is the ascending order of the original array.

The idea of ​​merge sort is used in the function. First judge whether the length of the array is less than or equal to 1, and if so, return the array directly. Otherwise, the array is divided into two, and the left and right parts are merged and sorted respectively. Then merge the left and right parts. The specific method is to use two pointers to compare the elements of the left and right parts in turn, put the smaller element into the result array, and move the pointer of the part where the element is located to the right by one. Finally, put the unprocessed part directly into the result array.

It should be noted that when merging two ordered arrays, the elements of the two arrays must be arranged in ascending order so that the merged result is also ordered.

6.js implements selection sorting algorithm

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]

In the above code, the selectionSort function receives an array to be sorted and returns a new array, which is the ascending order of the original array.

The idea of ​​selection sort is used in the function. First traverse the array, starting from the 0th element, each time find the smallest element in the remaining part (including the current element), and then exchange the element with the current position. Loop in turn until the entire array is sorted.

It should be noted that the time complexity of selection sort is O( n^{2}), which is not suitable for processing large-scale data.

Guess you like

Origin blog.csdn.net/weixin_39823006/article/details/130585500