/*************************** 运行环境 http://www.anycodes.cn/zh/ 原文件 http://www.cnblogs.com/hanxi/archive/2012/08/18/2645929.html 带注释的C++类版本 BST 二叉搜索树 ***************************/ #ifndef BTREE_H_ #define BTREE_H_ #include#include #include using namespace std; template class BSTree { private: class BSTNode { public: BSTNode* left; BSTNode* right; TreeDataType data; BSTNode():left(NULL),right(NULL) {} BSTNode(TreeDataType a_data):data(a_data),left(NULL),right(NULL) {} };//节点声明 typedef BSTNode* BSTNodePointer; BSTNodePointer m_root; public: BSTree():m_root(NULL) {} ~BSTree() {deleteNode(m_root);} bool isEmpty() const {return m_root == NULL;} bool find(const TreeDataType& a_data) const; void insert(const TreeDataType& a_data) {insertAux(m_root,a_data);} void remove(const TreeDataType& a_data); void inorder(ostream& out) const {inorderAux(out, m_root);} void graph(ostream& out) const {graphAux(out, 0, m_root);} protected: void deleteNode(BSTNodePointer a_node);/*/删除节点和所有到子节点/*/ void insertAux(BSTNodePointer& a_subRoot, const TreeDataType& a_data); void inorderAux(ostream& out, BSTNodePointer a_subRoot) const; void graphAux(ostream& out, int a_indent, BSTNodePointer a_subRoot) const; void find2(const TreeDataType& a_data, bool& found, BSTNodePointer& a_locPtr, BSTNodePointer& a_parent) const; };/*/类模板声明结束/*/ #endif template inline void BSTree ::deleteNode(BSTree ::BSTNodePointer a_node) {/*/递归删除结点/*/ if (a_node->left != NULL) { deleteNode(a_node->left); } else if (a_node->right != NULL) { deleteNode(a_node->right); } else if (a_node != NULL) { delete a_node; a_node = NULL; } } template inline void BSTree ::insertAux(BSTree ::BSTNodePointer& a_subRoot, const TreeDataType& a_data) {/*/ 递归 插入结点 /*/ if (a_subRoot == NULL) { a_subRoot = new BSTree ::BSTNode(a_data); } else if (a_data < a_subRoot->data) { insertAux(a_subRoot->left,a_data); } else if (a_subRoot->data < a_data) { insertAux(a_subRoot->right,a_data); } else {/*/不能有相同的结点/*/ std::cerr << "a_data already in the tree!\n"; } } template inline void BSTree ::inorderAux(ostream& out, BSTree ::BSTNodePointer a_subRoot) const {/*/LDR中序遍历/*/ if (a_subRoot != NULL) { inorderAux(out, a_subRoot->left);//L out << a_subRoot->data << " ";//V inorderAux(out, a_subRoot->right);//R } } template inline void BSTree ::graphAux(ostream& out, int a_indent, BSTree ::BSTNodePointer a_subRoot) const {/*/图表式打印树/*/ if (a_subRoot != NULL) { graphAux(out, a_indent+8, a_subRoot->right); //R out << setw(a_indent) << " " << a_subRoot->data << endl; //V graphAux(out, a_indent+8, a_subRoot->left); //L } } template inline bool BSTree ::find(const TreeDataType& a_data) const { BSTree ::BSTNodePointer locPtr = m_root; bool found = false; while (!found && locPtr != NULL) { if (a_data < locPtr->data) { locPtr = locPtr->left; } else if (locPtr->data < a_data) { locPtr = locPtr->right; } else { found = true; } } return found; } template inline void BSTree ::find2(const TreeDataType& a_data, bool& found, BSTree ::BSTNodePointer& a_locPtr, BSTree ::BSTNodePointer& a_parent) const {/*/ 这里不仅要找 还要找到p结点 已便于后期 删除找到的结点 /*/ a_locPtr = m_root; a_parent = NULL; found = false; while (!found && a_locPtr != NULL) { if (a_data < a_locPtr->data) { a_parent = a_locPtr; a_locPtr = a_locPtr->left; } else if (a_locPtr->data < a_data) { a_parent = a_locPtr; a_locPtr = a_locPtr->right; } else { found = true; } } } template inline void BSTree ::remove(const TreeDataType& a_data) { bool found = false; BSTree ::BSTNodePointer x; //被删除的节点 BSTree ::BSTNodePointer parent; find2(a_data,found,x,parent); if (!found) { std::cerr << "a_data is not in the tree!\n"; return; } if (x->left != NULL && x->right != NULL)//节点有两个子女 { //查找x的中续后继节点及其双亲节点 BSTree ::BSTNodePointer xSucc = x->right; parent = x; while (xSucc->left != NULL)/*/ 在右中找最左的元素/*/ { parent = xSucc; xSucc = xSucc->left; } x->data = xSucc->data; /*/ 替换要删除的结点数据/*/ x = xSucc; /*/ 转向这个替死鬼/*/ } BSTree ::BSTNodePointer subTree = x->left; if (subTree == NULL) /*/ 看替死鬼的情况 /*/ { subTree = x->right; } if (parent == NULL) { m_root = subTree; } else if (parent->left == x) { parent->left = subTree; /*/替死鬼的右做p的左 /*/ } else { parent->right = subTree; /*/替死鬼是p的右孩子,将右孩子做p的右孩子 /*/ } delete x; } /*/ -----------文件分割线-------"BSTree.h"---------------- #include "BSTree.h" #include #include using namespace std; /*/ int test() { /*/ 数据准备 int a[] /*/ int a[]={1,3,5,7,9,2,4,6,8,-999}; int i=0; BSTree intBST; cout << "Constructing empty BST\n"; cout << "BST " << (intBST.isEmpty()?"is":"is not") << "empty\n"; int number; for (;;) { number=a[i++]; if (number == -999) break; intBST.insert(number); } intBST.inorder(cout); cout << endl; intBST.graph(cout); //测试find for (i=0;;i++) { cout << "Item to find (-999 to stop):"; number=a[i]; if (number == -999) break; bool found = intBST.find(number); cout << boolalpha << found << endl; } //测试remove for (i=0;;i++) { cout << "Item to remove (-999 to stop):"< intBST; cout << "Constructing empty BST\n"; cout << "BST " << (intBST.isEmpty()?"is":"is not") << "empty\n"; int number; for (;;) { cout << "Item to insert (-999 to stop):"< > number; if (number == -999) break; intBST.insert(number); } intBST.inorder(cout); cout << endl; intBST.graph(cout); //测试find for (;;) { cout << "Item to find (-999 to stop):"; cin >> number; if (number == -999) break; bool found = intBST.find(number); cout << boolalpha << found << endl; } //测试remove for (;;) { cout << "Item to remove (-999 to stop):"; cin >> number; if (number == -999) break; intBST.remove(number); cout << endl; intBST.graph(cout); cout << endl; } intBST.inorder(cout); } int main() { test(); return 0; }