樹的遍歷,前中後+層次遍歷非遞歸

存在內存泄漏,,,,原因是沒有銷燬結點時內存釋放的處理.

#include<iostream>
#include<deque>
#include<stack>
#include<string>

using namespace std;

class cbtnode
{
public:
    char data;
    cbtnode * parent;
    cbtnode * lchild;
    cbtnode * rchild;
};
typedef cbtnode btnode;
class cbtroot
{
public:
    cbtroot(string &s)
    {
        settree(s);
    }
    void xianxubianli1()//遞歸形式的先序遍歷
    {
        xianxubianli1(root);
    }
private:
    void xianxubianli1(btnode *node)
    {
        if (node == nullptr)
            return;
        cout << node->data << "  ";
        xianxubianli1(node->lchild);
        xianxubianli1(node->rchild);
    }
public:
/*非遞歸形式的遍歷,都是通過棧來完成的.比如先序遍歷當節點出棧的時候要先將該節點的右孩子入棧然後在入左孩子...

*中序遍歷的話先不斷的將左孩子入棧,當左孩子出棧的時候如果父親有右孩子,那麼就將右孩子的左孩子不斷入棧.
沒有的話就不斷出棧知道右孩子不爲空..

*後序遍歷則是在中序的基礎上需要了一個標誌位,如果該節點的右孩子沒有遍歷才遍歷,遍歷過了就直接出棧.
*/
    void xianxubianli2()
    {
        if (root == nullptr)
            return;
        stack<btnode*> node_stack;
        node_stack.push(root);
        while (!node_stack.empty())
        {
            btnode * outp = node_stack.top();
            node_stack.pop();

            cout << outp->data;

            if (outp->rchild != nullptr)
                node_stack.push(outp->rchild);
            if (outp->lchild != nullptr)
                node_stack.push(outp->lchild);
        }
    }
    void zhongxubianli1()
    {
        stack<btnode*> node_stack;
        node_stack.push(root);

        btnode * outp;
        while (!node_stack.empty())
        {
            outp = node_stack.top();
            while (outp->lchild != nullptr)
            {
                node_stack.push(outp->lchild);
                outp = outp->lchild;
            }

            while (!node_stack.empty())
            {
                outp = node_stack.top();
                cout << outp->data << " ";
                node_stack.pop();

                if (outp->rchild != nullptr)
                {
                    node_stack.push(outp->rchild);
                    break;
                }
            }
        }
    }
    void houxubianli1()
    {
        stack<btnode*> node_stack;
        node_stack.push(root);

        btnode * outp;
        btnode * tag = nullptr;//標誌位
        while (!node_stack.empty())
        {
            outp = node_stack.top();
            while (outp->lchild != nullptr)
            {
                node_stack.push(outp->lchild);
                outp = outp->lchild;
            }
            while (!node_stack.empty())
            {
                outp = node_stack.top();

                if (outp->rchild != nullptr && tag != outp->rchild)
                {
                    node_stack.push(outp->rchild);
                    break;
                }
                else
                {
                    cout << outp->data << " ";
                    //當右孩子被遍歷過了才進行打印和出棧
                    node_stack.pop();
                    tag = outp;
                }
            }
        }
    }
    //層次遍歷則是一個隊列來完成的,很簡單不說了.
    void cengcibianli()
    {
        deque<btnode *> node_que;
        node_que.push_back(root);
        btnode * outp;
        while (!node_que.empty())
        {
            outp = node_que.front();
            node_que.pop_front();

            if (outp->lchild != nullptr)
                node_que.push_back(outp->lchild);
            if (outp->rchild != nullptr)
                node_que.push_back(outp->rchild);
            cout << outp->data << " ";
        }
    }
private:
    btnode * search(char);
    void settree(string &s);
    cbtnode * root;
};
typedef cbtroot btroot;
btnode * buynode(char data, btnode*l, btnode *r, btnode * p)
{
    btnode *root = (btnode*)malloc(sizeof(btnode));
    root->data = data;
    root->lchild = l;
    root->rchild = r;
    root->parent = p;
    return root;
}
btnode * btroot::search(char key)
{
    btnode * tmp = root;
    btnode * par = nullptr;
    while (tmp != nullptr && tmp->data != key)
    {
        par = tmp;
        if (tmp->data < key)
        {
            tmp = tmp->rchild;
        }
        else
        {
            tmp = tmp->lchild;
        }
    }
    if (tmp != nullptr)
    {
        return nullptr;
    }
    return par;
}
void btroot::settree(string &s) {
    for (int i = 0; i < s.size(); ++i)
    {
        if (root == nullptr)
        {
            root = buynode(s[i], nullptr, nullptr, nullptr);
        }
        else
        {
            btnode * tmp = search(s[i]);
            if (tmp == nullptr)
                continue;
            btnode * insert_node = buynode(s[i], nullptr, nullptr, tmp);
            if (s[i] < tmp->data)
                tmp->lchild = insert_node;
            else
                tmp->rchild = insert_node;
        }
    }
}

int main()
{
    string str = { "ebhadgcifk" };
    //這是一棵二叉搜索樹....
    btroot *root = new btroot(str);

    root->cengcibianli();//層次遍歷
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章