(复习代码 + 详细注解)二叉搜索的插入、删除

#include <iostream>

using namespace std;

template<class T>
struct BSTnode {
	BSTnode(const T &data)
		: _Lnode(nullptr)
		, _Rnode(nullptr)
		, _data(data) {
	}

	BSTnode<T> *_Lnode;
	BSTnode<T> *_Rnode;
	T _data;
};

template<class T>
class BSTree {
		typedef BSTnode<T> Node;
		typedef BSTnode<T> *PNode;

	public:
		BSTree()
			: _root(nullptr) {
		}

		~BSTree() {
		}
		bool insert(const T &data) {
			if (_root == nullptr ) {
				_root = new Node(data);
				return true;
			}

			//找到位置
			PNode cur = _root;
			PNode parent = nullptr;
			while (cur) {
				parent = cur;
				if (cur->_data < data) { // 大于
					cur = cur->_Rnode;
				} else if (cur->_data > data) {
					cur = cur->_Lnode;
				} else
					return false;
			}

			cur = new Node(data);
			if (parent->_data > data) {
				parent->_Lnode = cur;
			} else
				parent->_Rnode = cur;

			return true;
		}

		bool find(const T &val) {
			if (_root == nullptr ) {
				return false;
			}

			//找到位置
			PNode cur = _root;
			while (cur) {
				if (cur->_data < val) { // 大于
					cur = cur->_Rnode;
				} else if (cur->_data > val) {
					cur = cur->_Lnode;
				} else
					return true;;
			}

			return false;
		}

		void inorder() {
			_Inorder(_root);
			cout << endl;
		}

		bool erase(const T &data) {
			PNode cur = _root;
			PNode parent = nullptr;

			while (cur) {
				//找到要删除的元素
				if (cur->_data < data ) {
					parent = cur;
					cur = cur->_Rnode;
				} else if (cur->_data > data) {
					parent = cur;
					cur = cur->_Lnode;
				} else { //这里面是目标元素
				
					//删除 左边是空的 , 父亲指向我的右
					if (cur->_Lnode == nullptr) {
						if (cur == _root) //删除是根节点
							_root = cur->_Rnode;
						else { //删除元素不是根节点
							//判断删除元素在左右子树中的哪一个
							if (cur == parent->_Lnode)
								parent->_Lnode = cur->_Rnode;
							else
								parent->_Rnode = cur->_Rnode;
						}

						delete cur;//删除之后清理空间!!
					} else if (cur->_Rnode == nullptr) { //右边是空的  父亲指向我的左
						if (cur == _root)
							_root = cur->_Lnode;
						else {
							//判断删除元素在左右子树中的哪一个
							if (cur == parent->_Lnode)
								parent->_Lnode = cur->_Lnode;
							else
								parent->_Rnode = cur->_Lnode;
						}
						delete cur;
					} else { //要删除的元素左右子树都不为空的情况
						//替换法
						//1.找到左子树的最大值替换
						//2.找右子树的最小值替换
						//选择方案2

						//先找到右子树的最小值
						PNode MinLnode = cur->_Rnode;//这里拿到目标值的右孩子 去寻找它的最小值
						PNode Parent_Lnode = parent;
						while (MinLnode->_Lnode) {
							Parent_Lnode = MinLnode;
							MinLnode = MinLnode->_Lnode;
						}

						swap(MinLnode->_data, cur->_data);//交换操作 替换

						//左子树没有了 直接链接 MinLnode 的右子树
						//   MinLnode  的右子树的两种情况  1.为空  2.不为空还链接着节点
						//但都不会影响

						//判断 MinLnode 在左子树还是右子树
						if (Parent_Lnode->_Lnode == MinLnode) {
							Parent_Lnode->_Lnode = MinLnode->_Rnode;
						} else
							Parent_Lnode->_Rnode = MinLnode->_Rnode;

						delete cur;
					}
					return true;
				}
			}
			return false;
		}

	private:
		void _Inorder(PNode root) {
			if (root == nullptr)
				return ;

			_Inorder(root->_Lnode);
			cout << root->_data << " ";
			_Inorder(root->_Rnode);
		}

		PNode _root;
};



int main() {
	int a[] = {3,2,6,17,8348,84,4,2};
	BSTree<int> t1;
	for (auto e : a) {
		t1.insert(e);
	}
	t1.inorder();
	t1.erase(2);
	t1.erase(2);
	t1.inorder();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值