多叉樹 (遞歸遍歷,尾插入)

學習<<數據結構與算法分析>>,給以後留個記錄

tree.h

#ifndef TREE_H
#define TREE_H

#include <string>
#include <iostream>

using namespace std;

struct TreeNode
{
    string element;
    TreeNode *firstChild = nullptr;
    TreeNode *nextSibling = nullptr;
    TreeNode(string str) : element(str){}
    TreeNode(){}
};

class tree
{
public:
    tree();
    /// 手動添加一些節點,用於實驗
    bool addNode();
    /// 尾插法
    void insertNode(string father, string self);
    /// 返回根節點
    TreeNode* getRootNode() const;
    /// 深度優先遍歷
    void travel(TreeNode *root);

private:
    TreeNode* find(TreeNode *root, string str);

private:
    TreeNode *root;
};

#endif // TREE_H

tree.cpp

#include "tree.h"

tree::tree()
{
    root = new TreeNode;
    addNode();
}

///
/// \brief tree::addNode
///      A
///      |
/// B    C   D
///     /|\
///    E F G
bool tree::addNode()
{
    root->element = string("A");
    root->firstChild = new TreeNode("B");
    root->firstChild->nextSibling = new TreeNode("C");
    root->firstChild->nextSibling->nextSibling = new TreeNode("D");
    root->firstChild->nextSibling->firstChild = new TreeNode("E");
    root->firstChild->nextSibling->firstChild->nextSibling = new TreeNode("F");
    root->firstChild->nextSibling->firstChild->nextSibling->nextSibling = new TreeNode("G");

}

void tree::insertNode(string father, string self)
{
    auto temp = find(root, father);
    if(temp->firstChild == nullptr)     //父節點還沒有子節點
    {
        temp->firstChild = new TreeNode;
        temp->firstChild->element = self;
    }
    else
    {
        auto i = temp->firstChild;
        for(; i->nextSibling != nullptr; i = i->nextSibling){}
        i->nextSibling = new TreeNode;
        i->nextSibling->element = self;
    }

}

TreeNode *tree::getRootNode() const
{
    return root;
}

void tree::travel(TreeNode *root)
{
    cout << root->element << " ";
    for(TreeNode *i = root->firstChild; i != nullptr; i = i->nextSibling)
    {
        travel(i);
    }
}

TreeNode *tree::find(TreeNode *root, string str)
{
    if(root->element == str)
    {
        return root;
    }
    else
    {
        if(root->firstChild != nullptr)
        {
            for(TreeNode * i = root->firstChild; i != nullptr; i = i->nextSibling)
            {
                auto temp = find(i, str);
                if(temp != nullptr)
                    return temp;
            }
        }
    }
    return nullptr;
}

main.cpp

#include <iostream>
#include "tree.h"

using namespace std;

int main(int argc, char *argv[])
{
    cout << "Hello World!" << endl;
    tree a;

    a.travel(a.getRootNode());
//    auto aaa = a.find(a.getRootNode(), "F");
//    cout << aaa->element << endl;
    a.insertNode("G", "H");
    a.travel(a.getRootNode());

    return 0;
}

總結:
看過一些其他的實現方法,和本文的主要差別是對節點結構體的設計上的.
一般的設計用到std::list,如下:

struct Node
{
    Object element;
    std::list<Node *> child;
};

這樣做的話會使代碼節點,畢竟STL中分裝了大量的方法可以使用

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