【剑指】37.序列化二叉树

题目描述
  • 请实现两个函数,分别用来序列化和反序列化二叉树。
算法分析
  • 序列化:使用前序遍历,递归的将二叉树的值转化为字符,并且在每次二叉树的结点不为空时,在转化val所得的字符之后添加一个','作为分割,对于空节点则以 '#' 代替。
  • 反序列化:按照前序顺序,递归的使用字符串中的字符创建一个二叉树(在递归时,递归函数的参数是char **类型 ,这样才能保证每次递归后指向字符串的指针会随着递归的进行而移动)

提交代码:

class Solution {
public:
	/* 前序遍历序列化 */
	char* Serialize(TreeNode *root) {
		if (!root)
			return nullptr;

		string code;
		SerializeCore(root, code);
		// 去掉结尾","
		code.pop_back();
		char* serialize = new char[code.size() + 1];
		int i = 0;
		for (; i < code.size(); ++i)
			serialize[i] = code[i];
		serialize[i] = '\0';

		return serialize;
	}

	void SerializeCore(TreeNode *root, string &code) {
		code.append(to_string(root->val));
		code.append(",");

		if (root->left)
			SerializeCore(root->left, code);
		else
			code.append("#,");

		if (root->right)
			SerializeCore(root->right, code);
		else
			code.append("#,");
	}

	TreeNode* Deserialize(char *str) {
		if (!str || *str == '\0')
			return nullptr;

		TreeNode *pHead = DeserializeCore(&str);

		return pHead;
	}

	TreeNode* DeserializeCore(char **str) {
		if (**str == '#')
			return nullptr;

		int number = 0;
		while (**str != ',')
		{
			number = number * 10 + (**str - '0');
			++(*str);
		}
		TreeNode* pNode = new TreeNode(number);

		++(*str);
		pNode->left = DeserializeCore(str);
		(*str) += 2;
		pNode->right = DeserializeCore(str);

		return pNode;
	}
};

测试代码:

// ==================== Test Code ====================
bool isSameTree(const TreeNode* pRoot1, const TreeNode* pRoot2)
{
	if (pRoot1 == nullptr && pRoot2 == nullptr)
		return true;

	if (pRoot1 == nullptr || pRoot2 == nullptr)
		return false;

	if (pRoot1->val != pRoot2->val)
		return false;

	return isSameTree(pRoot1->left, pRoot2->left) &&
		isSameTree(pRoot1->right, pRoot2->right);
}

void Test(const char* testName, TreeNode* pRoot)
{
	if (testName != nullptr)
		printf("%s begins: \n", testName);

	PrintTree(pRoot);
	Solution s;

	char *code = s.Serialize(pRoot);
	int i = 0;
	while (code[i] != '\0')
	{
		cout << code[i] << " ";
		++i;
	}
	cout << endl;

	TreeNode* pNewRoot = s.Deserialize(code);
	PrintTree(pNewRoot);

	if (isSameTree(pRoot, pNewRoot))
		printf("The deserialized tree is same as the oritinal tree.\n\n");
	else
		printf("The deserialized tree is NOT same as the oritinal tree.\n\n");

	DestroyTree(pNewRoot);
}

//            8
//        6      10
//       5 7    9  11
void Test1()
{
	TreeNode* pNode8 = CreateBinaryTreeNode(8);
	TreeNode* pNode6 = CreateBinaryTreeNode(6);
	TreeNode* pNode10 = CreateBinaryTreeNode(10);
	TreeNode* pNode5 = CreateBinaryTreeNode(5);
	TreeNode* pNode7 = CreateBinaryTreeNode(7);
	TreeNode* pNode9 = CreateBinaryTreeNode(9);
	TreeNode* pNode11 = CreateBinaryTreeNode(11);

	ConnectTreeNodes(pNode8, pNode6, pNode10);
	ConnectTreeNodes(pNode6, pNode5, pNode7);
	ConnectTreeNodes(pNode10, pNode9, pNode11);

	Test("Test1", pNode8);

	DestroyTree(pNode8);
}

//            5
//          4
//        3
//      2
void Test2()
{
	TreeNode* pNode5 = CreateBinaryTreeNode(5);
	TreeNode* pNode4 = CreateBinaryTreeNode(4);
	TreeNode* pNode3 = CreateBinaryTreeNode(3);
	TreeNode* pNode2 = CreateBinaryTreeNode(2);

	ConnectTreeNodes(pNode5, pNode4, nullptr);
	ConnectTreeNodes(pNode4, pNode3, nullptr);
	ConnectTreeNodes(pNode3, pNode2, nullptr);

	Test("Test2", pNode5);

	DestroyTree(pNode5);
}

//        5
//         4
//          3
//           2
void Test3()
{
	TreeNode* pNode5 = CreateBinaryTreeNode(5);
	TreeNode* pNode4 = CreateBinaryTreeNode(4);
	TreeNode* pNode3 = CreateBinaryTreeNode(3);
	TreeNode* pNode2 = CreateBinaryTreeNode(2);

	ConnectTreeNodes(pNode5, nullptr, pNode4);
	ConnectTreeNodes(pNode4, nullptr, pNode3);
	ConnectTreeNodes(pNode3, nullptr, pNode2);

	Test("Test3", pNode5);

	DestroyTree(pNode5);
}

void Test4()
{
	TreeNode* pNode5 = CreateBinaryTreeNode(5);

	Test("Test4", pNode5);

	DestroyTree(pNode5);
}

void Test5()
{
	Test("Test5", nullptr);
}

//        5
//         5
//          5
//         5
//        5
//       5 5
//      5   5
void Test6()
{
	TreeNode* pNode1 = CreateBinaryTreeNode(5);
	TreeNode* pNode2 = CreateBinaryTreeNode(5);
	TreeNode* pNode3 = CreateBinaryTreeNode(5);
	TreeNode* pNode4 = CreateBinaryTreeNode(5);
	TreeNode* pNode5 = CreateBinaryTreeNode(5);
	TreeNode* pNode61 = CreateBinaryTreeNode(5);
	TreeNode* pNode62 = CreateBinaryTreeNode(5);
	TreeNode* pNode71 = CreateBinaryTreeNode(5);
	TreeNode* pNode72 = CreateBinaryTreeNode(5);

	ConnectTreeNodes(pNode1, nullptr, pNode2);
	ConnectTreeNodes(pNode2, nullptr, pNode3);
	ConnectTreeNodes(pNode3, pNode4, nullptr);
	ConnectTreeNodes(pNode4, pNode5, nullptr);
	ConnectTreeNodes(pNode5, pNode61, pNode62);
	ConnectTreeNodes(pNode61, pNode71, nullptr);
	ConnectTreeNodes(pNode62, nullptr, pNode72);

	Test("Test6", pNode1);

	DestroyTree(pNode1);
}

int main(int argc, char* argv[])
{
	Test1();
	Test2();
	Test3();
	Test4();
	Test5();
	Test6();

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值