Patricia树 - 代码实现

前文回顾

例子

代码实现

class PatriciaNode:
    def __init__(self, key=None, value=None):
        self.key = key
        self.value = value
        self.children = {}

    def __str__(self):
        return f"Key: {self.key}, Value: {self.value}, Children: {list(self.children.keys())}"


class PatriciaTree:
    def __init__(self):
        self.root = PatriciaNode()

    def insert(self, key, value):
        if not key:
            return  # Ignore empty key
        self._insert_recursive(self.root, key, value)

    def _insert_recursive(self, node, key, value):
        if not key:
            node.value = value
            return

        for child_key in node.children:
            # 检查匹配情况
            common_prefix = self._longest_common_prefix(child_key, key)
            if common_prefix:
                if common_prefix == len(child_key):
                    # 全匹配的情况:直接在匹配的节点添加children
                    # Continue traversal
                    self._insert_recursive(node.children[child_key], key[common_prefix:], value)
                else:
                    # 不完全匹配的情况下,需要拆分节点
                    # 1. 拆分节点
                    # 2. 给拆分出来的节点添加children
                    # 3. 拆分出的点击的父节点需要更改key
                    # Split node
                    split_node = PatriciaNode(child_key[common_prefix:])
                    split_node.value = node.children[child_key].value
                    split_node.children = node.children[child_key].children
                    node.children[child_key[0:common_prefix]] = PatriciaNode(child_key[0:common_prefix])
                    node.children[child_key[0:common_prefix]].children = {child_key[common_prefix:]: split_node}
                    del node.children[child_key]
                    child_key = child_key[0:common_prefix]
                    if common_prefix < len(key):
                        node.children[child_key].children[key[common_prefix:]] = PatriciaNode(key[common_prefix:],
                                                                                              value)
                    else:
                        node.children[child_key].value = value
                return
        # 没有匹配的情况,直接插入
        node.children[key] = PatriciaNode(key, value)

    def search(self, key):
        return self._search_recursive(self.root, key)

    def _search_recursive(self, node, key):
        if not key:
            return node.value

        for child_key in node.children:
            if key.startswith(child_key):
                return self._search_recursive(node.children[child_key], key[len(child_key):])

        return None

    # 这里获取两个字符串的最长前缀匹配
    def _longest_common_prefix(self, str1, str2):
        min_len = min(len(str1), len(str2))
        for i in range(min_len):
            if str1[i] != str2[i]:
                return i
        return min_len

    def __str__(self):
        return self._stringify(self.root)

    def _stringify(self, node, depth=0):
        result = "  " * depth + str(node) + "\n"
        for child_key in sorted(node.children.keys()):  # Sort children keys
            result += self._stringify(node.children[child_key], depth + 1)
        return result

测试

# 测试
if __name__ == "__main__":
    tree = PatriciaTree()

    tree.insert("alice", 10)
    tree.insert("alivea", 20)
    tree.insert("aitana", 30)
    tree.insert("abanoub", 15)
    tree.insert("aicha", 18)
    tree.insert("abiy", 100)

    print(tree.search("alice"))  # Output: 10
    print(tree.search("alivea"))  # Output: 20
    print(tree.search("aitana"))  # Output: 30
    print(tree.search("abanoub"))  # Output: 15
    print(tree.search("aicha"))  # Output: 18
    print(tree.search("abiy"))  # Output: 100

    print("\nPatricia Tree Structure:")
    print(tree)

=== 测试结果 ===

Patricia Tree Structure:
Key: None, Value: None, Children: ['a']
  Key: a, Value: None, Children: ['li', 'i', 'b']
    Key: b, Value: None, Children: ['anoub', 'iy']
      Key: anoub, Value: 15, Children: []
      Key: iy, Value: 100, Children: []
    Key: i, Value: None, Children: ['tana', 'cha']
      Key: cha, Value: 18, Children: []
      Key: tana, Value: 30, Children: []
    Key: li, Value: None, Children: ['ce', 'vea']
      Key: ce, Value: 10, Children: []
      Key: vea, Value: 20, Children: []

这里使用的是前文的测试用例,可以看出测试结果是一致的。

关注我,一起进入Web3的世界

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值