二叉树序列化题解






题意理解:层序遍历,就是从上往下,从左往右,遇到数字输出数字,空节点输出# 应该没人不理解
先序遍历:就是根左右,空的用# 代替,有人可能疑惑6 后面为啥3个 #  原因是,6 有两个空树,另外一个# 代表 4 的右子树

解题思路:
            1.根据层序遍历,创建二叉树。
               毫无疑问,第一个节点必定是根节点,层序遍历采用队列的思想,
                        1.1  : 先把跟节点入队,
                        当队列不空
                        1.2   取出队头节点,这个节点作为二叉树的待建立的树节点。这个说法怎么理解看你的悟性了,称此节点为  R
                        1.3  从  层序遍历   中拿到一个字符串,可以断定这就是R 的左子树的值,(理解这部,你可以按照堆的思想理解,或者在草稿纸上画一下。)
                                如果这个字符串不是 #  那么将它作为节点入队。
                                如果是# 就把它忽略掉。
                                不管是不是 #  那么最终 都要把它作为 R 的左节点插入到  R 的左树中

                                插完后,再继续从层序遍历中取出下一个节点   (可以断定这就是R 的 右子树的值 )
                                 如果这个字符串不是 #  那么将它作为节点入队。
                                如果是# 就把它忽略掉。
                                 不管是不是 #  那么最终 都要把它作为 R 的右节点插入到  R 的右树中
                2.  先序遍历输出 二叉树,
                                2.1  递归输出
                                递归出口:遇到空树  输出#  返回  
                                先输出当前节点,然后递归左边,再递归右边。
                                2.2  用栈  就可以不递归输出
                                把根节点入栈,
                                每次弹出栈顶元素,
                                            如果有数值,输出,并且将左右子树的根节点入栈。
                                            如果没有数值,输出 #  进入下一次循环。
具体做法:        
struct node
{
    int l, r;
    string val;
};          代表输的一个节点,用数组模拟二叉树   val 代表  数值, l  和  r  代表左右子树的下标,下表如果是  0   代表空树,这一部分应该大家都有基础,不再赘述,如有不懂欢迎留言。


遇到的坑:  就写在代码注释里面把
#include<iostream>
#include<queue>
#include<stack>
using namespace std;

const int N = 1e5 + 10;
int root = 1, idx = 1;
struct node
{
	int l, r;
	string val;
};
node tr[N];
queue< node* > q;
string tree[N];
stack<node*> st;



void addnode(node* root, string val, int opt)
{
        //着重解释  opt 的含义   如果是  1   代表将她插入到   root 的左树中,2  代表插入到右树中
	int u = ++idx;  
	if (opt == 1)     
	{
		root->l = u;
	}
	else
	{
		root->r = u;
	}
	tr[u].l = tr[u].r = 0;    //作为一个新的节点  左右两树应该置位空
	tr[u].val = val;
}
void output()
{
	st.push(&tr[1]);
	while (st.size())
	{
		node* t = st.top();
		st.pop();
		if (t->val.size() == 0) cout << "#" << endl;
		else
		{
			cout << t->val << endl;
			st.push(&tr[t->r]);
			st.push(&tr[t->l]); 
		}
		
	}
}
int main()
{
	int n;
	cin >> n;
	string s;
	cin >> s;

	tr[root].l = tr[root].r = 0;
	tr[root].val = s;

	q.push(&tr[root]);

	for (int i = 2; i <= n; i++) cin >> tree[i];    //规定  1是根节点,所以从2 开始
	int cur = 2;

	while (q.size())  //如果写成   while(true)   会发生段错误
	{
		node* t = q.front();

		q.pop();

		string l = tree[cur++];

		if (l != "#")
		{
			addnode(t, l, 1);
			q.push(&tr[t->l]); 
		}
		if (cur > n) break;   //坑 :注意如果  这个下标已经超过 n  那么已经说明所有节点遍历完了,不要继续了
		string r = tree[cur++];
		if (r != "#")
		{
			addnode(t, r, 2);
			q.push(&tr[t->r]); 
		}
		if (cur > n) break;
	}
	output();
	return 0;
}



                






#深信服笔试题二叉树的序列化题解##深信服##笔试题目#
全部评论

相关推荐

3 11 评论
分享
牛客网
牛客企业服务