之前打印二叉树的时候,创建的二叉树是一颗完全平衡的二叉树,对于不平衡的树打印会出现错误,今天又重新改了一下,样子也改进了点,可以打印不平衡的二叉树,算法主要采用中序遍历和层次遍历(广度优先遍历)。
下面是几张效果图:
____________________40_______
| |
__7____ _73________________________
| | | |
_4_ _15_______ ___71 ____________105_
| | | | | | |
2 6 _11 _31___ 61_ _____91___ 105_
| | | | | | |
9 ___25 _38_ 69 _81_ _100_ 107_
| | | | | | | |
16_ 34 39 _79 81_ 92 101_ 107_
| | | | |
19 73 90 102 122
_____75_____________
| |
_______64_ ___________99____________
| | | |
_____________59_____ 67_ 82_____ __________115_______
| | | | | |
__32___ ___62 72 _89_ 99_ _118_
| | | | | | | |
_2_ _37_ 59_ _84 95_ 100_ _117 121
| | | | | | | | |
1 7 35 39_ 61 82 98 103_ 115
| |
40_ 109
|
44_
|
46
代码如下:
//binary_tree.h struct binary_tree_node{ int level; int value; int pre_space; binary_tree_node* p_left; binary_tree_node* p_right; }; struct bst_node{ int value; struct bst_node* l; struct bst_node* r; }; binary_tree_node* copy_binary_tree(bst_node* p_bst_root); void copy_binary_tree_recursively(binary_tree_node* p_node, bst_node* p_bts_node); binary_tree_node* create_binary_tree_node(int value); void destroy_binary_tree(binary_tree_node* p_root); binary_tree_node* create_binary_tree_auto(); void create_binary_tree_recursively(binary_tree_node* p_node);//generate two son nodes, when pass into one node int get_random_num();
//binary_tree.cpp #include <stdio.h> #include "binary_tree.h" #include <stdlib.h> #include <time.h> int g_random_index=0; binary_tree_node* create_binary_tree_node(int value,int level){ binary_tree_node* p_node = new binary_tree_node(); p_node->value = value; p_node->level = level; p_node->pre_space = 0; p_node->p_left = NULL; p_node->p_right = NULL; return p_node; } void destroy_binary_tree(binary_tree_node* p_root) { if(p_root != NULL) { binary_tree_node* p_left = p_root->p_left; binary_tree_node* p_right = p_root->p_right; delete p_root; p_root = NULL; destroy_binary_tree(p_left); destroy_binary_tree(p_right); } } int get_random_num(){ if(g_random_index < 1){ srand((int)time(NULL)); g_random_index ++; } int number = (int)(rand()%321); return number; } //根据一个标准的二叉树来复制打印的树结构 binary_tree_node* copy_binary_tree(bst_node* p_bst_root){ int value = p_bst_root->value; binary_tree_node* p_root = create_binary_tree_node(value,1); copy_binary_tree_recursively(p_root,p_bst_root); return p_root; } void copy_binary_tree_recursively(binary_tree_node* p_node, bst_node* p_bst_node){ int level = p_node->level; if(p_bst_node->l != NULL){//left node is not null int value_left = p_bst_node->l->value; binary_tree_node* p_left = create_binary_tree_node(value_left,level+1); p_node->p_left = p_left; copy_binary_tree_recursively(p_left, p_bst_node->l); } if(p_bst_node->r != NULL){ int value_right = p_bst_node->r->value; binary_tree_node* p_right = create_binary_tree_node(value_right,level+1); p_node->p_right = p_right; copy_binary_tree_recursively(p_right, p_bst_node->r); } }
//print_binary_tree.h void print_binary_tree(bst_node* p_bst_root);
//print_binary_tree.cpp #include <stdio.h> #include "binary_tree.h" #include <deque> #include <iostream> #include <string> //处理字符串 #include <string.h> //处理字符串 using namespace std; int g_spaces = 0; int calc_characters(int value){ if(value == 0){ return 1; } int characters = 0; while(value){ characters ++; value = value/10; } return characters; } struct str_n{ string str; string str_pointer; }; struct str_n* set_string_node(string str, string str_pointer, binary_tree_node* p_node){ //set value int value_pos = p_node->pre_space; char ch[10]; sprintf(ch,"%d",p_node->value); str.replace(value_pos,strlen(ch),ch); //set vertical line string vertical_l; string vertical_r; //set underline left int underline_length_left = 0; int underline_index_left = 0; int vertical_left_length = 0; if(p_node->p_left != NULL){ underline_length_left = p_node->pre_space - p_node->p_left->pre_space - calc_characters(p_node->p_left->value) + 1; underline_index_left = p_node->p_left->pre_space + calc_characters(p_node->p_left->value) - 1; vertical_left_length = 1; vertical_l.assign(1,'|'); } string str_underline_left(underline_length_left,'_'); str.replace(underline_index_left,underline_length_left,str_underline_left); str_pointer.replace(underline_index_left,vertical_left_length,vertical_l); //set underline right int underline_length_right = 0; int underline_index_right = 0; int vertical_right_length = 0; int vertical_right_index = 0; if(p_node->p_right != NULL){ underline_length_right = p_node->p_right->pre_space - p_node->pre_space -calc_characters(p_node->value) + 1; underline_index_right = p_node->pre_space + calc_characters(p_node->value); vertical_right_length = 1; vertical_right_index = underline_index_right+underline_length_right-1; vertical_r.assign(1,'|'); } string str_underline_right(underline_length_right,'_'); str.replace(underline_index_right,underline_length_right,str_underline_right); str_pointer.replace(vertical_right_index,vertical_right_length,vertical_r); struct str_n* p_str_n = new str_n(); p_str_n->str = str; p_str_n->str_pointer = str_pointer; return p_str_n; } int g_currunt_level = 1; void print_from_top_to_bottom(binary_tree_node* p_root) { if(p_root == NULL) return; //队列 std::deque<binary_tree_node *> deque_tree_node; deque_tree_node.push_back(p_root); string str_node(g_spaces+1,' '); string str_node_pointer(g_spaces+1,' '); //cout << string << endl; while(deque_tree_node.size()) { binary_tree_node* p_node = deque_tree_node.front();//从前面获取结点 deque_tree_node.pop_front();//之后将其弹出 if(p_node->level == g_currunt_level){ struct str_n* p_str_n = set_string_node(str_node, str_node_pointer, p_node); str_node = p_str_n->str; str_node_pointer = p_str_n->str_pointer; } if(p_node->level > g_currunt_level){ //output str_node and then set str_node to empty cout << str_node << endl; cout << str_node_pointer << endl; str_node.assign(g_spaces+1,' '); str_node_pointer.assign(g_spaces+1,' '); g_currunt_level = p_node->level; struct str_n* p_str_n = set_string_node(str_node, str_node_pointer, p_node); str_node = p_str_n->str; str_node_pointer = p_str_n->str_pointer; } //do_print_binary_tree(p_node); //先压入左结点 if(p_node->p_left) deque_tree_node.push_back(p_node->p_left); //后压入右结点 if(p_node->p_right) deque_tree_node.push_back(p_node->p_right); } cout << str_node << endl; g_currunt_level = 1;//这个很重要,之前没有设置害的我只能打印一次 g_spaces = 0; printf(" "); } void in_order(binary_tree_node* p_node){ if(p_node->p_left!=NULL){ in_order(p_node->p_left); } //Do Something with root p_node->pre_space = g_spaces; g_spaces += calc_characters(p_node->value); //printf("%d(%d) ",p_node->value,p_node->pre_space); if(p_node->p_right!=NULL){ in_order(p_node->p_right); } } void print_binary_tree(bst_node* p_bst_root){ struct binary_tree_node* p_root = copy_binary_tree(p_bst_root); in_order(p_root); print_from_top_to_bottom(p_root); }
//BST.cpp #include <malloc.h> #include <iostream> #include "binary_tree.h" #include "print_binary_tree.h" //the node of a tree, included in binary_tree.h #include <stdlib.h> #include <time.h> using namespace std; //create node with value, left child and right child struct bst_node* create_bst_node(int value, struct bst_node* l, struct bst_node* r){ struct bst_node* t =(struct bst_node*) malloc(sizeof *t);//should call free() when finished t->value = value; t->l = l; t->r = r; return t; } struct bst_node* bst_insert(struct bst_node* root, int value){ if(root == NULL) return create_bst_node(value,NULL,NULL);//tree is empty //if root is not NULL if(value < root->value) root->l = bst_insert(root->l,value);//insert into left child else if (value >= root->value) root->r = bst_insert(root->r,value);// return root; } int main(){ //create_bst_node(); srand((unsigned)time(NULL));//使用系统时间初试化随机种子 int value = rand()%123; struct bst_node* bst_root = create_bst_node(value, NULL, NULL); for(int k=0; k<33; k++){ value = rand()%123; bst_insert(bst_root, value); } print_binary_tree(bst_root); return 0; }