二叉搜索树BST

401 阅读2分钟

Binary Search Tree(BST)

  • 或者是一棵空树;
  • 或者是具有下列性质的二叉树:
    • 对于任何一个结点,设其值为K
    • 则该结点的 左子树(若不空)的任意一个结点的值都 小于 K;
    • 该结点的 右子树(若不空)的任意一个结点的值都 大于 K;
    • 而且它的左右子树也分别为BST
  • 性质: 中序遍历是正序的(由小到大的排列)

检索

只需检索二个子树之一

  • 直到 K 被找到
  • 或遇上树叶仍找不到,则不存在

插入

  • 检索到不允许插入吧
  • 失败,则在该位置插入新叶,以保持BST的性质和性能

删除(值替换)

  • 先递归去找要删除的元素
  • 找到了,如果左右子树又一个为空,直接替换
  • 否则,找右子树的最小元素,进行值替换(把最小元素替换为右孩子,找到的元素的值替换为最小元素的值,最后内存释放最小元素)
void BST<T>:::remove(BinaryTreeNode <T> *& rt,
const T val) {
	if(rt == NULL) cout<<"not in the tree"<<endl;
	else if(val<rt->value())
		remove(rt->leftChild(),val);
	else if(val > rt->value())
		remove(rt->rightChild(),val);
	else {
		BinaryTreeNode *temp = rt;
		if(rt->leftChild == NULL) rt = tr->rightChild();  //直接替换就好了
		else if(rt->rightChild == NULL) rt = rt->leftChild();//直接替换就好了
		else { //左右子树都不为空,找到右子树的最小节点,然后替换该节点值
			temp = deletemin(rt->rightChild());
			rt->setValue(temp->value());
		}
	}
}

//找右子树的最小节点
template<class T>
BinaryTreeNode *BST::deletemin(BinaryTreeNode<T> *rt){
	if(rt->leftChild() !=NULL)
		return deletemin(rt->leftChild());
	else {  //删除右子树中的最小节点
		BinaryTreeNode *temp = rt;  //找到了右子树中最左的节点,也就是右子树中最小的节点
		rt = rt->rightChild();  //把最小节点替换为右子树
		return temp;   //这里返回引用,引用用完之后内存会被释放,很巧妙
	}
}

二叉搜索树总结

  • 组织内存索引
    • 二叉搜索树是适用于内存储器的一种重要的树形索引
      • 常用红黑树、伸展树等,以维持平衡
    • 外存常用B/B+树
  • 保持性质 vs 保持性能
    • 插入新结点或删除已有结点,要保证操作结束后仍符合二叉搜索树的定义

思考

若二叉搜索树中含有重复的元素,如何进行元素的插入和删除操作?

答:可以在每个节点增设一个标记位,标记当前该节点元素的个数。若要插入/删除的元素BST中已存在,则只需修改标记位的值即可。