二叉树

/************************************************
*
*author:周翔
*e-mail:604487178@qq.com
*blog:http://blog.csdn.net/zhx6044
*
*
*************************************************/

#include "linkQueue.hpp"

#ifndef BINARYTREE_HPP
#define BINARYTREE_HPP

#include <iostream>

template <typename T>
class BinaryTree
{
public:
    BinaryTree();
    ~BinaryTree();
    bool isEmpty() const;
    void clear();
    int size() const;
    int height() const;
    void create(T stop);

    void preTraverse(std::ostream &os = std::cout) const;
    void midTraverse(std::ostream &os = std::cout) const;
    void postTraverse(std::ostream &os = std::cout) const;


private:
    struct node{
        T d;
        node* lc,*rc;
        node():lc(0),rc(0){

        }
        node(const T &t, node* _lc = 0, node* _rc = 0):
            d(t),
            lc(_lc),
            rc(_rc) {

        }
        ~node(){}
    };

    node *root;

    void clear(node *t) const;
    int size(node *t) const;
    int height(node *t) const;
    void preTraverse(node *t, std::ostream &os = std::cout) const;
    void midTraverse(node *t, std::ostream &os = std::cout) const;
    void postTraverse(node *t, std::ostream &os = std::cout) const;
};


template <typename T>
BinaryTree<T>::BinaryTree():
    root(0)
{

}

template <typename T>
BinaryTree<T>::~BinaryTree()
{
    if(!isEmpty()) {
        clear();
    }

}


template <typename T>
bool BinaryTree<T>::isEmpty() const
{
    return root == 0;
}

template <typename T>
void BinaryTree<T>::clear(node *t) const
{
    if (t->lc != 0) {
        clear(t->lc);
    }
    if (t->rc != 0) {
        clear(t->rc);
    }
    delete t;
}

template <typename T>
int BinaryTree<T>::size(node *t) const
{
    if (t == 0) return 0;
    return 1 + size(t->lc) + size(t->rc);

}

template <typename T>
int BinaryTree<T>::height(node *t) const
{
    if (t == 0) return 0;
    int i = height(t->lc);
    int j = height(t->rc);
    //高度为来个子树中高度较大的加一
    return 1 + ( i > j ? i : j );
}

template <typename T>
void BinaryTree<T>::clear()
{
    clear(root);
}

template <typename T>
int BinaryTree<T>::size() const
{
    return size(root);
}

template <typename T>
int BinaryTree<T>::height() const
{
    return height(root);
}

template <typename T>
void BinaryTree<T>::preTraverse(node *t, std::ostream &os) const
{
    if (t != 0) {
        os << t->d << "   ";
        preTraverse(t->lc);
        preTraverse(t->rc);
    }

}

template <typename T>
void BinaryTree<T>::midTraverse(node *t, std::ostream &os) const
{
    if (t != 0) {
        midTraverse(t->lc);
        os << t->d << "  ";
        midTraverse(t->rc);
    }

}

template <typename T>
void BinaryTree<T>::postTraverse(node *t, std::ostream &os) const
{
    if (t != 0) {
        postTraverse(t->lc);
        postTraverse(t->rc);
        os << t->d << "   ";
    }


}

template <typename T>
void BinaryTree<T>::preTraverse(std::ostream &os) const
{
    if (!isEmpty()) {
        preTraverse(root,os);
    }
}

template <typename T>
void BinaryTree<T>::midTraverse(std::ostream &os) const
{
    if (!isEmpty()) {
        midTraverse(root,os);
    }
}

template <typename T>
void BinaryTree<T>::postTraverse(std::ostream &os) const
{
    if (!isEmpty()) {
        postTraverse(root,os);
    }
}

template <typename T>
/**
 * @brief BinaryTree<T>::create 从上到下按层创建
 * @param stop 结束符
 */
void BinaryTree<T>::create(T stop)
{
    LinkQueue<node*> queue;
    T x,l,r;
    node* t;
    std::cout << "输入根节点:\n";
    std::cin >> x;
    root = new node(x);
    queue.enqueue(root);
    while (!queue.isEmpty()) {
        t = queue.dequeue();
        std::cout << "输入" << "节点" << t->d << "的两个孩子,没有则输入" << stop << '\n';
        std::cin >> l >> r;
        if (l != stop) queue.enqueue(t->lc = new node(l));
        if (r != stop) queue.enqueue(t->rc = new node(r));
    }

}


#endif // BINARYTREE_HPP

之后撸的加上

template <typename T>
void BinaryTree<T>::preTraverse2(std::ostream &os) const
{
    if (isEmpty()) {
        os << "这是一颗空树!\n";
    } else {
        LinkStack<node*> stack;
        stack.push(root);
        while(!stack.isEmpty()) {
            node *t = stack.pop();
            os << t->d << "  ";
            //先压右子树再压左子树,这样左子树在上可以先遍历
            if (t->rc != 0)  stack.push(t->rc);
            if (t->lc != 0)  stack.push(t->lc);
        }
    }
}

template <typename T>
/**
 * @brief BinaryTree<T>::midTraverse2
 * @param os
 *
 *
 *
 * 根节点第一次出栈,然后进栈,左子树进栈,然后遍历左子树,根节点第二次出栈,右子树进栈
 *
 */
