二叉搜索树
二叉搜索树是树结构中最基础的一种。
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)实现集合的流程图如下所示:
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('已存在相同元素')