【难】【BET】无重复值的搜索二叉树的插入和删除操作

题目:EPI


class treenode
{
public:
	int data;
	shared_ptr<treenode> left, right;
	treenode(int d) :data(d), left(nullptr), right(nullptr){}
	treenode(int d, shared_ptr<treenode> &l, shared_ptr<treenode> &r) :data(d), left(l), right(r){}
};

bool BST_insert(shared_ptr<treenode> &root, const int key)
{
	shared_ptr<treenode> t(new treenode(key));
	if (root == nullptr)
	{
		root = t;
		return true;
	}
	shared_ptr<treenode> cur = root, parent = nullptr;
	while (cur && cur->data != key)
	{
		parent = cur;
		if (cur->data > key)
			cur = cur->left;
		else
			cur = cur->right;
	}
	//不插入重复的值
	if (cur && cur->data == key)
	{
		t = nullptr;
		return false;
	}		
	//插入操作
	if (key < parent->data)
		parent->left = t;
	else
		parent->right = t;
	return true;
}

bool BST_earse(shared_ptr<treenode> &root, const int key)
{
	shared_ptr<treenode> cur = root, parent = nullptr;
	//寻找值为key的节点
	while (cur && cur->data!=key)
	{
		parent = cur;
		if (cur->data > key)
			cur = cur->left;
		else
			cur = cur->right;
	}
	//找不到值为key的节点
	if (cur == nullptr)
		return false;
	//此时 cur->data==key,应该删除cur节点
	//若cur有右孩子,则cur的父节点parent应连接cur右子树的最小节点cur_r_min
	//cur的孩子变成cur_r_min的孩子
	if (cur->right)
	{
		//cur_r_par初始化为cur,对cur的右孩子就是右子树最小值的情况,起着关键作用!
		shared_ptr<treenode> cur_r = cur->right, cur_r_par=cur;
		while (cur_r->left)
		{
			cur_r_par = cur_r;
			cur_r = cur_r->left;
		}
		//若被删节点是root,则此时 parent==nullptr
		//此时cur_r是最小值了,parent连接cur_r
		if (parent && parent->left == cur)
			parent->left = cur_r;
		else if (parent)
			parent->right = cur_r;
		//cur_r_par要连接cur_r的右子树	
		if (cur_r_par->left==cur_r)
			cur_r_par->left = cur_r->right;			
		else
			cur_r_par->right = cur_r->right;		
		//cur_r“接管”被删除节点cur的左右孩子
		cur_r->left = cur->left;
		cur_r->right = cur->right;
		if (root == cur)
			root = cur_r;
	}
	else//若cur没有右孩子
	{
		if (root == cur)
			root = cur->left;
		if (parent && parent->left == cur)
			parent->left = cur->left;
		else if (parent)
			parent->right = cur->left;
	}
	cur = nullptr;
	return true;
}


//测试代码
void inorder(const shared_ptr<treenode> &root)
{
	if (root == nullptr)
		return;
	inorder(root->left);
	cout << root->data << "\t";
	inorder(root->right);
}

shared_ptr<treenode> a1(new treenode(1));
shared_ptr<treenode> a2(new treenode(2));
shared_ptr<treenode> a3(new treenode(3));
shared_ptr<treenode> a4(new treenode(4));
shared_ptr<treenode> a5(new treenode(5));
shared_ptr<treenode> a6(new treenode(6));
shared_ptr<treenode> a7(new treenode(7));
shared_ptr<treenode> a8(new treenode(8));
a4->left = a2;
a4->right = a6;
a2->left = a1;
a2->right = a3;
a6->left = a5;
a6->right = a7;
a7->right = a8;
inorder(a4);
cout << endl;
BST_earse(a4, 7);
inorder(a4);
cout << endl;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值