LeetCode. 二叉树的序列化与反序列化(非递归【层次遍历】or 递归【先序遍历】)

#include
#include
#include
#include
using namespace std;
struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Codec {
public:
	//有个坑,使用auto &node = _queue.front();内存会直接爆掉
	//初步判断,应该是auto在编译期间的时候,编译器便做了标记
	//类似于提前分配内存空间,无需再运行时动态调用代码去分配空间
	//所以在程序开始运行时,就直接分配了空间,而不是运行到目标代码后动态申请

	//-----------------------------------------------------
	//非递归
	//层次遍历序列化
	string serialize(TreeNode* root) {
		ostringstream oss;
		if (root == nullptr)return oss.str();
		queue<TreeNode*>_queue;
		_queue.push(root);
		while (!_queue.empty())
		{
			TreeNode* node = _queue.front();
			_queue.pop();
			if (node == nullptr) {
				oss << "#_";
			}
			else {
				oss << node->val << "_";
				_queue.push(node->left);
				_queue.push(node->right);
			}
		}
		return oss.str();
	}

	TreeNode* deserialize(string data) {
		if (data.empty())return nullptr;
		vector<TreeNode*> _vec;
		cout << data << endl;
		//deserialize string data
		while (!data.empty())
		{
			//find '_' index
			int _index = 0;
			for (; _index < data.size(); ++_index)
				if (data[_index] == '_')
					break;
			if (_index == 0)break;
			//get subString before '_' : "1232_"=>"1232"
			string val = data.substr(0, _index);
			//check the node is nullptr or isn't
			if (val[0] == '#') {
				_vec.emplace_back(nullptr);
			}
			else {
				_vec.emplace_back(new TreeNode(stoi(val)));
			}
			//get subString after '_' : "1232_#_"=>"#_"
			data = data.substr(_index + 1, data.size());
		}
		//Level Traversal To General Tree
		//_vec is the Level Traversal Result Vector
		//_queue is helpful to carry on level traversal
		TreeNode*root;
		queue<TreeNode*> _queue;
		int vec_index = 0;//Level Traversal current node index
		_queue.push(_vec[vec_index]);
		root = _vec[vec_index];
		++vec_index;
		while (vec_index < _vec.size())
		{
			TreeNode* node = _queue.front();
			_queue.pop();

			if (node != nullptr) {
				//left node and right node
				_queue.push(_vec[vec_index]);
				node->left = _vec[vec_index];
				++vec_index;
				_queue.push(_vec[vec_index]);
				node->right = _vec[vec_index];
				++vec_index;
			}
		}
		return root;
	}

	//-----------------------------------------------------
	//递归
	// Encodes a tree to a single string.
	string serialize(TreeNode* root) {
		if (root == nullptr)return"#";
		//preOrder Recursion
		string result(to_string(root->val) + '_');
		string leftStr = serialize(root->left);
		string rightStr = serialize(root->right);
		result.append(leftStr + '_');
		result.append(rightStr + '_');
		cout << result << endl;
		return result;
	}

	// Decodes your encoded data to tree.
	TreeNode* deserialize(string data) {
		vector<TreeNode*> data_vec;
		DoDeserialize(data_vec, data);
		TreeNode *root;
		int vec_index = 0;
		MakeTreebyPreOrder(root, data_vec, vec_index);
		return root;
	}

	//反序列化
	void DoDeserialize(vector<TreeNode*> &data_vec, const string &data) {
		string tempStr;
		for (int i = 0; i < data.size(); ++i)
		{
			if (data[i] == '_') {
				if (data[i] == '#')
					data_vec.emplace_back(nullptr);
				else
					data_vec.emplace_back(new TreeNode(stoi(tempStr)));
				tempStr.clear();
			}
			else {
				tempStr += data[i];
			}
		}
		return;
	}
	//先序 生成树
	void MakeTreebyPreOrder(
		TreeNode* &node, 
		const vector<TreeNode*> &data_vec, 
		int &vec_index) 
	{
		if (vec_index >= data_vec.size())return;
		node = data_vec[vec_index];
		if (node != nullptr) {
			MakeTreebyPreOrder(node->left, data_vec, ++vec_index);
			MakeTreebyPreOrder(node->right, data_vec, ++vec_index);
		}
		else {
			vec_index += 2;
		}
	}
};

你可能感兴趣的:(LeetCode,二叉树)