C++實現二叉樹

其中的 linkStack.h 和 linkQueue 分別在 以下兩篇博文裏:linkStack 、linkQueue

#include <iostream>
#include "linkStack.h"
#include "linkQueue.h"

using namespace std;

//定義節點
template<class T>
struct node
{
    T data;    //結點中保存的數據
    node *left;    //結點的左兒子
    node *right;    //結點的右兒子
    node():left(NULL),right(NULL){}    //構造函數,無參數
    //構造函數,帶參數
    node(const T &x,node *l=NULL,node *r=NULL):data(x),left(l),right(r){}     
    ~node(){}    //析構函數
};

//定義二叉樹
template<class T>
class BT
{
    public:
      BT();    //構造空二叉樹
      BT(const T &x);    //構造以數據值爲x的結點爲根結點的二叉樹
      BT(const node<T> *p);    //構造以p爲根結點的二叉樹
      node<T> * getRoot();    //返回根結點地址
      //創建一個以數據值爲x的結點爲根結點,以lt爲左子樹、rt爲右子樹的二叉樹
      void makeTree(const T &x,BT <,BT &rt);
      void delLeft();    //刪除左子樹
      void delRight();    //刪除右子樹
      bool empty() const;    //判斷是否爲空樹
      void clear();    //刪除二叉樹
      int size() const;    //求二叉樹的規模
      int height() const;    //求二叉樹的高度
      int leafCount() const;    //求二叉樹葉子結點個數
      void preOrder() const;    //前序遍歷二叉樹
      void midOrder() const;    //中序遍歷二叉樹
      void postOrder() const;    //後續遍歷二叉樹
      void levelOrder() const;    //層次遍歷二叉樹
      bool isCompBT() const;    //判斷是否爲完全二叉樹
      void createTree(T flag);    //創建二叉樹,輸入flag表示爲空
      void copyTree(BT &tree);    //複製二叉樹
      ~BT();    //析構函數
    private:
      node<T> *root;    //二叉樹的根結點
      void clear(node<T> *t);    //刪除以t爲根結點的二叉樹
      int size(node<T> *t) const;    //求以t爲根結點的二叉樹的規模
      int height(node<T> *t) const;    //求以t爲根結點的二叉樹的高度
      //複製以t爲根結點的二叉樹爲以r爲根結點的新二叉樹
      void copyTree(node<T> *&r,node<T> *t);    
};

/*二叉樹的實現*/

//構造空二叉樹
template <class T>
BT<T>::BT()
{
    root=NULL;
}

//構造以數據值爲x的結點爲根結點的二叉樹
template <class T>
BT<T>::BT(const T &x)
{
    root=new node<T>(x);
}

//構造以p爲根結點的二叉樹
template <class T>
BT<T>::BT(const node<T> *p)
{
    root=p;
}

//返回根結點地址
template <class T>
node<T> * BT<T>::getRoot()
{
    return root;
}

//創建一個以數據值爲x的結點爲根結點,以lt爲左子樹、rt爲右子樹的二叉樹
template <class T>
void BT<T>::makeTree(const T &x,BT <,BT &rt)
{
    root=new node<T>(x,lt.root,rt.root);
    lt.root=NULL;
    rt.root=NULL;
}

//刪除左子樹
template <class T>
void BT<T>::delLeft()
{
    if(root&&root->left)
    {
        BT tmp=root->left;
        root->left=NULL;
        tmp.clear();
    }
}

//刪除右子樹
template <class T>
void BT<T>::delRight()
{
    if(root&&root->right)
    {
        BT tmp=root->right;
        root->right=NULL;
        tmp.clear();
    }
}

//判斷是否爲空樹
template <class T>
bool BT<T>::empty() const
{
    return root==NULL;
}

//刪除二叉樹
template <class T>
void BT<T>::clear()
{
    if(root)
    {
        clear(root);
        root=NULL;
    }
}

//刪除以t爲根結點的二叉樹
template <class T>
void BT<T>::clear(node<T> *t)
{
    if(t)
    {
        if(t->left) clear(t->left);
        if(t->right) clear(t->right);
        delete t;
    }
}

//求二叉樹的規模
template <class T>
int BT<T>::size() const
{
    return size(root);
}

//求以t爲根結點的二叉樹的規模
template <class T>
int BT<T>::size(node<T> *t) const
{
    if(t) return 1+size(t->left)+size(t->right);
    return 0;
}

//求二叉樹的高度
template <class T>
int BT<T>::height() const
{
    return height(root);
}

//求以t爲根結點的二叉樹的高度
template <class T>
int BT<T>::height(node<T> *t) const
{
    if(t)
    {
        int lt=height(t->left),rt=height(t->right);
        return 1+(lt>rt ? lt : rt);
    }
    return -1;
}

//求二叉樹葉子結點個數
template <class T>
int BT<T>::leafCount() const
{
    /*遞歸實現:
    if(!t) return 0;
    if(!t->left&&!t->right) return 1;
    return leavesCount(t->left)+leavesCount(t->right);
    */

    //非遞歸實現:
    int cnt=0;
    linkStack<node<T> *> stack;
    node<T> *t=root;
    if(t)
    {
        stack.push(t);
        while(!stack.empty())
        {
            node<T> *tmp=stack.pop();
            if(!tmp->left&&!tmp->right) ++cnt;
            if(tmp->right) stack.push(tmp->right);
            if(tmp->left) stack.push(tmp->left);
        }
    }
    return cnt;
}

