您的位置:首页 > 其它

二叉查找树_前序遍历_中序_后序_递归与非递归写法_层次遍历_以及树形显示

2016-10-29 21:31 417 查看
#include <iostream>
#include <stack>
using namespace std;

template<typename T>
struct BinaryNode
{
T element;
BinaryNode<T> *left;
BinaryNode<T> *right;

BinaryNode(const T &theElement, BinaryNode *lt, BinaryNode *rt)
: element(theElement), left(lt), right(rt) {}
};

template<typename T>
class BinarySearchTree
{
public:
BinarySearchTree() {
root = nullptr;
}
BinarySearchTree(const BinarySearchTree& rhs) {  //复制构造函数
root = clone(rhs.root);
}
~BinarySearchTree();

const T &findMin() const {
return findMin(root)->element;
}
const T &findMax() const {
return findMax(root)->element;
}

bool contains(const T& x) const;
T& getNode(const T& e) {                        //得到元素为e的结点
return getNode(e, root)->element;
}

bool isEmpty() const {
if (root == nullptr)
return true;
return false;
}
void PreprintTree() const {
PreprintTree(root);
}

void InprintTree() const {
InprintTree(root);
}

void PostprintTree() const {
PostprintTree(root);
}

void LevelprintTree() const {
LevelprintTree(root);
}

void PreprintTree_N() const {
PreprintTree_N(root);
}

void InprintTree_N() const {
InprintTree_N(root);
}

void PostprintTree_N() const {
PostprintTree_N(root);
}

void DisplayTreeShape(int level = 1) const {
DisplayTreeShape(root, level);
}

void makeEmpty();
void insert(const T &x);
void remove(const T &x);
int Depth();
int CountLeaf() {
BinaryNode<T> *p = root;
int count = 0;
CountLeaf(p, count);
return count;
}

const BinarySearchTree& operator = (const BinarySearchTree& rhs);

private:

BinaryNode<T> *root;                      //指向树根结点的指针

void insert(const T & x, BinaryNode<T> * & t);
void remove(const T & x, BinaryNode<T> * & t);
BinaryNode<T> * findMin(BinaryNode<T> *t) const;
BinaryNode<T> * findMax(BinaryNode<T> *t ) const;

bool contains(const T & x, BinaryNode<T> *t) const;
BinaryNode<T> * getNode(const T &x, BinaryNode<T> *t);

void makeEmpty( BinaryNode<T> * & t );
//利用 递归 算法 计算树的 深度
int Depth( BinaryNode<T> * t, int level, int &depth);
//利用 递归 算法 计算树的 高度
void CountLeaf(BinaryNode<T> * t, int &count);

void PreprintTree( BinaryNode<T> * t ) const;           //先序遍历
void InprintTree( BinaryNode<T> *t ) const;             //中序遍历
void PostprintTree( BinaryNode<T> * t ) const;          //后序遍历
void LevelprintTree( BinaryNode<T> * t) const;          //层次遍历

void PreprintTree_N( BinaryNode<T> * t) const;          //非递归先序遍历
void InprintTree_N( BinaryNode<T> * t) const;           //非递归中序遍历二叉树
void PostprintTree_N( BinaryNode<T> * t) const;         //非递归后序遍历二叉树
void DisplayTreeShape(BinaryNode<T> *bt, int level) const;    //二叉树的树形显示算法

BinaryNode<T> * clone( BinaryNode<T> * t ) const;
};

template<typename T>
bool BinarySearchTree<T>::contains(const T& x) const
{
return contains(x, root);
}

template<typename T>
bool BinarySearchTree<T>::contains(const T & x, BinaryNode<T> *t) const
{
if (t == nullptr)
return false;
else if (x < t->element)          // x 小, 说明应该在左边找
return contains(x, t->left);
else if (t->element < x)          // x 大, 说明应该在右面找
return contains(x, t->right);
else
return true;
}

