树结构(一)

二叉搜索树

  二叉搜索树是树结构中最基础的一种。

class BST(object):
    def __init__(self, key, left=None, right=None):
        self.__label = key
        self.__right = right
        self.__left = left
        self.__height = 1

    def add(self, key, condition=True, height=1):
        if key < self.__label:
            height += 1
            if self.__left is None:
                self.__left = BST(key)
            else:
                condition, height = self.__left.add(key, condition, height)
        if key > self.__label:
            height += 1
            if self.__right is None:
                self.__right = BST(key)
            else:
                condition, height = self.__right.add(key, condition, height)
        if height > self.__height:
            self.__height = height
        if key == self.__label:
            condition = False
        return condition, height

  与QuickUnion类似,二叉搜索树容易出现不平衡的情况,会大大降低其效率,因此引入B-tree。

B-tree

  B-tree本质上与二叉搜索树类似,但一个节点中可以存在多个元素。对于存在 n n n个元素的节点,拥有 n + 1 n+1 n+1个子节点。根据节点中可存在的最多元素个数 L L L的不同,B-tree的名称也不同。当 L = 1 L=1 L=1时,即为二叉搜索树;当 L = 2 L=2 L=2时,成为2-3树;当 L = 3 L=3 L=3时,称为2-4树。实际应用中, L L L的值一般很大。B-tree( L = 2 L=2 L=2)实现集合的流程图如下所示:B-tree添加操作流程图

class Node:
    def __init__(self, data, parent=None):
        self.data = [data] if type(data) is int else data
        self.parent = parent
        self.children = list()

    def __is_leaf(self):
        return len(self.children) == 0

    def __which_child(self):
        for index, child in enumerate(self.parent.children):
            if self.data[0] == child.data[0] or self.data[-1] == child.data[-1]:
                return index

    def add(self, value):
        if self.__is_leaf():
            if self.__insert(value) is False:
                return False
            if len(self.data) == L + 1:
                if not self.parent:
                    self.children.append(Node(self.data[:L // 2], self))
                    self.children.append(Node(self.data[L // 2 + 1:], self))
                    self.data = [self.data[L // 2]]
                else:
                    if len(self.parent.data) < L:
                        self.__child_split()
                    else:
                        while self.parent and len(self.parent.data) == L:
                            self.__child_split()
                            if not self.__is_leaf():
                                self.__child_assign(self.__which_child() - 1)
                            self = self.parent
                        if not self.parent:
                            self.parent = Node(self.data[L // 2])
                            self.parent.children = [self]
                            self.parent.children.insert(self.__which_child(), Node(
                                self.data[:L // 2], self.parent))
                            self.data = self.data[L // 2 + 1:]
                            self.__child_assign()
                        else:
                            self.__child_split()
                            self.__child_assign(self.__which_child() - 1)
        else:
            for index, number in enumerate(self.data):
                if value == number:
                    return False
                elif value < number:
                    if self.children[index].add(value) is False:
                        return False
                    break
            else:
                if self.children[-1].add(value) is False:
                    return False

    def __child_split(self):
        self.parent.__insert(self.data[L // 2])
        self.parent.children.insert(self.__which_child(), Node(self.data[:L // 2], self.parent))
        self.data = self.data[L // 2 + 1:]

    def __child_assign(self, index=0):
        self.parent.children[index].children = self.children[:L // 2 + 1]
        self.parent.children[index].__parent_assign()
        self.parent.children[index + 1].children = self.children[L // 2 + 1:]
        self.parent.children[index + 1].__parent_assign()

    def __parent_assign(self):
        for child in self.children:
            child.parent = self

    def __insert(self, value):
        for index, number in enumerate(self.data):
            if value == number:
                return False
            if value < number:
                self.data.insert(index, value)
                break
        else:
            self.data.insert(index + 1, value)


class Btree:
    def __init__(self, value):
        self.__root = Node(value)

    def add(self, value):
        result = self.__root.add(value)
        if self.__root.parent:
            self.__root = self.__root.parent
        return result is None


L = 2
items = [1, 2, 3, 4, 1, 4, 0, 4, 1, 5]
btree = Btree(items[0])
for item in items[1:]:
    if btree.add(item) is True:
        print('添加成功')
    else:
        print('已存在相同元素')
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值