1. 程式人生 > >使用廣義表建立二叉樹

使用廣義表建立二叉樹

  1.   利用廣義表A(B(D,E),C(F,G))建立二叉樹,利用棧來輔助,這裡使用陣列模擬棧。原則如下:
(1)遇到節點資料如'A','B','C'等資料,則建立新節點,並分配記憶體空間; (2)遇到左括號'(',表明左子樹開始(flag=0),根節點入棧; (3)遇到逗號',',表明右子樹開始(flag=1);

(4)遇到右括號,表明子樹建立結束,根節點出棧。

2. 圖示:待補充


3.示例程式碼:

  void CreateBTreeUseList( BTree<char>*& node)
    {
        char ch;   //節點資料
        BTree<char>* st[100]{nullptr};   //用陣列模擬棧
        BTree<char>* p = nullptr;         //節點
        char flag = 2;                            //左右子樹的標識
        int8_t top = -1;                         //棧頂指標
        while ((ch = getchar()) != '\n')    //遇到換行符二叉樹建立結束
        {
            switch (ch)
            {
            case '(':                                 //遇到左括號,根節點入棧,
                st[++top] = p;
                flag = 0;   //左子樹開始
                break;
            case ',':
                flag = 1;   //右子樹開始
                break;
            case ')':        //遇到右括號,根節點出棧
                top--;
                break;
            default:      //遇到節點資料,分配記憶體,建立新節點
                p = new BTree<char>();
                p->leftSubTree = nullptr;
                p->rightSubTree = nullptr;
                p->data = ch;
                if (nullptr == mRoot)   //儲存整個樹的根節點
                    mRoot = p;
                else
                {
                    switch (flag)      //節點的左右子樹
                    {
                    case 0:             //左子樹
                        st[top]->leftSubTree = p;
                        break;
                    case 1:             //右子樹
                        st[top]->rightSubTree = p;
                        break;
                    default:
                        break;
                    }
                }


                break;
            }
        }


    }

4.執行結果:

int main()
{

    BinaryTree<char> bt;
    cout << "後序遍歷:";
    bt.postOrderVisit();
    cout << endl << "列印二叉樹:";
    bt.PrintBTree();
    return 0;
}
codeblock下執行結果:

