c++实现树

1、树的概念:树 是一种经常用到的数据结构,用来模拟具有树状结构性质的数据集合,树里的每一个节点有一个值和一个包含所有子节点的列表。
2、二叉树是一种更为典型的树状结构。如它名字所描述的那样,二叉树是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”。
3、树里的一些专业名词:前、中、后、序遍历;左子树,右子树,父节点,子节点,兄弟节点,双亲节点
4、 遍历的顺序(注意每一种顺序都是放到相应的节点上去说的):
  • 前序遍历:根左右的顺序,如下图中
  • 中序遍历:左根右的顺序,如下图
  • 后续遍历:左右根的顺序,如下图
比较常用的是后续遍历。
5、遍历之前、中、后序
关于遍历的方法,这里可以有循环遍历的方法,十分有效,采用的是递归
#include<iostream>
using namespace std;
class mytree
{
public:
       struct treenode
       {
              char n;
              treenode* ltree;
              treenode* rtree;
              treenode(char n) :n(n), ltree(NULL), rtree(NULL)
              {}
       };
       //前序遍历
       void pretra(treenode* r)
       {
              if (r == NULL)
              {
                     return;
              }
              cout << r->n << " ";
              pretra(r->ltree);
              pretra(r->rtree);
       }
       //中序遍历
       void intra(treenode* r)
       {
              if (r == NULL)
              {
                     return;
              }
              intra(r->ltree);
              cout << r->n <<" ";
              intra(r->rtree);
       }
       //后序遍历
       void postra(treenode* r)
       {
              if (r == NULL)
              {
                     return;
              }
              postra(r->ltree);
              postra(r->rtree);
              cout << r->n << " ";
       }
       void test1()
       {
              //创建节点
              treenode a('a');
              treenode b('b');
              treenode c('c');
              treenode d('d');
              treenode e('e');
              treenode f('f');
              treenode g('g');
              //创建关系
              a.ltree = &b;
              a.rtree = &e;
              b.ltree = &c;
              b.rtree = &d;
              e.rtree = &f;
              f.ltree = &g;
              //前序遍历
              cout << "前序遍历" << endl;
              pretra(&a);
              cout << endl;
              //中序遍历
              cout << "中序遍历" << endl;
              intra(&a);
              cout << endl;
              //后序遍历
              cout << "后序遍历" << endl;
              postra(&a);
              cout << endl;
       }
};
int main(void)
{
       mytree tree;
       tree.test1();
       system("pause");
       return 0;
}

  

6、树的层序遍历
这里的遍历方法为:(注意一定要用队列,而不能用栈),注意区别
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct treenode
{
       int val;
       treenode* left;
       treenode* right;
       treenode(int val):val(val),left(nullptr),right(nullptr)
       {
       }
};
class solution
{
public:
    vector<vector<int>> levelorder(treenode* root)
    {
        vector<vector<int>> v;
        if (root == nullptr)
        {
            return v;
        }
        queue<treenode*> q;
        q.push(root);
        while (!q.empty())
        {
            int quesize = q.size();
            vector<int> cur;
            for (int i = 0; i < quesize; i++)
            {
                treenode* node = q.front();
                q.pop();
                cur.push_back(node->val);
                if (node->left)
                {
                    q.push(node->left);
                }
                if (node->right)
                {
                    q.push(node->right);
                }
            }
            v.push_back(cur);
        }
        return v;
    }
    void printv(vector<vector<int>>& v)
    {
        for (int i = 0; i < v.size(); i++)
        {
            cout << "[" << "";
            for (int j = 0; j < v[i].size(); j++)
            {
                cout << v[i][j] << a;
            }
            cout << "]" << "";
        }
    }
};
void test()
{
    treenode a(1);
    treenode b(2);
    treenode c(3);
    treenode d(4);
    treenode e(5);
    treenode f(6);
    treenode g(7);
    //创建关系
    a.left = &b;
    a.right = &e;
    b.left = &c;
    b.right = &d;
    e.right = &f;
    f.left = &g;
    //层序遍历的解决方案
    solution so;
    vector<vector<int>>s = so.levelorder(&a);
    so.printv(s);
}
int main()
{
    test();
       system("pause");
       return 0;
}

 

其结果为:
7、使用循环解决树的遍历问题:
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
class mytree
{
public:
    struct treenode
    {
        char n;
        treenode* ltree;
        treenode* rtree;
        treenode(char n) :n(n), ltree(NULL), rtree(NULL)
        {}
    };
    
