📜  根树 java (1)

📅  最后修改于: 2023-12-03 15:10:49.858000             🧑  作者: Mango

根树 Java

根树(Radix Tree),也叫前缀树(Prefix Tree)或字典树(Trie),是一种基于字符串前缀匹配的高效数据结构。Java中的根树实现主要有两种:基于数组的实现和基于HashMap的实现。

基于数组的实现

基于数组的实现,其实就是一个内部节点包含着一个固定大小的数组,数组的大小就是字符集的大小,而对于每个字符来说,数组中会存储一个继续下去的子树。因此,查询时也只需一次字符数组寻址即可,效率非常高。但是,由于固定数组的大小,无法支持存储大量不同的字符串。

以下是一个基于数组的根树Java代码片段:

public class ArrayRadixTree {
    private final static int CHAR_SIZE = 256;
    private RadixTreeNode root;

    public void insert(String key) {
        if (key == null || key.length() == 0) {
            return;
        }
        char[] charArr = key.toCharArray();
        if (root == null) {
            root = new RadixTreeNode(false);
        }
        insert(root, charArr, 0);
    }

    private void insert(RadixTreeNode node, char[] charArr, int index) {
        char c = charArr[index];
        if (node.children[c] == null) {
            node.children[c] = new RadixTreeNode(false);
        }
        if (index == charArr.length - 1) {
            node.children[c].isEnd = true;
        } else {
            insert(node.children[c], charArr, index + 1);
        }
    }

    public boolean search(String key) {
        if (key == null || key.length() == 0) {
            return false;
        }
        char[] charArr = key.toCharArray();
        if (root == null) {
            return false;
        }
        return search(root, charArr, 0);
    }

    private boolean search(RadixTreeNode node, char[] charArr, int index) {
        char c = charArr[index];
        if (node.children[c] == null) {
            return false;
        }
        if (index == charArr.length - 1) {
            return node.children[c].isEnd;
        } else {
            return search(node.children[c], charArr, index + 1);
        }
    }

    private static class RadixTreeNode {
        boolean isEnd;
        RadixTreeNode[] children;

        RadixTreeNode(boolean isEnd) {
            this.isEnd = isEnd;
            this.children = new RadixTreeNode[CHAR_SIZE];
        }
    }
}
基于HashMap的实现

基于HashMap的实现,每个节点不再包含固定大小的数组,而是一个HashMap,存储字符与子节点的对应关系。这种实现方式可支持大量的不同字符串,但是其性能介于基于数组和基于树的实现之间。

以下是一个基于HashMap的根树Java代码片段:

public class MapRadixTree {
    private RadixTreeNode root;

    public void insert(String key) {
        if (key == null || key.length() == 0) {
            return;
        }
        if (root == null) {
            root = new RadixTreeNode(false);
        }
        insert(root, key, 0);
    }

    private void insert(RadixTreeNode node, String key, int index) {
        char c = key.charAt(index);
        if (!node.children.containsKey(c)) {
            node.children.put(c, new RadixTreeNode(false));
        }
        if (index == key.length() - 1) {
            node.children.get(c).isEnd = true;
        } else {
            insert(node.children.get(c), key, index + 1);
        }
    }

    public boolean search(String key) {
        if (key == null || key.length() == 0) {
            return false;
        }
        if (root == null) {
            return false;
        }
        return search(root, key, 0);
    }

    private boolean search(RadixTreeNode node, String key, int index) {
        char c = key.charAt(index);
        if (!node.children.containsKey(c)) {
            return false;
        }
        if (index == key.length() - 1) {
            return node.children.get(c).isEnd;
        } else {
            return search(node.children.get(c), key, index + 1);
        }
    }

    private static class RadixTreeNode {
        boolean isEnd;
        Map<Character, RadixTreeNode> children;

        RadixTreeNode(boolean isEnd) {
            this.isEnd = isEnd;
            this.children = new HashMap<>();
        }
    }
}

无论基于数组还是基于HashMap的实现,都提供了高效而有效的方法来存储和查询字符串。开发者可以根据自己的需求选择更适合自己的实现方式。