void BinaryTree<T>::midTraverse2(std::ostream &os) const
{
    if (isEmpty()) {
        os << "这是一颗空树!\n";
    } else {
        LinkStack<elemt> stack;
        stack.push(elemt(root));
        while(!stack.isEmpty()) {
            elemt t = stack.pop();
            if (++t.step == 2) {
                os << t.n->d << "   ";
                if (t.n->rc != 0) {
                    stack.push(elemt(t.n->rc));
                }
            } else {
                stack.push(t);
                if(t.n->lc != 0) {
                    stack.push(t.n->lc);
                }
            }
        }

    }

}


template <typename T>
/**
 * @brief BinaryTree<T>::postTraverse2
 * @param os
 *
 *
 *
 * 根节点第一次出栈进栈,左子树进栈,第二次进栈出栈,右子树进栈,第三次出栈
 */
void BinaryTree<T>::postTraverse2(std::ostream &os) const
{
    if (isEmpty()) {
        os << "这是一颗空树!\n";
    } else {
        LinkStack<elemt> stack;
        stack.push(elemt(root));
        while(!stack.isEmpty()) {
            elemt t = stack.pop();
            if (++t.step == 3) {
                os << t.n->d << "   ";
            } else {
                if (t.step == 2) {
                    stack.push(t);
                    if(t.n->rc != 0) {
                        stack.push(t.n->rc);
                    }
                } else {
                    stack.push(t);
                    if(t.n->lc != 0) {
                        stack.push(t.n->lc);
                    }
                }

            }
        }
    }
}


template <typename T>
/**
 * @brief BinaryTree<T>::changeChildrens 交换子节点,使用一个队列完成
 */
void BinaryTree<T>::changeChildrens()
{
    LinkQueue<node*> queue;
    queue.enqueue(root);
    while(!queue.isEmpty()) {
        node *t = queue.dequeue();
        if (t != NULL) {
            queue.enqueue(t->lc);
            queue.enqueue(t->rc);//将两个字节点入队
            node *t2 = t->lc;//交换子节点
            t->lc = t->rc;
            t->rc = t2;
        }
    }
}


template <typename T>
void BinaryTree<T>::levelTraverse(std::ostream &os) const
{
    LinkQueue<node*> queue;
    queue.enqueue(root);
    while(!queue.isEmpty()) {
        node *t = queue.dequeue();
        if (t != NULL) {
            os << t->d << "  ";
            queue.enqueue(t->lc);
            queue.enqueue(t->rc);
        }
    }
}

template <typename T>
int BinaryTree<T>::degreeTwo() const
{
    int re = 0;
    if (isEmpty()) {
    } else {
        LinkQueue<node*> queue;
        queue.enqueue(root);
        while(!queue.isEmpty()) {
            node *t = queue.dequeue();
            if (t->lc != NULL) {
                queue.enqueue(t->lc);
                if (t->rc != NULL) {
                    queue.enqueue(t->rc);
                    ++re;
                }
            } else {
                if (t->rc != NULL) {
                    queue.enqueue(t->rc);
                }
            }
        }
    }
    return re;
}

template <typename T>
/**
 * @brief BinaryTree<T>::completeBT 将树作为完全二叉树考虑构件,最后看结论是否矛盾(反证法)
 * @return
 */
bool  BinaryTree<T>::completeBT() const
{
    LinkQueue<elemt> queue;
    elemt t,tc;
    int c = 1;//节点的个数
    int l = 1;//最后节点编号
    //root编号为1,根据性质5,如果是完全二叉树则节点个数等于最后节点的编号
    if (isEmpty()) return true;//空树是完全二叉树
    t.n = root;
    t.step = 1;
    queue.enqueue(t);
    while (!queue.isEmpty()) {
        t = queue.dequeue();
        if (t.n->lc != NULL) {
            ++c;
            tc.n = t.n->lc;
            l = tc.step = t.step * 2;//完全二叉树性质5
            queue.enqueue(tc);
        }
        if (t.n->rc != NULL) {
            ++c;
            tc.n = t.n->rc;
            l = tc.step = t.step * 2 + 1;
            queue.enqueue(tc);
        }

    }
    return c == l;
}

template <typename T>
/**
 * @brief BinaryTree<T>::isEqual
 * @param t1
 * @param t2
 * @return
 *
 *
 *写递归主要是找出递归出口,这个有三个出口,值不同和形状不同,和都是空节点
 */
bool BinaryTree<T>::isEqual(BinaryTree::node *t1, BinaryTree::node *t2)
{
    //形状,值相同,最后如果相同是以形状出口
    if (t1 == NULL && t2 == NULL) return true;
    if (t1 == NULL || t2 == NULL) return false;
    //值不同,直接出口
    if (t1->d != t2->d) return false;
    //值相同,再看形状,可以是值出口和形状出口
    return isEqual(t1->lc, t2->lc) && isEqual(t1->rc, t2->rc);

}

template <typename T>
bool operator == (const BinaryTree<T> &bt1, const BinaryTree<T> &bt2)
{
    return BinaryTree<T>::isEqual(bt1.root,bt2.root);
}


template <typename T>
/**
 * @brief BinaryTree<T>::mirror 树是镜像的吗,左右子树对称
 * @return
 */
bool BinaryTree<T>::mirror() const
{
    if (isEmpty()) return false;
    return isMirror(root->lc,root->rc);
}

template <typename T>
bool BinaryTree<T>::isMirror(BinaryTree::node *t1, BinaryTree::node *t2)
{
    if (t1 == NULL && t2 == NULL) return true;
    if (t1 == NULL || t2 == NULL) return false;
    if (t1->d != t2->d) return false;

    return isMirror(t1->lc, t2->rc) && isMirror(t1->rc, t2->lc);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值