    //前序遍历
    void pretra(treenode* r)
    {
        vector<char>s;
        stack<treenode*>st;
        if (r == NULL) {
            return;
        }
        st.push(r);
        while (!st.empty()) {
            treenode* ft = st.top();
            s.push_back(ft->n);
            st.pop();
            if (ft->rtree)st.push(ft->rtree);//进栈的顺序是反过来的,和递归是不一样的
            if (ft->ltree)st.push(ft->ltree);
        }
        for (int i = 0; i < s.size(); i++) {
            cout << s[i] << " ";
        }
    }
    //中序遍历
    void intra(treenode* r)
    {
        vector<char>s;
        stack<treenode*>st;
        if (r == NULL) {
            return;
        }
        treenode* topval = r;
        while (topval||!st.empty()) {
            if (topval != NULL) {
                st.push(topval);
                topval = topval->ltree;
            }
            else {
                topval = st.top();
                st.pop();
                s.push_back(topval->n);
                topval = topval->rtree;
            }
        }
        for (int i = 0; i < s.size(); i++) {
            cout << s[i] << " ";
        }
    }
    void postra(treenode* r)
    {
        vector<char>s;
        stack<treenode*>st;
        if (r == NULL) {
            return;
        }
        st.push(r);
        while (!st.empty()) {
            treenode* ft = st.top();
            s.push_back(ft->n);
            st.pop();
            if (ft->ltree)st.push(ft->ltree);//这里往下有两个反转的过程,第一应该是前序换一个位置(注意前序本来也是换了一个位置的)
            if (ft->rtree)st.push(ft->rtree);
        }
        reverse(s.begin(),s.end());//这里的是第二个反转
        for (int i = 0; i < s.size(); i++) {
            cout << s[i] << " ";
        }
    }
    void test1()
    {
        //创建节点
        treenode a('a');
        treenode b('b');
        treenode c('c');
        treenode d('d');
        treenode e('e');
        treenode f('f');
        treenode g('g');
        //创建关系
        a.ltree = &b;
        a.rtree = &e;
        b.ltree = &c;
        b.rtree = &d;
        e.rtree = &f;
        f.ltree = &g;
        //前序遍历
        cout << "前序遍历" << endl;
        pretra(&a);
        cout << endl;
        //中序遍历
        cout << "中序遍历" << endl;
        intra(&a);
        cout << endl;
        //后序遍历
        cout << "后序遍历" << endl;
        postra(&a);
        cout << endl;
    }
};
int main(void)
{
    mytree tree;
    tree.test1();
    system("pause");
    return 0;
}
8、把一个建立好的树其他的深度dep
其实这个问题就是求一个树的层数的问题,我们用层序遍历就OK,我们最后返回层序遍历当中的vector<vector<int>> v;这个容器当中的v.size();这个size()就是代表了层数,也同时代表了树的深度。
代码如下:
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct treenode
{
       int val;
       treenode* left;
       treenode* right;
       treenode(int val):val(val),left(nullptr),right(nullptr)
       {
       }
};
class solution
{
public:
    int maxdep(treenode* root)
    {
        vector<vector<int>> v;
        if (root == nullptr)
        {
            return 0;
        }
        queue<treenode*> q;
        q.push(root);
        while (!q.empty())
        {
            int quesize = q.size();
            vector<int> cur;
            for (int i = 0; i < quesize; i++)
            {
                treenode* node = q.front();
                q.pop();
                cur.push_back(node->val);
                if (node->left)
                {
                    q.push(node->left);
                }
                if (node->right)
                {
                    q.push(node->right);
                }
            }
            v.push_back(cur);
        }
        return v.size();
    }
};
void test()
{
    treenode a(1);
    treenode b(2);
    treenode c(3);
    treenode d(4);
    treenode e(5);
    treenode f(6);
    treenode g(7);
    //创建关系
    a.left = &b;
    a.right = &e;
    b.left = &c;
    b.right = &d;
    e.right = &f;
    f.left = &g;
    //层序遍历的解决方案
    solution so;
    int size=so.maxdep(&a);
    cout<<size<<endl;
}
int main()
{
    test();
       return 0;
}

 

 
 
 
posted @ 2022-09-04 09:16  铜锣湾陈昊男  阅读(185)  评论(0)    收藏  举报