template<typename T>
BinaryNode<T>* BinarySearchTree<T>::getNode(const T & x, BinaryNode<T> *t)
{
if (t == nullptr)
return nullptr;
else if (x < t->element)
return getNode(x, t->left);
else if (t->element < x)
return getNode(x, t->right);
return t;
}

//findMin--返回指向树中包含最小元的结点的指针
template<typename T>
BinaryNode<T> * BinarySearchTree<T>::findMin(BinaryNode<T> *t) const
{
if (t == nullptr)
return  nullptr;
if (t->left == nullptr)
return t;
return findMin(t->left);
}

template<typename T>
BinaryNode<T>* BinarySearchTree<T>::findMax(BinaryNode<T> *t) const
{
if (t != nullptr)
while (t->right != nullptr) {
t = t->right;
}
return t;
}

template<typename T>
void BinarySearchTree<T>::insert(const T &x)
{
insert(x, root);
}

/************************************************************************/
/* x is the item to insert        */
/* t is the node that roots the subtree*/
/* Set the new root of the subtree*/
///* 只有当一个新树叶生成时候,t才改变.
///* t 是到p->left或p->right的引用.==> 意味着p->left或p->right将会改变为指向新结点.
/************************************************************************/
template<typename T>
void BinarySearchTree<T>::insert(const T & x, BinaryNode<T> * & t)
{
if (t == nullptr)         //没有结点,在该位置处添加新结点
t = new BinaryNode<T>(x, nullptr, nullptr);
else if (x < t->element)  //x 小, 在左子树查询
insert(x, t->left);
else if (t->element < x)  //x 大, 在右子树查询
insert(x, t->right);
else;                     //Duplicate, do nothing;
}

template<typename T>
void BinarySearchTree<T>::remove(const T &x)
{
remove(x, root);
}

/************************************************************************/
/* x is item to remove                                                  */
/* t is the node that roots the subtree                                 */
/* Set the new root of the subtree                                      */
/* 1.结点是一片树叶时 -- 可被立即删除*/
/* 2.结点有一个儿子, 则该结点可以在其父节点调整他的链 以绕过该结点后被删除 */
/* 3.结点有两个儿子, 则其右子树的最小数据代替该结点的数据,并递归删除那个结点 */
/* 注: 右子树中的最小的结点不可能有左结点                               */
/************************************************************************/
template<typename T>
void BinarySearchTree<T>::remove(const T &x, BinaryNode<T> * & t)
{
if (t == nullptr) return;     //Item not found; do nothing
if (x < t->element)           //x 小,在左子树递归查找
remove(x, t->left);
else if (t->element < x)      //x 大,在右子树递归查找
remove(x, t->right);
else if (t->left != nullptr && t->right != nullptr)  //two children
{
//在右子树中查找最小数据代替该结点数据.;
t->element = findMin(t->right)->element;
remove(t->element, t->right);                    //删除该结点
}
else                         //只有一个结点或是树叶. 调整它的链,以绕过该结点后被删除.
{
BinaryNode<T> *oldNode = t;
t = (t->left != nullptr) ? t->left : t->right;
delete oldNode;
}
}

/************************************************************************/
///* Destructor for the tree
/************************************************************************/
template<typename T>
BinarySearchTree<T>::~BinarySearchTree()
{
makeEmpty();
}

template<typename T>
void BinarySearchTree<T>::makeEmpty()       //公有函数
{
makeEmpty(root);
}

/************************************************************************/
///* Internal method to make subtree empty -- 私有函数
/************************************************************************/
template<typename T>
void BinarySearchTree<T>::makeEmpty(BinaryNode<T> * & t)
{
if (t != nullptr)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = nullptr;
}

/************************************************************************/
///* Deep copy
/************************************************************************/
template<typename T>
const BinarySearchTree<T>& BinarySearchTree<T>::operator = (const BinarySearchTree &rhs)
{
if (this != &rhs) {
makeEmpty();
root = clone(rhs.root);
}
return *this;
}

