算法与数据结构基础11:C++实现——二叉搜索树节点删除

来源:互联网 发布:profileuntitled软件 编辑:程序博客网 时间:2024/06/05 05:24

基于我的另一篇文章《算法与数据结构基础4:C++二叉树实现及遍历方法大全》 ,二叉树的结构用的这篇文章里的。


二查找叉树的删除可以细分为三种情况:
1 被删除的是叶子节点,直接删除;
2 被删除只有一个子节点,指针下移;
3 有两个子节点,为了不破坏树的结构,需要找出一个节点来替换当前节点。
  根据二叉树的特点,当前节点大于所有左子树,小于所有右子树,
  可以用左子树中最大的节点,或者右子树最小的节点来替换当前节点,然后删除替换节点。


  // BSTree.h

#include <cstdio>#include <iostream>#include <stack>#include <queue>using namespace std;// binary search tree,中文翻译为二叉搜索树、二叉查找树或者二叉排序树。简称为BSTclass BSTree{struct Node{Node(int x = 0):data(x), lchild(NULL), rchild(NULL){}struct Node* lchild;struct Node* rchild;int data;};public:// **************************************************************************// 类的四大函数:构造函数、拷贝构造函数、重载赋值运算符、析构函数// **************************************************************************BSTree();~BSTree();// **************************************************************************// 增删改查// **************************************************************************void Insert(int x);void Remove(int x);// 返回二叉树的个数unsigned short Size();unsigned short Deep();unsigned short Leaf();bool IsEmpty();// 遍历void PreorderTraversal();// 先序遍历void InorderTraversal();// 中序遍历void PostorderTraversal();// 后序遍历void DepthFirstSearch();// 深度优先遍历void BreadthFirstSearch();// 广度优先遍历private:void Remove(int x, Node** pNode);// 递归计算二叉树个数unsigned short CountSize(Node* n);unsigned short CountDeep(Node* n);unsigned short CountLeaf(Node* n);// 递归遍历void PreorderTraversal(Node* n);void InorderTraversal(Node* n);void PostorderTraversal(Node* n);void DepthFirstSearch(Node* n);void BreadthFirstSearch(Node* n);void Free(Node* node);private:Node* m_root;};// **************************************************************************// 私有方法// **************************************************************************/* //1 请问下面这份代码有什么问题?void BSTree::Remove(int x, Node* node){if (!node) {return;}if (x < node->data) {Remove(x, node->lchild);}else if (x > node->data){Remove(x, node->rchild);}else if (node->lchild && node->rchild) {Node* min = node->rchild;while(min->lchild){min = min->lchild;}node->data = min->data;Remove(node->data, node->rchild);}else{Node* tmp = node;if(node->lchild){node = node->lchild;}else if (node->rchild){node = node->rchild;}else{node = NULL;}delete tmp;tmp = NULL;}}node是一个局部变量,对node的操作除delete之外都不会生效// 2 再问,下面的代码有什么问题?void BSTree::Remove(int x, Node** pNode){if (!pNode || !(*pNode)) {return;}Node* node = *pNode;if (x < node->data) {Remove(x, node->lchild);}else if (x > node->data){Remove(x, node->rchild);}else if (node->lchild && node->rchild) {Node* min = node->rchild;while(min->lchild){min = min->lchild;}node->data = min->data;Remove(node->data, node->rchild);}else{Node* tmp = node;if(node->lchild){node = node->lchild;}else if (node->rchild){node = node->rchild;}else{node = NULL;}delete tmp;tmp = NULL;}}同样的问题,虽然这里传递的参数是指针,但是Node* node = *pNode;发生了拷贝。*/void BSTree::Remove(int x, Node** pNode){if (!pNode || !(*pNode)) {return;}if (x < (*pNode)->data) {Remove(x, &((*pNode)->lchild));}else if (x > (*pNode)->data){Remove(x, &((*pNode)->rchild));}else if ((*pNode)->lchild && (*pNode)->rchild) {Node* min = (*pNode)->rchild;while(min->lchild){min = min->lchild;}(*pNode)->data = min->data;Remove((*pNode)->data, &((*pNode)->rchild));}else{Node* tmp = *pNode;if((*pNode)->lchild){(*pNode) = (*pNode)->lchild;}else if ((*pNode)->rchild){*pNode = (*pNode)->rchild;}else{*pNode = NULL;}delete tmp;tmp = NULL;}}unsigned short BSTree::CountSize(Node* n){if(!n){return 0;}return CountSize(n->lchild) + CountSize(n->rchild) + 1;}unsigned short BSTree::CountDeep(Node* n){if (!n) {return 0;}int ldeep = CountDeep(n->lchild);int rdeep = CountDeep(n->rchild);return ( ldeep > rdeep ) ? (ldeep + 1) : (rdeep + 1);}unsigned short BSTree::CountLeaf(Node* n){if (!n){return 0;}if (!n->lchild&& !n->rchild){return 1;}return CountLeaf(n->lchild) + CountLeaf(n->rchild);}void  BSTree::PreorderTraversal(Node* n){if (n) {cout << n->data << ",";PreorderTraversal(n->lchild);PreorderTraversal(n->rchild);}}void  BSTree::InorderTraversal(Node* n){if (n) {InorderTraversal(n->lchild);cout << n->data << ",";InorderTraversal(n->rchild);}}void  BSTree::PostorderTraversal(Node* n){if (n) {PostorderTraversal(n->lchild);PostorderTraversal(n->rchild);cout << n->data << ",";}}void BSTree::DepthFirstSearch(Node* root){stack<Node *> nodeStack;nodeStack.push(root);Node* node = NULL;while(!nodeStack.empty()){node = nodeStack.top();cout << node->data << ",";nodeStack.pop();if (node->rchild) {nodeStack.push(node->rchild);}if (node->lchild) {nodeStack.push(node->lchild);}}}void BSTree::BreadthFirstSearch(Node* root){queue<Node *> nodeQueue;nodeQueue.push(root);Node* node = NULL;while(!nodeQueue.empty()){node = nodeQueue.front();nodeQueue.pop();cout << node->data << ",";if (node->lchild) {nodeQueue.push(node->lchild);}if (node->rchild) {nodeQueue.push(node->rchild);}}}void BSTree::Free(Node* n){if (n) {Free(n->lchild);Free(n->rchild);delete n;n = NULL;}}// **************************************************************************// 类的四大函数:构造函数、拷贝构造函数、重载赋值运算符、析构函数// **************************************************************************BSTree::BSTree(){m_root = NULL;}BSTree::~BSTree(){Free(m_root);}// **************************************************************************// 增删改查// **************************************************************************void BSTree::Insert(int x){Node* tmp = new Node(x);if (!m_root){m_root = tmp;}else{Node* pre = m_root;Node* cur = m_root;while (cur){pre = cur;cur = (x < cur->data) ? (cur->lchild) : (cur->rchild);}(x < pre->data) ? (pre->lchild = tmp) : (pre->rchild = tmp);}}void BSTree::Remove(int x){if (!m_root){return;}Remove(x, &m_root);}unsigned short BSTree::Size(){return CountSize(m_root);}unsigned short BSTree::Deep(){return CountDeep(m_root);}unsigned short BSTree::Leaf(){return CountLeaf(m_root);}bool BSTree::IsEmpty(){return m_root == NULL;}void BSTree::PreorderTraversal(){PreorderTraversal(m_root);cout << endl;}void BSTree::InorderTraversal(){InorderTraversal(m_root);cout << endl;}void BSTree::PostorderTraversal(){PostorderTraversal(m_root);cout << endl;}void BSTree::DepthFirstSearch(){DepthFirstSearch(m_root);cout << endl;}void BSTree::BreadthFirstSearch(){BreadthFirstSearch(m_root);cout << endl;}



  // main.cpp
// test for BSTree#include "BSTree.h"#include <cstdlib>#include <iostream>using namespace std;int main(){BSTree tree;int arr[6] = {5, 4, 8, 1, 7, 10};for (int i = 0; i < 6; ++i){tree.Insert(arr[i]);}tree.PreorderTraversal();tree.InorderTraversal();tree.PostorderTraversal();tree.DepthFirstSearch();tree.BreadthFirstSearch();tree.Remove(4);tree.PreorderTraversal();tree.Remove(1);tree.PreorderTraversal();tree.Remove(10);tree.PreorderTraversal();cout << "size:" << tree.Size() << endl;cout << "deep:" << tree.Deep() << endl;cout << "leaf:" << tree.Leaf() << endl;system("pause");return 0;}



  // 树的结构
  


  // 运行结果截图


0 0