【剑指offer】序列化二叉树

题目描述

请实现两个函数,分别用来序列化和反序列化二叉树

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

思路:

(1)序列化比较简单,就是将二叉树进行一个前序遍历,存储在一个string中,每个空节点存成“#!”,非空节点存成“value!”,最后将string类型复制到char*数组中。
(2)反序列化相对而言麻烦点:
1》计算每个节点的长度len,若str[idx]是‘#’代表空节点返回NULL,将索引号后移len+1,调到后一个节点;
2》对于非空节点,判断其正负,赋值给value,创建树节点,下面就是对左右节点递归赋值操作。

代码段:

前序遍历序列化,反序列化。

struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};
class Solution {
public:
	//序列化//
	char* Serialize(TreeNode* root) {
		string tmp;
		dfs1(root, tmp);
		char* res=new char[tmp.size()+1];
		strcpy(res, tmp.c_str());
		return res;
	}
	void dfs1(TreeNode* root,string & tmp) {
		if (root == nullptr) {
			tmp += "#!";
			return;
		}
		tmp += to_string(root->val) + '!';
		dfs1(root->left, tmp);
		dfs1(root->right, tmp);
	}
	//反序列化//
	TreeNode* Deserialize(char* str) {
		int idx = 0;
		return dfs2(str,idx);
	}
	TreeNode* dfs2(char* str, int& idx) {
		int len = idx;
		while (str[len] != '!') len++;//计算每个节点的数值长度
		//(1)对于空节点直接跳过
		if (str[idx] == '#') { 
			idx=len+1;
			return nullptr;
		}
		//(2)对于非空节点,计算数值,转化成二叉树val值
		int tag = 1;//标签值,若为正则为1,若为负,则为-1;
		if (str[idx] == '-' && idx < len) {//判断节点数值是否为负数?
			tag = -1;
			idx++;
		}
		int value = 0;//计算节点的值;
		for (int i = idx; i < len; ++i) {
			value = value * 10 + str[i] - '0';
		}
		value *= tag;
        idx=len+1;//idx移到下一个节点。
		TreeNode* root = new TreeNode(value);
		root->left = dfs2(str, idx);
		root->right = dfs2(str, idx);
        return root;
	}

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力做一个code杠精

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值