二叉树反序列化与直观打印

来源:互联网 发布:ps3模拟器数据损坏 编辑:程序博客网 时间:2024/06/05 02:19

二叉树算法当中一般不提供相应的输入输出函数,这就使得在调试相关二叉树算法的时候需要手工的在纸上演算而没有直观的观察到效果.


自己做了一点费力的工作,将二叉树层次遍历的序列还原成二叉树,并且将二叉树尽量形象的打印出来.

反序列化的过程我们这样定义,对于一个任意的二叉树,按照层次遍历的方式得到序列,空节点用#表示,分隔符采用!.
例如序列 1!2!3!#!4!的结构是:

1
/ \
2 3
\
4

直观打印二叉树采用的是类似上述结构.首先遍历二叉树得到二叉树的层数,然后确定最下面的一排最大的空白的数量.按照公式

maxSpace=pow(2,level1)+(pow(2,level1)1)2
算出. 那么递推根节点位置是maxSpace/2,下一层间隔是maxSpace/4,依此类推.

虽然现在已经对代码不太自豪了,完善以下对刷题debug还算有用,有拿去用的尽管拿去,非常希望能指出其中的问题和代码的粗鄙之处,使我受益.
演示下效果:
输入: 1!2!3!4!5!6!7!8!9!10!#!
输出:

       1  /         \ 2          3/   \      /   \4    5     6    7/ \  /8  9 10

反序列化代码如下(释放内存部分未实现):

#include<iostream>#include<math.h>#include<string>#include<queue>using namespace std;struct TreeNode {    int val ;    TreeNode(int vvi){       val = vvi;    }    int posi =0;    int posj =0;    TreeNode * parent=NULL;    TreeNode * left;    TreeNode * right;};string getVal(string &s){   string res ="";   int i =0 ;   while(i < s.size()&&s[i]!='!')   {     res += s[i];     i++;   }   if(i+1 < s.size())   s= s.substr(i+1,s.size());   else   s="";   return res;}/* ===================================================*    二叉树反序列化*    str = "1!2!3!4!#!#!5!#!#!#!#!"*///====================================================TreeNode * recoverByString(string s){    if(s.empty())return NULL;      string val = getVal(s);      queue<TreeNode *> que;      if(val=="#"||val=="")         return NULL;      TreeNode * root = new TreeNode(stoi(val));      que.push(root);      while(s!="")      {          TreeNode * node = que.front();          que.pop();          string left  = getVal(s);          string right = getVal(s);          if(left=="#")node->left = NULL;          else if(left!=""){             TreeNode * nl = new TreeNode(stoi(left));             nl->parent = node;             node->left = nl;             que.push(nl);          }          if(right=="#")node->right=NULL;          else  if(right!="")          {            TreeNode * nr = new TreeNode(stoi(right));            nr->parent = node;            node->right = nr;            que.push(nr);          }      }    return root;    }/*======================================================*    释放二叉树的空间**///===================================================void freeTree(TreeNode *root){}void Inorder(TreeNode *root){   if(root==NULL){return ;}    cout <<  root->val<<" ";    Inorder(root->left);    Inorder(root->right);}/*======================================================*    直观打印二叉树**///===================================================void PrintBtree(TreeNode * root){  //求出二叉树的层数  queue<TreeNode *> que;  if(root==NULL)return ;  que.push(root);  TreeNode * last = root ;  int level = 0 ;  TreeNode * nlast = NULL;  while(!que.empty())  {     TreeNode * node = que.front();     que.pop();     if(node->left!=NULL)     {         que.push(node->left);        nlast = node->left;       }     if(node->right!=NULL)     {        que.push(node->right);        nlast = node->right;     }     if(node == last)     {        last = nlast;        level++;     }  } // 求出最后一行空格的数量 int maxSpace = pow(2, level-1)+(pow(2,level-1)-1)*2; //vector<vector<TreeNode *> > map(level , vector<TreeNode*>(maxSpace , NULL)); root->posi =0; root->posj =maxSpace/2; que.push(root); last = root; nlast = NULL; int curr_level =1 ; vector<TreeNode *> temp; while(!que.empty()) {   TreeNode * node = que.front();   que.pop();   temp.push_back(node);   // 找到node所在位置   if(node!=root)   {     node->posi = node->parent->posi+1;     if(node->parent->left == node){       node->posj = node->parent->posj - (1.0/pow(2,curr_level))*maxSpace;                 }else{       node->posj = node->parent->posj + (1.0/pow(2,curr_level))*maxSpace;     }   }  if(node->left!=NULL)  {    nlast = node->left;    que.push(node->left);  }  if(node->right!=NULL)  {    nlast = node->right;    que.push(node->right);  }  if(node == last)  {     last = nlast;     curr_level++;// 打印当前层    int j =0 ;    //for(auto i : temp)cout<<i->val<<" "; cout << endl;    for(int i =0 ; i < maxSpace&&j<temp.size(); i++)    {       if(i==temp[j]->posj&&temp[j]!=root)       {          if(temp[j]->parent->left == temp[j])             cout <<" "<<"/";          else             cout <<"\b\\";          j++;       }else       cout << " ";    }    cout <<endl;    j=0;    for(int i =0 ; i< maxSpace&&j<temp.size() ; i++ )    {       if(i==temp[j]->posj){       //cout << " ( " << temp[j]->posj<<")";         cout << temp[j]->val;         j++;       }else        cout << " ";    }     temp.clear();     cout << endl;  } }}int main(){   string s = "1!2!3!4!#!#!5!6!#!#!7!";   TreeNode *root= recoverByString(s);   PrintBtree(root); //vector<TreeNode *> nodes;//  Inorder(root);}
原创粉丝点击