• 树形结构打印二叉搜索树


    之前打印二叉树的时候,创建的二叉树是一颗完全平衡的二叉树,对于不平衡的树打印会出现错误,今天又重新改了一下,样子也改进了点,可以打印不平衡的二叉树,算法主要采用中序遍历和层次遍历(广度优先遍历)。

    下面是几张效果图:

       ____________________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;
    }
    

    去吧,去吧,到彼岸去吧,彼岸是光明的世界!
  • 相关阅读:
    声明属性Hibernate的Annotation注解
    索引查询MySQL前缀索引导致的慢查询
    定义最小POJ 1384 PigBank
    执行调用bat文件启用dos命令
    控制器框架Struts与策略模式那点事
    路径位置JDK+tomcat 环境变量配置
    目录设置PHP和Apache环境搭建小记
    驱动源码看门狗用户空间程序(可用来检测服务器死机)
    安装文件MyEclipse6.5安装与卸载SVN插件方法
    问题文件Android Studio 安装完成不能打开等问题解决记录
  • 原文地址:https://www.cnblogs.com/lengyue365/p/5084128.html
Copyright © 2020-2023  润新知