ホームページ >ウェブフロントエンド >jsチュートリアル >Trie (プレフィックス ツリー) の概要

Trie (プレフィックス ツリー) の概要

Patricia Arquette
Patricia Arquetteオリジナル
2025-01-15 06:26:43354ブラウズ

Introduction to Trie (Prefix Tree)

Trie は、特にオートコンプリート、スペル チェック、IP ルーティングなどのアプリケーションで文字列を効率的に保存および検索するために使用されるツリー状のデータ構造です。


トライの主なプロパティ:

  1. ノード: 各ノードは文字を表します。
  2. ルート: ルート ノードは空であり、開始点として機能します。
  3. : 各ノードには、文字セットに応じて最大 26 個 (英小文字の場合) 以上の子があります。
  4. 単語の終わりのマーカー: いくつかのノードは単語の終わりを示すためにマークされています。

基本的な試行操作:

1.挿入

単語を挿入するには、トライを走査し、存在しない文字の新しいノードを作成する必要があります。

2.検索

検索は、そのノードをたどることにより、単語がトライ内に存在するかどうかをチェックします。

3. プレフィックス検索

これは、トライ内の単語が指定された接頭辞で始まるかどうかをチェックします。


JavaScript での基本的なトライの実装:

class TrieNode {
    constructor() {
        this.children = {}; // Stores child nodes
        this.isEndOfWord = false; // Marks the end of a word
    }
}

class Trie {
    constructor() {
        this.root = new TrieNode();
    }

    // Insert a word
    insert(word) {
        let node = this.root;
        for (let char of word) {
            if (!node.children[char]) {
                node.children[char] = new TrieNode();
            }
            node = node.children[char];
        }
        node.isEndOfWord = true; // Mark the end of the word
    }

    // Search for a word
    search(word) {
        let node = this.root;
        for (let char of word) {
            if (!node.children[char]) {
                return false;
            }
            node = node.children[char];
        }
        return node.isEndOfWord;
    }

    // Check if any word starts with the given prefix
    startsWith(prefix) {
        let node = this.root;
        for (let char of prefix) {
            if (!node.children[char]) {
                return false;
            }
            node = node.children[char];
        }
        return true;
    }
}

// Example usage
const trie = new Trie();
trie.insert("apple");
console.log(trie.search("apple"));   // true
console.log(trie.search("app"));     // false
console.log(trie.startsWith("app")); // true
trie.insert("app");
console.log(trie.search("app"));     // true

高度な試行操作:

1. 単語を削除:

単語の削除には再帰的なアプローチが含まれ、不要になったノードを削除します。

delete(word, node = this.root, depth = 0) {
    if (depth === word.length) {
        if (!node.isEndOfWord) return false; // Word doesn't exist
        node.isEndOfWord = false;
        return Object.keys(node.children).length === 0; // Check if node has children
    }

    const char = word[depth];
    if (!node.children[char]) return false;

    const shouldDeleteChild = this.delete(word, node.children[char], depth + 1);

    if (shouldDeleteChild) {
        delete node.children[char];
        return Object.keys(node.children).length === 0 && !node.isEndOfWord;
    }

    return false;
}

2. 接頭辞が付いている単語を数える:

指定された接頭辞で始まる単語の数を数えます。

countWordsWithPrefix(prefix) {
    let node = this.root;
    for (let char of prefix) {
        if (!node.children[char]) return 0;
        node = node.children[char];
    }
    return this._countWords(node);
}

_countWords(node) {
    let count = node.isEndOfWord ? 1 : 0;
    for (let char in node.children) {
        count += this._countWords(node.children[char]);
    }
    return count;
}

3. オートコンプリートの提案:

接頭辞を指定すると、それで始まるすべての単語を返します。

getWordsWithPrefix(prefix) {
    let node = this.root;
    for (let char of prefix) {
        if (!node.children[char]) return [];
        node = node.children[char];
    }
    return this._collectWords(node, prefix);
}

_collectWords(node, prefix) {
    let results = [];
    if (node.isEndOfWord) results.push(prefix);

    for (let char in node.children) {
        results = results.concat(this._collectWords(node.children[char], prefix + char));
    }

    return results;
}

時間計算量:

  1. 挿入: O(L) (L = 単語の長さ)
  2. 検索: O(L)
  3. 前方一致検索: O(L)
  4. 削除: O(L)

トライの応用:

  1. オートコンプリート システム (検索バー、テキスト エディターなど)。
  2. スペルチェッカー.
  3. IP ルーティング (最長プレフィックス マッチング)。
  4. 単語ゲーム (例: Boggle)。
  5. DNA 配列の一致.

以上がTrie (プレフィックス ツリー) の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。