//前序遍歷二叉樹
template <class T>
void BT<T>::preOrder() const
{
    /*遞歸實現:
    if(t)
    {
        cout<<t->data<<' ';
        preOrder(t->left);
        preOrder(t->right);
    }
    */

    //非遞歸實現:
    if(root)
    {
        cout<<"\n前序遍歷:";
        linkStack<node<T> *> stack;
        node<T> *t=root;
        if(t)
        {
            stack.push(t);
            while(!stack.empty())
            {
                node<T> *tmp=stack.pop();
                cout<<tmp->data<<' ';
                if(tmp->right) stack.push(tmp->right);
                if(tmp->left) stack.push(tmp->left);
            }
        }
    }
}

//中序遍歷二叉樹
template <class T>
void BT<T>::midOrder() const
{
    /*遞歸實現:
    if(t)
    {
        midOrder(t->left);
        cout<<t->data<<' ';
        midOrder(t->right);
    }
    */

    //非遞歸實現:
    if(root)
    {
        cout<<"\n中序遍歷:";
        linkStack<node<T> *> stack;
        node<T> *t=root;
        if(t)
        {
            while(t)
            {
                stack.push(t);
                t=t->left;
            }
            while(!stack.empty())
            {
                node<T> *tmp=stack.pop();
                cout<<tmp->data<<' ';
                if(tmp->right)
                {
                    stack.push(tmp->right);
                    node<T> *tmp1=tmp->right;
                    while(tmp1->left)
                    {
                        stack.push(tmp1->left);
                        tmp1=tmp1->left;
                    }
                }
            }
        }
    }
}

//後續遍歷二叉樹
template <class T>
void BT<T>::postOrder() const
{
    /*遞歸實現:
    if(t)
    {
        postOrder(t->left);
        postOrder(t->right);
        cout<<t->data<<' ';
    }
    */

    //非遞歸實現:
    if(root)
    {
        cout<<"\n後續遍歷:";
        linkStack<node<T> *> stack;
        node<T> *t=root;
        do
        {
            while(t)
            {
                stack.push(t);
                t=t->left;
            }
            node<T> *tmp=NULL;
            bool flag=1;
            while(!stack.empty()&&flag)
            {
                t=stack.top();
                if(t->right==tmp)
                {
                    cout<<t->data<<' ';
                    stack.pop();
                    tmp=t;
                }
                else
                {
                    t=t->right;
                    flag=0;
                }
            }
        }while(!stack.empty());
    }
}

//層次遍歷二叉樹
template <class T>
void BT<T>::levelOrder() const
{
    if(root)
    {
        cout<<"\n層次遍歷:";
        linkQueue<node<T> *> queue;
        node<T> *t=root;
        queue.enQueue(t);
        while(!queue.empty())
        {
            t=queue.deQueue();
            cout<<t->data<<' ';
            if(t->left) queue.enQueue(t->left);
            if(t->right) queue.enQueue(t->right);
        }
    }
}

//判斷是否爲完全二叉樹
template <class T>
bool BT<T>::isCompBT() const
{
    if(!root) return 1;
    bool judge=1;
    bool flag=0;
    linkQueue<node<T> *> queue;
    queue.enQueue(root);
    while(!queue.empty())
    {
        node<T> *tmp=queue.getHead();
        if(flag)
        {
            if(tmp->left||tmp->right)
            {
                judge=0;
                break;
            }
        }
        else
        {
            if(tmp->left&&tmp->right)
            {
                queue.enQueue(tmp->left);
                queue.enQueue(tmp->right);
            }
            else if(!tmp->left&&tmp->right)
            {
                judge=0;
                break;
            }
            else
            {
                if(tmp->left) queue.enQueue(tmp->left);
                flag=1;
            }
        }
        queue.deQueue();
    }
    while(!queue.empty())
    queue.deQueue();
    return judge;
}

//創建二叉樹,輸入flag表示爲空
template <class T>
void BT<T>::createTree(T flag)
{
    linkQueue<node<T> *> queue;
    node<T> *tmp;
    T x,ldata,rdata;

    //創建樹,輸入flag表示空
    cout<<"\n輸入根結點:";
    cin>>x;
    if(x==flag) root=NULL;
    else
    {
        root=new node<T>(x);
        queue.enQueue(root);
        while(!queue.empty())
        {
            tmp=queue.deQueue();
            cout<<"\n輸入"<<tmp->data<<"的兩個兒子("<<flag<<"表示空結點):";
            cin>>ldata>>rdata;
            if(ldata!=flag) queue.enQueue(tmp->left=new node<T>(ldata));
            if(rdata!=flag) queue.enQueue(tmp->right=new node<T>(rdata));
        }
    }
    cout<<"\n創建完成!\n\n";
}

//複製二叉樹
template <class T>
void BT<T>::copyTree(BT &tree)
{
    copyTree(root,tree.root);
}

//複製以t爲根結點的二叉樹爲以r爲根結點的新二叉樹
template <class T>
void BT<T>::copyTree(node<T> *&r,node<T> *t)
{
    if(t)
    {
        r=new node<T>(t->data);
        copyTree(r->left,t->left);
        copyTree(r->right,t->right);
    }
    else r=NULL;
}

//析構函數
template <class T>
BT<T>::~BT()
{
    clear();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章