[数据结构] BSTree二叉搜索树的模拟实现

定义

它或者是一颗空树,或者是具有下面性质的二叉树:
若它的左子树不为空,左子树的结点的值都小于根结点的值;
若它的右子树不为空,右子树结点的值都大于根结点;
同时,它的左右子树又都是搜索二叉树。
BSTree

效率

最优情况下,二叉搜索树为完全二叉树,其平均比较次数为:logN
最差情况下,二叉搜索树退化为单支树,其平均比较次数为:n/2

模拟实现

1)实现基本框架

构造函数

BSTree()
	:_root(nullptr){
}

拷贝构造函数

BSTree(const BSTree<T>& t){
	_root = _copy(t._root);
}

node* _copy(node* root){
	if (root == nullptr)
		return nullptr;
	node* copyroot = new node(root->_val);
	copyroot->_left = _copy(root->_left);
	copyroot->_right = _copy(root->_right);
	return copyroot;
}

赋值重载函数

// 现代写法
BSTree<T>& operator=(BSTree<T> t){
	swap(_root, t._root);
	return *this;
}

析构函数

~BSTree(){
	destroy(_root);
	_root = nullptr;
}

void destroy(node*& root){
	if (root == nullptr)
		return;
	destroy(root->_left);
	destroy(root->_right);
	delete root;
}

2)实现基本操作

insert插入操作

bool insert(const T& val){
	// 根节点为空,直接插入根节点
	if (_root == nullptr){
		_root = new node(val);
		return true;
	}
	// 先找待插入结点的位置
	node* parent = nullptr;
	node* cur = _root;
	while (cur != nullptr){
		if (val < cur->_val){
			parent = cur;
			cur = cur->_left;
		}
		else if (val > cur->_val){
			parent = cur;
			cur = cur->_right;
		}
		else{
			return false;
		}
	}
	// 在此处插入结点
	node* newnode = new node(val);
	if (parent->_val < val){
		parent->_right = newnode;
	}
	else{
		parent->_left = newnode;
	}
	return true;
}

erase删除操作

bool erase(const T& val){
	//1.先找待删除结点的位置
	node* parent = nullptr;
	node* cur = _root;
	while (cur != nullptr){
		if (val < cur->_val){
			parent = cur;
			cur = cur->_left;
		}
		else if (val > cur->_val){
			parent = cur;
			cur = cur->_right;
		}
		else{  //2.找到了待删除结点的位置,删除结点
		//左为空或者右为空,把另一个孩子交给父亲
			if (cur->_left == nullptr){
				if (cur == _root){  //注意待删除结点是根结点的情况
					_root = cur->_right;
				}
				else{
					if (parent->_left == cur){
						parent->_left = cur->_right;
					}
					else{
						parent->_right = cur->_right;
					}
				}
				delete cur;
			}
			else if (cur->_right == nullptr){
				if (cur == _root){
					_root = cur->_left;
				}
				else{
					if (parent->_left == cur){
						parent->_left = cur->_left;
					}
					else{
						parent->_right = cur->_left;
					}
				}
				delete cur;
			}
			else{ //左右孩子都存不为空:替换删除
				node* minparent = cur;
				node* minnode = cur->_right;
				//先找到右子树的最小结点
				while (minnode->_left != nullptr){  
					minparent = minnode;
					minnode = minnode->_left;
				}
				//递归删除替换结点,再替换最小结点的值
				T minval = minnode->_val;
				this->erase(minval);
				cur->_val = minval;
			}
			return true;
		}
	return false;
}

find查找操作

node* find(const T& val){
	node* cur = _root;
	while (cur != nullptr){
		if (val < cur->_val)
			cur = cur->_left;
		else if (val > cur->_val)
			cur = cur->_right;
		else
			return cur;
	}
	return nullptr;
}

判定是否是BSTree

看其中序遍历序列是否有序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值