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

浙公网安备 33010602011771号