之前打印二叉树的时候,创建的二叉树是一颗完全平衡的二叉树,对于不平衡的树打印会出现错误,今天又重新改了一下,样子也改进了点,可以打印不平衡的二叉树,算法主要采用中序遍历和层次遍历(广度优先遍历)。
下面是几张效果图:
____________________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("\n");
}
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)\t",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;
}