【说明】:
本文是左程云老师所著的《程序员面试代码指南》第三章中“如何较为直观的打印二叉树”这一题目的C++复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
二叉树可以用常规的三种遍历结果来描述其结构,但不够直观。尤其是二叉树中有重复值的时候,仅通过三种遍历的结果来构造二叉树的真实结构更是难上加难,有时则根本不可能。给定一个二叉树的头节点 head,已知二叉树节点值的类型为 32 位整形,请实现一个打印二叉树的函数,可以直观的展现树的形状,也便于画出真实的结构。
二叉树的图例:
打印结果:
【思路】:
1、打印顺序:右节点 -> 根节点 -> 左节点
2、每个节点所占的空间固定为 len,其中子层与父层的间隔也固定为 len。
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现及测试】:
实现及测试代码:
1 /* 2 *文件名:bt_print.cpp 3 *作者 4 *摘要:直观的打印二叉树 5 */ 6 7 #include <iostream> 8 #include <string> 9 #include <sstream> 10 11 using namespace std; 12 13 class Node 14 { 15 public: 16 Node(int data) 17 { 18 value = data; 19 left = NULL; 20 right = NULL; 21 } 22 public: 23 int value; 24 Node *left; 25 Node *right; 26 }; 27 28 /* 29 *函数介绍:先打印右子树,再打印根节点,最后打印左子树 30 *输入参数:root为根节点,height为当前处于二叉树的那一层(从0层开始);to为根、左、右节点的区分符号;len为格式化打印参数,固定为17,即每个节点都将占有17个字符的位置 31 *输出参数:无 32 *返回值:无 33 */ 34 void printInorder(Node *root,int height,string to,int len) 35 { 36 if(NULL == root) 37 return ; 38 printInorder(root->right,height+1,"v",len);//先打印右子树 39 //打印跟节点 40 stringstream ss; 41 ss << root->value; 42 string val = to + ss.str() + to; //构造H*H或v*v或^*^ 43 int lenM = val.length(); 44 int lenL = (len-lenM)/2; 45 int lenR = len -lenM-lenL; 46 val = string(lenL,' ') + val + string(lenR,' '); 47 cout << string(height*len,' ') << val << endl; 48 printInorder(root->left,height+1,"^",len); 49 return ; 50 } 51 52 void printTree(Node *root) 53 { 54 cout << "Binary Tree:" << endl; 55 printInorder(root,0,"H",17); 56 cout << endl; 57 } 58 59 void createBT(Node **head,int arr[],int len,int index=0) 60 { 61 if(index > len-1 || -1 == arr[index] ) 62 return; 63 (*head) = new Node(arr[index]); 64 createBT(&((*head)->left),arr,len,2*index+1); 65 createBT(&((*head)->right),arr,len,2*index+2); 66 } 67 68 int main() 69 { 70 int arr[] = {1,2,3,4,-1,5,6,-1,7}; 71 Node *root = NULL; 72 createBT(&root,arr,9); 73 printTree(root); 74 75 return 0; 76 }
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。