#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); }
二叉排序树的创建,插入,遍历,节点删除,整个删除的封装
猜你喜欢
转载自blog.csdn.net/m0_37907835/article/details/78969808
今日推荐
周排行