c++ 树

1、树的概念:树 是一种经常用到的数据结构,用来模拟具有树状结构性质的数据集合,树里的每一个节点有一个值和一个包含所有子节点的列表。

2、二叉树是一种更为典型的树状结构。如它名字所描述的那样,二叉树是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”。

3、树里的一些专业名词:前、中、后、序遍历;左子树,右子树,父节点,子节点,兄弟节点,双亲节点

4、 遍历的顺序(注意每一种顺序都是放到相应的节点上去说的):

  • 前序遍历:根左右的顺序,如下图中

  • 中序遍历:左根右的顺序,如下图

  • 后续遍历:左右根的顺序,如下图

比较常用的是后续遍历。

5、遍历之前、中、后序

关于遍历的方法,这里可以有循环遍历的方法,十分有效,采用的是递归

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

#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、使用循环解决树的遍历问题:

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;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值