二叉排序树的创建,插入,遍历,节点删除,整个删除的封装

#include<iostream>
using namespace std;

typedef struct BSTree
{
	int key;
	struct BSTree *LChild , *RChild;
}BSTree;

class CBSTree
{
private:
	BSTree *root;	//二叉排序树的根节点,可以代表一个树
	bool SearchKey(int key,BSTree **node,BSTree *root,BSTree *Father);
	void traverse(BSTree *root2);
	bool DeleteKey(int key,BSTree **root);
public:
	CBSTree();
	~CBSTree();
	bool search(int key, BSTree**node,BSTree *Father); //对SearchKey 函数的一个封装,减少参数
	bool InsertKey( int key);
	void Traverse();	//对遍历函数traverse的一个封装,减少参数
	void CreateBSTree(int data[],int length);
	void DeleteCBSTree(BSTree **root);
	void DeleteOperation(BSTree **node);
	bool DeleteKeyEx(int key);	// 对DeleteKey的一个封装减少参数
};

CBSTree::CBSTree()
{
	root = NULL;	//对树进行初始化,为空树
}

CBSTree::~CBSTree()
{
	DeleteCBSTree(&root);
}

bool CBSTree::SearchKey(int key,BSTree **node,BSTree *root,BSTree *Father)
{
	if(!root)	//如果为空
	{
		*node = Father;
		return false;
	}
	else
	{
		if(key > root->key)
		{
			Father = root;
			return SearchKey( key, node,root->RChild, root);
		}
		else if(key < root->key)
		{
			Father = root;
			return SearchKey(key , node, root->LChild, root);
		}
		else
		{
			*node = root;	//把root指针的地址数据传给node,这样函数外部node对应的变量就能获取当前root本身,而不是副本
			return true;
		}
	}
}

void CBSTree::traverse(BSTree *root2)
{
	if(root2)
	{
		traverse(root2->LChild);
		cout << root2->key <<" ";
		traverse(root2->RChild);
	}
}

bool CBSTree::search(int key, BSTree**node,BSTree *Father = NULL)
{
	return SearchKey(key,node,root,Father);
}

bool CBSTree::InsertKey( int key)	
{
	if(!this->root)	//先判断当前root是否为空,为空就把root作为根节点,左右孩子为空
	{
		this->root = new BSTree;
		this->root->key = key;
		this->root->LChild = NULL;
		this->root->RChild = NULL;
		return true;
	}
	else	//root不为空
	{
		BSTree *temp = NULL;	//temp保存search到的key对应的节点指针,如果没有search到则保存沿着路线查找的最后一个节点
		if(search(key,&temp))
		{
			cout << key << "已经存在"<< endl;
			return false;
		}
		else
		{
			if(key > temp->key)
			{
				temp->RChild = new BSTree;
				temp->RChild->key = key;
				temp->RChild->LChild = NULL;
				temp->RChild->RChild = NULL;
				return true;
			}
			else
			{
				temp->LChild = new BSTree;
				temp->LChild->key = key;
				temp->LChild->LChild = NULL;
				temp->LChild->RChild = NULL;
				return true;
			}
		}
	}
}

void CBSTree::Traverse()	//对遍历函数traverse的一个封装,减少参数
{
	traverse(root);
}
void CBSTree::CreateBSTree(int data[],int length)	//创建二叉排序树的过程就是把一次次插入新节点的过程
{
	for(int i = 0; i < length; i++)
	{
		InsertKey(data[i]);
	}
}
void CBSTree::DeleteCBSTree(BSTree **root)	//删除整个树
{
	if(*root)
	{
		DeleteCBSTree(&(*root)->LChild);
		DeleteCBSTree(&(*root)->RChild);
		delete *root;
		*root = NULL;

	}
}

void CBSTree::DeleteOperation(BSTree **node)	//删除某个指针对应节点的具体操作
{
	if(!(*node)->LChild && !(*node)->RChild)	//如果该节点没有左右孩子,则直接删除,并复制为空
	{
		delete(*node);		//关键点是该函数传进来的参数*node必须是root这个二叉树内的真实节点,非拷贝
		*node = NULL;	//因为要对root内部的真实节点进行操作
	}
	else if((*node)->LChild && !(*node)->RChild)	//如果只有左孩子
	{
		BSTree *temp = *node;
		(*node) = (*node)->LChild;	//则把指向该节点的指针指向节点左孩子
		delete temp;
	}
	else if((*node)->RChild && !(*node)->LChild)	//如果只有右孩子,参考上面
	{
		BSTree *temp = (*node)->RChild;
		delete (*node);
		(*node) = temp;

	}
	else	//如果左右孩子都有
	{
		BSTree*temp = (*node)->RChild;
		while(temp->LChild->LChild)	//寻找*node右子树下最靠左的叶子节点也就是最小的节点,也就是中序遍历下*node的后继,获取它的父节点
		{
			temp = temp->LChild;	//关键点:如果不获取父节点,而是直接获取最小节点的话,temp存储的是该节点的一个拷贝,不能直接进行操作
		}
		(*node)->key = temp->LChild->key;	//通过最小节点的父节点temp指向最小节点这个不是拷贝,而是直接操作了root里的节点
		DeleteOperation(&temp->LChild);
	}
}

bool CBSTree::DeleteKey(int key,BSTree **root)	//找到要删除的节点的指针,调用具体操作的函数删除
{
	if(!*root)	//如果为空
	{
		cout << "未找到" << key << endl;
		return false;
	}
	else
	{
		if(key > (*root)->key)
		{
			return DeleteKey( key,&(*root)->RChild);
		}
		else if(key < (*root)->key)
		{
			return DeleteKey(key , &(*root)->LChild);
		}
		else
		{
			DeleteOperation(&*root);
			return true;
		}
	}
}

bool CBSTree::DeleteKeyEx(int key)
{
	return DeleteKey(key,&root);
} 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值