二叉树的序列化和反序列化(C++)

 

 

本题考点:
http://blog.csdn.net/weiwei22844/article/details/42004983


leetcode题目地址
297. Serialize and Deserialize Binary Tree
https://leetcode.com/problems/serialize-and-deserialize-binary-tree/

层次遍历,ac代码,注意反序列化如何操作??

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string. 层次遍历
    string serialize(TreeNode* root) {
        string ans;
        if (root == NULL)
            return "[]";
        ans = "[";
        queue<TreeNode*> que;
        que.push(root);

        char str[100];

        while (!que.empty())
        {
            TreeNode* top = que.front();
            que.pop();

            if (top != NULL)
            {
                que.push(top->left);
                que.push(top->right);

                sprintf(str, "%d", top->val);
                ans += str;
            }
            else{
                ans += "null";
            }

            ans += ",";
        }

        int end = ans.length() - 1;
        while ( !( ans[end] >= '0' && ans[end] <= '9') )
            end--;

        string rs = ans.substr(0, end + 1);
        rs += "]";

        return rs;
    }

    // Decodes your encoded data to tree. // 解析一个层次遍历
    TreeNode* deserialize(string data) {

        int len = data.size();

        if (len <= 2)
            return NULL;

        int numsCount = 0;
        vector<TreeNode*> nums;

        string word = "";
        for (int i = 1; i <= len - 2; i++){
            if (data[i] == ',')
            {
                TreeNode* tmp = NULL;
                if (word == "null")
                {

                }
                else{
                    int num = atoi(word.c_str());
                    tmp = new TreeNode(num);
                }
                nums.push_back(tmp);
                word = "";
            } else{
                //if (data[i] >= '0' && data[i] <= '9')
                    word += data[i];
            }
        }
        if (word != "" && word != "null")
        {
            int num = atoi(word.c_str());
            TreeNode* tmp = new TreeNode(num);
            nums.push_back(tmp);
        }

        int cnt = nums.size();

        int q = 0; // 遍历的节点,每个节点一个一个遍历(包括了NULL 节点)
        int p = 1; // 当前遍历结点 的 左孩子节点, p+1就是右孩子节点
        while (p < cnt)
        {
            if (nums[q] == NULL){
                q++;
            }
            else{
                if (p < cnt)
                    nums[q]->left = nums[p];
                if (p + 1 < cnt)
                    nums[q]->right = nums[p + 1];
                p += 2;
                q++;
            }
        }

        return nums[0];
    }
};


// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));

参考其中的一个解题方法

http://blog.csdn.net/brucehb/article/details/50472732

C++实现(BFS 字符串处理,层次遍历)

char* Serialize(TreeNode *root) {
    if (root == NULL)
        return NULL;

    queue<TreeNode*> sta;
    sta.push(root);

    string s = "";
    char str[10];

    while (!sta.empty())
    {
        while (!sta.empty())
        {
            TreeNode* tmp = sta.front();
            sta.pop();
            if (tmp != NULL)
            {
                sta.push(tmp->left);
                sta.push(tmp->right);
                sprintf(str, "%d", tmp->val);
                s += str;
            }
            else
            {   
                s += "#";
            }

            s += " ";
        }

    }// while

    int end = s.length() - 1;
    while (s[end] == '#' || s[end] == ' ')
        end--;
    char *rs = new char[end + 2];
    //strcpy(rs, s.c_str());
    for (int i = 0; i <= end; i++)
        rs[i] = s[i];
    rs[end + 1] = '\0';
    return rs;
}
TreeNode* Deserialize(char *str) {
    if (str == NULL)
        return NULL;
    int len = strlen(str);
    if (len == 0)
        return NULL;

    int numsCount = 0;
    vector<TreeNode*> nums;
    string s(str);
    stringstream ss(s);
    string word;
    while (ss >> word)
    {
        // cout << word << endl;
        // nums.push_back(word);
        if (word == "#") {
            nums.push_back(NULL);
        }
        else{
            int tmp = atoi(word.c_str());
            nums.push_back(new TreeNode(tmp));
        }
        numsCount++;
    }

    int q = 0; // BFS层次,一个一个的处理节点
    int p = 1; // 相当于q的左孩子
    while (p < numsCount)
    {
        if (nums[q] == NULL){
            q++;
        }
        else{
            if (p < cnt)
                nums[q]->left = nums[p];
            if (p + 1 < cnt)
                nums[q]->right = nums[p + 1];
            p += 2;
            q++;
        }
    }
    TreeNode* root = nums[0];
    return root;
}

采用前序遍历

参考:
http://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84?tpId=13&tqId=11214&rp=4&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

