基于我的另一篇文章《算法与数据结构基础4:C++二叉树实现及遍历方法大全》 ,二叉树的结构用的这篇文章里的。
二查找叉树的删除可以细分为三种情况:
1 被删除的是叶子节点,直接删除;
2 被删除只有一个子节点,指针下移;
3 有两个子节点,为了不破坏树的结构,需要找出一个节点来替换当前节点。
根据二叉树的特点,当前节点大于所有左子树,小于所有右子树,
可以用左子树中最大的节点,或者右子树最小的节点来替换当前节点,然后删除替换节点。
// BSTree.h
#include <cstdio> #include <iostream> #include <stack> #include <queue> using namespace std; // binary search tree,中文翻译为二叉搜索树、二叉查找树或者二叉排序树。简称为BST class 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; }
// 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; }
原文地址:http://blog.csdn.net/xufeng0991/article/details/41862827