赞
踩
二叉查找树是先对待查找的数据进行生成树,确保树的左分支的值小于右分支的值,然后在就行和每个节点的父节点比较大小,查找最适合的范围。 这个算法的查找效率很高,但是如果使用这种查找方法要首先创建树。
二叉查找树(BinarySearch Tree,也叫二叉搜索树 BST,或称二叉排序树Binary Sort Tree)或者是一棵空树,或者是具有下列性质的二叉树:
1)若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2)若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3)任意节点的左、右子树也分别为二叉查找树;
4) 没有键值相等的节点(no duplicate nodes)。
根据BST的特性,对于每个节点:
在上面的二叉搜索树中搜索目标值为 4 的节点
- def search(self, node, parent, data):
- if node is None:
- return False, node, parent
- if node.data == data:
- return True, node, parent
- if node.data > data:
- return self.search(node.leftChild, node, data)
- else:
- return self.search(node.rightChild, node, data)
与搜索操作类似,对于每个节点,我们将:
这样,我们就可以添加一个新的节点并依旧维持二叉搜索树的性质。
- def insert(self, data):
- flag, n, p = self.search(self.root, self.root, data)
- if not flag:
- new_node = BSTNode(data)
- if data > p.data:
- p.rightChild = new_node
- else:
- p.leftChild = new_node
删除要比我们前面提到过的两种操作复杂许多。有许多不同的删除节点的方法,根据其子节点的个数,我们需考虑以下三种情况:
1. 如果目标节点没有子节点,我们可以直接移除该目标节点。
2. 如果目标节只有一个子节点,我们可以用其子节点作为替换。
3. 如果目标节点有两个子节点,我们需要用其中序后继节点或者前驱节点来替换,再删除该目标节点。
例 1:目标节点没有子节点
例 2:目标节只有一个子节点
例 3:目标节点有两个子节点
- def delete(self, root, data):
- flag, n, p = self.search(root, root, data)
- if flag is False:
- return "关键字不存在,删除失败"
- else:
- if n.leftChild is None:
- if n == p.leftChild:
- p.leftChild = n.rightChild
- else:
- p.rightChild = n.rightChild
- del p
- elif n.rightChild is None:
- if n == p.leftChild:
- p.leftChild = n.leftChild
- else:
- p.rightChild = n.leftChild
- del p
- else: # 左右子树均不为空
- pre = n.rightChild
- if pre.leftChild is None:
- n.data = pre.data
- n.rightChild = pre.rightChild
- del pre
- else:
- next = pre.leftChild
- while next.leftChild is not None:
- pre = next
- next = next.leftChild
- n.data = next.data
- pre.leftChild = next.rightChild
- del p
- class BSTNode:
- def __init__(self, data):
- self.data = data
- self.leftChild = None
- self.rightChild = None
-
-
- class BST:
- def __init__(self, node_list):
- self.root = BSTNode(node_list[0])
- for data in node_list[1:]:
- self.insert(data)
-
- def search(self, node, parent, data):
- if node is None:
- return False, node, parent
- if node.data == data:
- return True, node, parent
- if node.data > data:
- return self.search(node.leftChild, node, data)
- else:
- return self.search(node.rightChild, node, data)
-
- def insert(self, data):
- flag, n, p = self.search(self.root, self.root, data)
- if not flag:
- new_node = BSTNode(data)
- if data > p.data:
- p.rightChild = new_node
- else:
- p.leftChild = new_node
-
- def delete(self, root, data):
- flag, n, p = self.search(root, root, data)
- if flag is False:
- return "关键字不存在,删除失败"
- else:
- if n.leftChild is None:
- if n == p.leftChild:
- p.leftChild = n.rightChild
- else:
- p.rightChild = n.rightChild
- del p
- elif n.rightChild is None:
- if n == p.leftChild:
- p.leftChild = n.leftChild
- else:
- p.rightChild = n.leftChild
- del p
- else: # 左右子树均不为空
- pre = n.rightChild
- if pre.leftChild is None:
- n.data = pre.data
- n.rightChild = pre.rightChild
- del pre
- else:
- next = pre.leftChild
- while next.leftChild is not None:
- pre = next
- next = next.leftChild
- n.data = next.data
- pre.leftChild = next.rightChild
- del p
- # 先序遍历
- def preOrderTraverse(self, node):
- if node is not None:
- print(node.data)
- self.preOrderTraverse(node.leftChild)
- self.preOrderTraverse(node.rightChild)
-
- # 中序遍历
- def inOrderTraverse(self, node):
- if node is not None:
- self.inOrderTraverse(node.leftChild)
- print(node.data)
- self.inOrderTraverse(node.rightChild)
-
- # 后序遍历
- def postOrderTraverse(self, node):
- if node is not None:
- self.postOrderTraverse(node.leftChild)
- self.postOrderTraverse(node.rightChild)
- print(node.data)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。