A(B(C,D(,F(E,G))),H(I(J(,L(,M)),K)))
後序遍歷:C E G F D B M L J K I H A
列印二叉樹:A(B(C,D(,F(E,G))),H(I(J(,L(,M)),K))


5.附錄:完整的二叉樹C++檔案:

#ifndef BINARYTREE_H_INCLUDED
#define BINARYTREE_H_INCLUDED
#include <iostream>

using namespace std;

template <typename T>
 struct BTree
{
    T data;
    struct BTree* leftSubTree;
    struct BTree* rightSubTree;
};

template <class T>
class BinaryTree
{
};


template <>
class BinaryTree<char>
{
public:
    BinaryTree()
    {
        mRoot = nullptr;
        //CreateBTree(mRoot);   //AB#E##C#G##
        CreateBTreeUseList(mRoot);
    }
    virtual ~BinaryTree()
    {
        DestroyBTree(mRoot);
    }

    void postOrderVisit()
    {
        PostOrderVisit(mRoot);
    }

    size_t high()
    {
        return High(mRoot);
    }

    size_t width()
    {
        return Width();
    }

    //查詢
    bool findBTree(char ch)
    {
        return FindBTree(mRoot,ch);
    }

    //輸出
    void PrintBTree()
    {
        printBTree(mRoot);
    }
private:

    //以廣義表的形式輸出樹
    void printBTree(BTree<char>* node)
    {
        if (nullptr != node)
        {
            cout << node->data;
            if (node->leftSubTree != nullptr )
            {
                cout << "(";
                printBTree(node->leftSubTree);
            }
            if (node->rightSubTree != nullptr)
            {
                if (node->leftSubTree == nullptr)
                    cout << "(";
                cout << ",";
                printBTree(node->rightSubTree);
                cout << ")";
            }
        }
        else
            return;
    }

    //查詢
    bool FindBTree(BTree<char>* node,char ch)
    {
        if (nullptr == node)return false;
        else
        {

            if (ch == node->data)
               return true;
            else
            {
                if (FindBTree(node->leftSubTree,ch))
                    return true;
                if (FindBTree(node->rightSubTree,ch))
                    return true;

                return false;
            }
        }

    }

    //銷燬二叉樹
    void DestroyBTree(BTree<char>* node)
    {
        if (nullptr == node)
        {
            return;
        }else
        {
            DestroyBTree(node->leftSubTree);
            DestroyBTree(node->rightSubTree);
            delete node;
        }
    }

    //建立二叉樹
    void CreateBTree( BTree<char>*& node)
    {
        char ch = getchar();

        if ('\n' == ch)
            return;
        else if (ch == '#')
        {
            node = nullptr;
        }else
        {
            node = new BTree<char>();
            node->data = ch;
            /*
            if (nullptr == mRoot)
            {
                mRoot = node;
            }
            */
            CreateBTree(node->leftSubTree);
            CreateBTree(node->rightSubTree);


        }
    }

    //利用廣義表建立二叉樹
    void CreateBTreeUseList( BTree<char>*& node)
    {
        char ch;
        BTree<char>* st[100]{nullptr};
        BTree<char>* p = nullptr;
        char flag = 2;
        int8_t top = -1;
        while ((ch = getchar()) != '\n')
        {
            switch (ch)
            {
            case '(':
                st[++top] = p;
                flag = 0;   //左子樹開始
                break;
            case ',':
                flag = 1;   //右子樹開始
                break;
            case ')':
                top--;
                break;
            default:
                p = new BTree<char>();
                p->leftSubTree = nullptr;
                p->rightSubTree = nullptr;
                p->data = ch;
                if (nullptr == mRoot)
                    mRoot = p;
                else
                {
                    switch (flag)
                    {
                    case 0:  //左子樹
                        st[top]->leftSubTree = p;
                        break;
                    case 1:  //右子樹
                        st[top]->rightSubTree = p;
                        break;
                    default:
                        break;
                    }
                }


                break;
            }
        }


    }

    //後序遍歷
    void PostOrderVisit(BTree<char>*& node)
    {
        if (nullptr == node)
            return;
        else
        {
            PostOrderVisit(node->leftSubTree);
            PostOrderVisit(node->rightSubTree);
            cout << node->data << " ";
        }
    }

    //求樹的高度
    size_t High(BTree<char>*& node)
    {
        if (nullptr == node)
            return 0;
        else
          return Max(High(node->leftSubTree),High(node->rightSubTree)) + 1;
    }

    size_t Max(size_t a,size_t b)
    {
        return a>b ? a: b;
    }

    //求樹的寬度
    #define MAX_SIZE (50)
    size_t Width()
    {
        if (nullptr == mRoot)
            return 0;
        BTree<char>* q[MAX_SIZE]={nullptr};
        size_t last = 0,fr=0,rear=1;
        size_t tmp=0;
        size_t maxw=0;
        q[rear] = mRoot;
        BTree<char>* p = nullptr;
        while (fr <= last)
        {
            fr++;
            fr = fr % MAX_SIZE;
            p = q[fr];
            if (nullptr != p)
                tmp++;


            if (nullptr != p && p->leftSubTree != nullptr)
            {
                rear++;
                rear = rear % MAX_SIZE;
                q[rear] = p->leftSubTree;
            }

            if (nullptr != p && p->rightSubTree != nullptr)
            {
                rear++;
                rear = rear % MAX_SIZE;
                q[rear] = p->rightSubTree;
            }

            if (fr >= last)
            {
                last = rear;
                if (tmp > maxw)
                    maxw = tmp;
                tmp = 0;
            }/*
            if (nullptr == p)
                break;
                */
        }

        return maxw;
    }

private :
    BTree<char>* mRoot;

};


#endif // BINARYTREE_H_INCLUDED