/***************************
运行环境 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 <cstdlib>
#include <iostream>
#include <iomanip>
using namespace std;
template <class TreeDataType>
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 <class TreeDataType>
inline void BSTree<TreeDataType>::deleteNode(BSTree<TreeDataType>::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 <class TreeDataType>
inline void BSTree<TreeDataType>::insertAux(BSTree<TreeDataType>::BSTNodePointer& a_subRoot, const TreeDataType& a_data)
{/*/ 递归 插入结点 /*/
if (a_subRoot == NULL)
{
a_subRoot = new BSTree<TreeDataType>::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 <class TreeDataType>
inline void BSTree<TreeDataType>::inorderAux(ostream& out, BSTree<TreeDataType>::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 <class TreeDataType>
inline void BSTree<TreeDataType>::graphAux(ostream& out, int a_indent, BSTree<TreeDataType>::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 <class TreeDataType>
inline bool BSTree<TreeDataType>::find(const TreeDataType& a_data) const
{
BSTree<TreeDataType>::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 <class TreeDataType>
inline void BSTree<TreeDataType>::find2(const TreeDataType& a_data, bool& found,
BSTree<TreeDataType>::BSTNodePointer& a_locPtr,
BSTree<TreeDataType>::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 <class TreeDataType>
inline void BSTree<TreeDataType>::remove(const TreeDataType& a_data)
{
bool found = false;
BSTree<TreeDataType>::BSTNodePointer x; //被删除的节点
BSTree<TreeDataType>::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<TreeDataType>::BSTNodePointer xSucc = x->right;
parent = x;
while (xSucc->left != NULL)/*/ 在右中找最左的元素/*/
{
parent = xSucc;
xSucc = xSucc->left;
}
x->data = xSucc->data; /*/ 替换要删除的结点数据/*/
x = xSucc; /*/ 转向这个替死鬼/*/
}
BSTree<TreeDataType>::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 <cstdlib>
#include <iostream>
using namespace std;
/*/
int test()
{
/*/
数据准备 int a[]
/*/
int a[]={1,3,5,7,9,2,4,6,8,-999};
int i=0;
BSTree<int> 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):"<<endl;
number=a[i];
if (number == -999) break;
intBST.remove(a[i]);
intBST.graph(cout);
cout << endl;
}
intBST.inorder(cout);
}
void use()
{
BSTree<int> 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):"<<endl;
cin >> 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;
}
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。