二叉樹的模板類實現

二叉樹的定義
二叉樹(Binary Tree)是n>0個結點的有限集合,該集合或者爲空集(稱爲空二叉樹),或者由一個根節點和兩棵不相交的分別被稱爲左子樹和右子樹組成。

·不存在度大於2的結點;
·左右子樹是有序的,次序不能任意的顛倒。
這裏寫圖片描述

二叉樹的鏈表存儲方式
二叉樹的每個結點最多有兩個孩子,所以設計一個數據域和兩個指針域,我們稱爲二叉鏈表。
這裏寫圖片描述

二叉鏈樹的結點定義爲

template<typename T>
struct BiTNode
{
    T data;
    BiTNode<T>   *lchild, *rchild;
    BiTNode(BiTNode<T>* pl = NULL, BiTNode<T>* pr = NULL)
    {
        lchild = pl;
        rchild = pr;
    }
};

爲了方便介紹是如何生成一顆二叉樹的,我們先來簡單介紹一下三序遍歷。
①前序遍歷
先訪問根節點,然後前序遍歷左子樹,再前序遍歷右子樹
這裏寫圖片描述
前序遍歷:ABDGHCEIF

②中序遍歷
從根節點開始(先不訪問),中序遍歷根節點的左子樹,然後訪問根結點,最後中序遍歷右子樹。
這裏寫圖片描述
中序遍歷:GDHBAEICF

③後序遍歷
從左到右先葉子結點後根結點的方式遍歷左右子樹,最後訪問根結點。
這裏寫圖片描述
後序遍歷:GHDBIEFCA

接着看回代碼

//二叉樹
#ifndef BINARYTREE_H_
#define BINARYTREE_H_
#include <vector>
using namespace std;

template<typename T>
struct BiTNode
{
    T data;
    BiTNode<T>   *lchild, *rchild;
    BiTNode(BiTNode<T>* pl = NULL, BiTNode<T>* pr = NULL)
    {
        lchild = pl;
        rchild = pr;
    }
};
template<typename T>
class BiTree
{
public:
    BiTree();
    //構造函數
    ~BiTree();
    //析構函數
    void PreOrderTraverse(BiTNode<T>* node);
    //前序遍歷
    void InOrderTraverse(BiTNode<T>* node);
    //中序遍歷
    void PostOrderTraverse(BiTNode<T>* node);
    //後序遍歷
    void PrintNodeTraverse(BiTNode<T>*node);
    //層次遍歷
    BiTNode<T>* GetRoot();

private:
    BiTNode<T> *m_root;                   //根節點
    BiTNode<T> *createBiTree(T x[], int &n);           //二叉樹的創建
    void Release(BiTNode<T>* root); //二叉樹的刪除
};
template<typename T>
BiTree<T>::BiTree()
{
    T ch[100];
    cin.getline(ch, 100);
    int num = 0;
    m_root = createBiTree(ch,num);
}
template<typename T>
BiTree<T>::~BiTree()
{
    Release(m_root);
}

template<typename T>
BiTNode<T>* BiTree<T>::createBiTree(T x[], int &n)
{
        T ch = x[n];
        n++;
        if (ch == '#')
        {
            return NULL;
        }
        else
        {
            BiTNode<T> *Node = new BiTNode<T>;
            Node->data = ch;
            Node->lchild = createBiTree(x,n);
            Node->rchild = createBiTree(x,n);
            return Node;
        }



}

template<class T>
void BiTree<T>::Release(BiTNode<T>* root)
{
    if (root != NULL)
    {

        Release(root->lchild);
        Release(root->rchild);
        delete root;
    }

}

template<class T>
void BiTree<T>::PreOrderTraverse(BiTNode<T>* node)
{

    if (node == NULL)
    {
        return;
    }
    else
    {
        cout << node->data;
        PreOrderTraverse(node->lchild);
        PreOrderTraverse(node->rchild);
    }
}
template<class T>
void BiTree<T>::InOrderTraverse(BiTNode<T>* node)
{
    if (node == NULL)
    {
        return;
    }
    else
    {
        InOrderTraverse(node->lchild);
        cout << node->data;
        InOrderTraverse(node->rchild);
    }
}
template<class T>
void BiTree<T>::PostOrderTraverse(BiTNode<T>* node)
{
    if (node == NULL)
    {
        return;
    }
    else
    {
        PostOrderTraverse(node->lchild);
        PostOrderTraverse(node->rchild);
        cout << node->data;
    }
}

template<class T>
void BiTree<T>::PrintNodeTraverse(BiTNode<T>*node)
{
    vector<BiTNode<T>*> vec;
    vec.push_back(node);
    int cur = 0;                     //保存的是之前所以層的結點數
    int last = 1;                    //加上待遍歷層結點數後的總結點數
    while (cur<vec.size())
    {
        last = vec.size();         //重置上一行結點數
        while (cur<last)               //做幾次是由上一層的結點數決定的
        {
        cout << vec[cur]->data << " "; // 訪問節點
            if (vec[cur]->lchild) // 當前訪問節點的左節點不爲空則壓入
                vec.push_back(vec[cur]->lchild);
            if (vec[cur]->rchild) // 當前訪問節點的右節點不爲空則壓入,注意左右節點的訪問順序不能顛倒
                vec.push_back(vec[cur]->rchild);
            cur++;
        }
        cout << endl;           //當cur=last時說明該層的結點已被遍歷

    }
}



template<class T>
BiTNode<T>* BiTree<T>::GetRoot()
{
    return m_root;
}

#endif

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章