http://www.nowcoder.com/questionTerminal/cf7e25aa97c04cc1a68c8f040e71fb84

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:

    string seri(TreeNode * root)
    {
        if (root == NULL)
            return "# ";
        char str[11];
        sprintf(str, "%d ", root->val);
        string rs = str;

        rs += seri(root->left);
        rs += seri(root->right);

        return rs;
    }

    char* Serialize(TreeNode *root) {
        if (root == NULL)
            return NULL;
        string s = seri(root);
        int len = s.size();
        char *rs = new char[len+1];
        //strcpy(rs, s.c_str());
        for (int i = 0; i < len; i++)
            rs[i] = s[i];
        rs[len] = '\0';
        return rs;
    }

    TreeNode* Deser(vector<TreeNode*> nums, int len ,int &index)
    {
        if (index >= len)
            return NULL;
        TreeNode* root = NULL;
        if (index < len)
        {
            root = nums[index];
            if (root != NULL){
                root->left = Deser(nums, len, ++index);// 左边遇到null会到树底,返回后接着右子树,index始终++
                root->right = Deser(nums, len, ++index);
            }
        }
        return root;
    }

    TreeNode* Deserialize(char *str) {

        if (str == NULL || (int)strlen(str) <= 0)
            return NULL;
        // 得到一个一个的前序遍历的节点
        vector<TreeNode*> nums;
        string s(str);
        stringstream ss(s);
        string word;
        while (ss >> word)
        {
            // cout << word << endl;
            // nums.push_back(word);
            if (word == "#") {
                nums.push_back(NULL);
            }
            else{
                int tmp = atoi(word.c_str());
                nums.push_back(new TreeNode(tmp));
            }
        }

        int len = nums.size();
        int index = 0;
        TreeNode* root = Deser(nums,len, index); //解析前序遍历节点得到树

        return root;
    }
};

 

 

 我的代码

/*题目描述
请实现两个函数,分别用来序列化和反序列化二叉树*/



#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include <string.h>
#include <sstream>
#include <stdlib.h>
#include <cstdio>

#ifndef _DEBUG
#define _SECURE_SCL 0
#endif

using namespace std;

struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
		val(x), left(NULL), right(NULL) {
    }
};

class Solution {
public:
	void preCreate(TreeNode* &T)
    {
        int num;
        cin >> num;
        if (num == 0) T = NULL;
        else
        {
            T = new TreeNode(num);
            preCreate(T->left);
            preCreate(T->right);
        }
    }
	
    char* Serialize(TreeNode *root) 
	{    
        if(root == NULL)
		{
			return NULL;
		}
		
		string str = "";
		str = SerializeCore(root);
		
		int len = str.size();
		char *res = new char[len + 1];
		
		for(int i = 0; i < len; i++)
		{
			res[i] = str[i];
		}
		
		res[len] = '\0';
		
		return res;
    }
	
    TreeNode* Deserialize(char *str) {
		if(str == NULL)
		{
			return NULL;
		}
		
		
		
		
		
		
		vector<TreeNode *> nodesVec;
		const char *delm = ",";
		vector<string> strVec = split(str, delm);
		int size = strVec.size();
		for(int i = 0; i < size; ++i)
		{
			if(strVec[i] == "#")
			{
				nodesVec.push_back(NULL);
			}
			else
			{
				int val = atoi(strVec[i].c_str());
				TreeNode *n = new TreeNode(val);
				nodesVec.push_back(n);	
			}
		}
		
		int index = 0;
		TreeNode *root = DeserializeCore(nodesVec, size, index);
		return root;
    }
	
	string SerializeCore(TreeNode *root)
	{
		if(root == NULL)
		{
			return string("#,");
		}
		
		char str[10];
		sprintf(str, "%d,", root->val);
		string rs = str;
		
		rs += SerializeCore(root->left);
		rs += SerializeCore(root->right);
		
		return rs;
	}
	
	
	
	//len元素个数 index数组索引
	TreeNode *DeserializeCore(vector<TreeNode *> &num, int len, int &index)
	{
		if(index >= len)
		{
			return NULL;
		}
		
		TreeNode *node = NULL;
		if(index < len)
		{
			node = num[index];
			if(node == NULL)
			{
				return NULL;
			}
			
			node->left = DeserializeCore(num, len, ++index);
			node->right = DeserializeCore(num, len, ++index);
		}
		
		return node;
	}
	
private:
	vector<string> split(char *str, const char *delim)
	{
		vector<string> res;
		res.clear();
		
		if(str == NULL || delim == NULL)
		{
			return res;
		}
	
		char *p;
		p = strtok(str, delim);
		string s;
		while(p) 
		{
			stringstream ss(p);
			
			ss >> s;
			res.push_back(s);
			
			p = strtok(NULL, delim);
			
			s.clear();
		}
		
		return res;
	}
	
public:
	void preOrderTraver(TreeNode *T)
    {
        if (T == NULL) return;
        else
        {
            cout << T->val << "  ";
            preOrderTraver(T->left);
            preOrderTraver(T->right);
        }
    }
	
};

int main()
{
	Solution so;
    TreeNode *T1;
    TreeNode *T2;
    vector<vector<int> > vec;
	
	
    cout << "创建T1:" << endl;
    so.preCreate(T1);
    cout << "创建T1成功!" << endl;
	
	char *str = so.Serialize(T1) /*"1,2,4,#,#,5,#,#,3,6,#,#,7,#,#"*/;
	
	TreeNode *T3 = so.Deserialize(str);
	so.preOrderTraver(T3);
	cout << endl;
    //cout << "T1的前序遍历:" << endl;
    //so.preOrder(T1);
    //cout << endl;
	
	
	return 0;
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值