/************************************************************************/
///* Internal method to clone subtree.  --  递归复制结点
/************************************************************************/
template<typename T>
BinaryNode<T>* BinarySearchTree<T>::clone(BinaryNode<T> * t) const
{
if (t == nullptr)
return nullptr;
return new BinaryNode<T>( t->element, clone(t->left), clone(t->right) );
}

//利用递归计算树的深度
template<typename T>
int BinarySearchTree<T>::Depth()
{
BinaryNode<T> *t = root;
int depth = 0;
if (root == nullptr)
return 0;
Depth(t, 1, depth);
return depth;
}

//由public的函数Depth调用, 完成树的深度的计算,p是根结点,Level是层,depth用来返回树的深度
template<typename T>
int BinarySearchTree<T>::Depth(BinaryNode<T> *t, int level, int &depth)
{
if (level > depth) depth = level;                  //层数
if (t->left) Depth(t->left, level + 1, depth);     //递归遍历左子树,且层数加1
if (t->right) Depth(t->right, level + 1, depth);   //递归遍历右子树, 且层数加1
return 0;
}

template<typename T>
//利用 递归 算法 计算树的 高度
void BinarySearchTree<T>::CountLeaf(BinaryNode<T> * t, int &count)
{
if (t == nullptr) return;               //为空时,退出

//    CountLeaf(t->left, count);
//    CountLeaf(t->right, count);
if (!(t->left) && !(t->right)) {        //儿子为空时
count++;
}
CountLeaf(t->left, count);
CountLeaf(t->right, count);
}

/************************************************************************/
///* printTree   ---    前序遍历
/************************************************************************/
template<typename T>
void BinarySearchTree<T>::PreprintTree(BinaryNode<T> * t) const
{
if (t != nullptr) {
cout << t->element << ' ';
PreprintTree(t->left);
PreprintTree(t->right);
}
}

//中序遍历
template<typename T>
void BinarySearchTree<T>::InprintTree(BinaryNode<T> * t ) const
{
if (t != nullptr) {
InprintTree(t->left);
cout << t->element << ' ';
InprintTree(t->right);
}
}

//后序遍历
template<typename T>
void BinarySearchTree<T>::PostprintTree(BinaryNode<T> * t) const
{
if (t != nullptr) {
PostprintTree(t->left);
PostprintTree(t->right);
cout << t->element << ' ';
}
}

//利用队列Queue层次遍历二叉树
template<typename T>
void BinarySearchTree<T>::LevelprintTree( BinaryNode<T> * t) const
{
const int maxn = 1024;
BinaryNode<T> *Queue[maxn];                          //一维数组作为队列
BinaryNode<T> *tmp;
int front = 0, rear = 0;                             //队列初始为空
if (root) {
Queue[rear++] = root;                            //二叉树的根结点指针入队列
while (front != rear)
{
tmp = Queue[front++];                        //队首的元素出队列
if (tmp) cout << tmp->element << ' ';        //输出结点值
if (tmp->left) Queue[rear++] = tmp->left;
if (tmp->right) Queue[rear++] = tmp->right;
}
}
}

//先序遍历
template<typename T>
void BinarySearchTree<T>::PreprintTree_N( BinaryNode<T> * t) const          //非递归先序遍历
{
const int maxn = 1024;
BinaryNode<T> *Stack[maxn];
int top = 0;
BinaryNode<T> *tmp = root;            //将根结点的指针赋值给tmp

//    cout << "Debug :\n";
while (tmp || top != 0)
{
//        cout << "debug : \n";
while (tmp) {
cout << tmp->element << ' ';
Stack[top++] = tmp;           //右孩子入栈
tmp = tmp->left;              //一直递归到最左的结点
}
if (top) {                        //栈不为空, 从栈中取出一个结点指针
tmp = Stack[--top];
tmp = tmp->right;
}
}
}

