#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);
}
二叉排序树的创建,插入,遍历,节点删除,整个删除的封装
最新推荐文章于 2022-10-05 14:45:20 发布