BST树
BST树,二叉查找树(Binary Search Tree),又叫二叉搜索树、二叉排序树。
它或者是一颗空树,或者是具有以下性质的二叉树:
- 若它的左子树不为空,则左子树上所有的结点的值均小于它的根结点的值;
- 若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左右子树也分别为二叉排序树
二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。
这张图片是BST树的一个简单示例
BST树的构造
二叉搜索树(BST)又称二叉查找树或二叉排序树。一棵二叉搜索树是以二叉树来组织的,可以使用一个链表数据结构来表示,其中每一个结点就是一个对象。一般地,除了key之外,每个结点还包含属性lchild、rchild和parent,分别指向结点的左孩子、右孩子和双亲(父结点)。如果某个孩子结点或父结点不存在,则相应属性的值为空(NIL)。根结点是树中唯一父指针为NIL的结点,而叶子结点的孩子结点指针也为NIL。
class BSTree {
class BstNode {
int key;
BstNode leftchild;
BstNode parent;
BstNode rightchild;
public BstNode() {
key = 0;
leftchild = parent = leftchild = null;
}
public BstNode(int x) {
key = x;
leftchild = parent = leftchild = null;
}
public BstNode(int x,BstNode left,BstNode pa,BstNode right) {
key = x;
leftchild = left;
parent = pa;
rightchild = right;
}
}
BstNode root; //根节点
BstNode cur; //指向当前节点
public BSTree() {
root = null;
cur = null;
}
}
BST习题
BST树的查询
1.查询否存在值为kx的Node,并返回。
private BstNode Search(BstNode ptr,int kx) {
if(ptr == null || ptr.key == kx) {
return ptr;
}
else if(kx < ptr.key) {
return Search(ptr.leftchild, kx);
}else {
return Search(ptr.rightchild, kx);
}
}
2.查询是否存在值为kx的结点
public boolean SearchValue(int kx) {
boolean res = false;
cur = Search(root,kx);
if(cur != null) {
res = true;
}
return res;
}
public boolean FindValue(int kx) {
cur = root;
boolean res = false;
while(cur != null && cur.key != kx) {
cur = kx < cur.key ? cur.leftchild : cur.rightchild;
}
if(cur != null && cur.key == kx) {
res = true;
}
return res;
}
BST树的插入
在插入时,将所插入的节点值分别比较,如果小就往左子树找,大就往右子树找。
public boolean Insert(int kx)//插入
{
boolean res = true;
if(root == null)
{
root = new BstNode(kx);
return res;
}
cur = root;
BstNode pa = null;
while(cur != null && cur.key != kx) {
pa = cur;
cur = kx < cur.key ? cur.leftchild : cur.rightchild;
}
if(cur != null && cur.key == kx) {
res = false;
}
else
{
cur = new BstNode(kx);
cur.parent = pa;
if(cur.key < pa.key)
{
pa.leftchild = cur;
}
else
{
pa.rightchild = cur;
}
}
return res;
}
BST树的中序遍历
其实,BST最简单的标志就是它的中序遍历序列是有序的。
public void NiceInOrder() //非递归中序遍历
{
if(root == null) return ;
Stack<BstNode> st = new Stack<>();
cur = root;
while(cur != null || !st.isEmpty())
{
while(cur != null)
{
st.push(cur);
cur = cur.leftchild;
}
cur = st.pop();
System.out.print(cur.key+ " ");
cur = cur.rightchild;
}
System.out.println();
}
判断是否为BST树
利用栈,每次去比较当前节点的右子节点的大小。
public boolean Is_BSTree() //是否为bst树
{
boolean res = true;
if(root == null) return res;
Stack<BstNode> st = new Stack<>();
cur = root;
BstNode pre = null;
while(cur != null || !st.isEmpty())
{
while(cur != null)
{
st.push(cur);
cur = cur.leftchild;
}
cur = st.pop();
if(pre != null && pre.key >= cur.key)
{
res = false;
break;
}
pre = cur;
cur = cur.rightchild;
}
return res;
}
BST的删除
private BstNode Next(BstNode ptr)
{
while(ptr != null && ptr.leftchild != null)
{
ptr = ptr.leftchild;
}
return ptr;
}
public boolean Remove(int kx)
{
boolean res = false;
if(root == null) return res;
BstNode pa = null;
cur = root;
while(cur != null && cur.key == kx)
{
pa = cur;
cur = kx < cur.key ? cur.leftchild:cur.rightchild;
}
if(cur == null) return res;
if(cur.leftchild != null && cur.rightchild != null)
{
BstNode nt = Next(cur.rightchild);
cur.key = nt.key;
pa = nt.parent;
cur = nt;
}
BstNode child = cur.leftchild != null ? cur.leftchild:cur.rightchild;
if(child != null) child.parent = pa;
//leaf // one brch
if(pa == null)
{
root = child;
}
else {
if (cur.key < pa.key) {
pa.leftchild = child;
} else {
pa.rightchild = child;
}
}
return true;
}
}