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

BSTree

  • 定义
  • 效率
  • 模拟实现
    • 1)实现基本框架
      • 构造函数
      • 拷贝构造函数
      • 赋值重载函数
      • 析构函数
    • 2)实现基本操作
      • insert插入操作
      • erase删除操作
      • find查找操作
      • 判定是否是BSTree
        • 看其中序遍历序列是否有序

定义

它或者是一颗空树,或者是具有下面性质的二叉树:
若它的左子树不为空,左子树的结点的值都小于根结点的值;
若它的右子树不为空,右子树结点的值都大于根结点;
同时,它的左右子树又都是搜索二叉树。
[数据结构] BSTree二叉搜索树的模拟实现_第1张图片

效率

最优情况下,二叉搜索树为完全二叉树,其平均比较次数为: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

看其中序遍历序列是否有序

你可能感兴趣的:(数据结构,c++,算法,开发语言)