一般的に使用されるアルゴリズムを js で実装する

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]

このコードでは、パーティション関数を使用して配列を 2 つに分割し、ピボット値のインデックスを返します。この関数では、左ポインタはピボット値の位置ではなく、その前の位置であることに注意してください。

時間計算量は 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) で 1 つずつ解決できます。

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 以下かどうかを判定し、1 以下であれば配列を直接返します。それ以外の場合、配列は 2 つに分割され、左側と右側の部分がそれぞれマージされて並べ替えられます。次に、左右の部分をマージします。具体的な方法は、2 つのポインタを使用して左右の部分の要素を順番に比較し、小さい方の要素を結果の配列に入れ、その要素が配置されている部分のポインタを移動します。一つ右へ。最後に、未処理の部分を結果配列に直接入れます。

2 つの順序付けされた配列をマージする場合、マージされた結果も順序付けされるように、2 つの配列の要素を昇順に配置する必要があることに注意してください。

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( n^{2}) であり、大規模なデータの処理には適していないことに注意してください。

おすすめ

転載: blog.csdn.net/weixin_39823006/article/details/130585500