//中序非递归遍历二叉树 (LDR)
template<typename T>
void BinarySearchTree<T>::InprintTree_N( BinaryNode<T> * t) const           //非递归中序遍历二叉树
{
const int maxn = 1024;
BinaryNode<T> *Stack[maxn];
int top = 0;
BinaryNode<T> *tmp = root;

while (tmp || top != 0)
{
while (tmp) {                  //迭代到最左的子树
Stack[top++] = tmp;        //左子树入栈
tmp = tmp->left;
}
if (top) {
tmp = Stack[--top];            //出栈最左的子树
cout << tmp->element << ' ';   //输出该元素
tmp = tmp->right;              //并指向右结点开始迭代
}
}

}

//非递归后序遍历二叉树 (LRD)
template<typename T>
void BinarySearchTree<T>::PostprintTree_N( BinaryNode<T> * t) const
{
const int maxn = 1024;
struct Mystack {
BinaryNode<T> * link;
int flag;
};

Mystack Stack[maxn];
BinaryNode<T> * p = root, *tmp;

if (root == nullptr) return;

int top = -1,                  //栈顶初始化
sign = 0;                  //为结点tmp 的标志量

while ( p != nullptr || top != -1)
{
while (p != nullptr)       //遍历到最左
{
Stack[++top].link = p; //并且一直入栈
Stack[top].flag = 1;   //设置flag为第一次入栈
p = p->left;
}

if (top != -1)
{
tmp = Stack[top].link;
sign = Stack[top].flag;
top--;                 //出栈

if (sign == 1)         //结点第一次进栈
{
top++;
Stack[top].link = tmp;
Stack[top].flag = 2;            //标记为第二次出栈
p = tmp->right;
}
else {                 //第二次出栈就输出
cout << tmp->element << ' ';      //访问该结点数据域
p = nullptr;
}
}

}

}

//树形显示二叉树,也是中序遍历
template<typename T>
void BinarySearchTree<T>::DisplayTreeShape(BinaryNode<T> *bt, int level) const
{
if (bt)                                         //二叉树的树形显示算法
{
cout << endl;
for (int i = 0; i < level - 1; i++)
cout << "   ";                            //确保在第level列显示结点
cout << bt->element;                        //显示结点
DisplayTreeShape(bt->left, level - 1);     //空二叉树不显示
//        cout << endl;                               //显示右子树
DisplayTreeShape(bt->right, level + 2);      //显示左子树
}
}

int main()
{
//    srand((unsigned)time(nullptr));
int testData, t = 0;
BinarySearchTree<int> test;
cout << "输入数字个数: \n";
cin >> t;
cout << "输入数字: \n";
while (t--)
{
testData = rand() % 500 + 1;
test.insert(testData);
}
cout << "\n全部元素为: \n";
test.PreprintTree();

cout << endl;
//    cin >> testData;                //不符合查找二叉树
//    test.getNode(testData) = 10000;

cout << "\nMax = " << test.findMax() << endl;
cout << "Min = " << test.findMin() << endl;

cout << "输入查找元素: \n";
cin >> testData;
cout << "是否包含 " << testData  << " : " << test.contains(testData) << endl;
test.PreprintTree();

cout << endl;
cout << "输入删除元素: \n";
cin >> testData;
test.remove(testData);

cout << "\n树的高度: " << test.Depth() << endl;
cout << "\n叶子的个数: " << test.CountLeaf() << endl;
cout << endl;

cout << "先序遍历树元素: \n";
test.PreprintTree();

cout << "\n\n中序遍历树元素: \n";
test.InprintTree();

cout << "\n\n后序遍历树元素: \n";
test.PostprintTree();

cout << "\n\n层次遍历树元素: \n";
test.LevelprintTree();

cout << "\n\n先序遍历树元素(非递归): \n";
test.PreprintTree_N();

cout << "\n\n中序遍历树元素(非递归): \n";
test.InprintTree_N();

cout << "\n\n后序遍历树元素(非递归): \n";
test.PostprintTree_N();

cout << "\n\n二叉树的树形显示算法: \n";
test.DisplayTreeShape(43);

cout << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