zoukankan      html  css  js  c++  java
  • 树形结构打印二叉搜索树

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

    下面是几张效果图:

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

    去吧,去吧,到彼岸去吧,彼岸是光明的世界!
  • 相关阅读:
    保存时出错jup
    Spyder默认页面布局调整
    根据所处位置提取单元格内容的函数(left、right、mid)和查找字符串位于单元格内容第几位的函数(find)
    excel打印出现多余空白页
    Excel的布尔值运算
    excel VBA一个fuction同时执行多个正则表达式,实现方法
    excel VBA把一个单元格内容按逗号拆分并依次替换到另一个单元格的括号里面(本题例子,把文本中的括号换成{答案}的格式,并按顺序填空)
    excel自动记录项目完成进度,是否逾期,逾期/提前完成天数,计算天数可以把now()改为today()
    jquery循环动画
    jquery动画(控制动画隐藏、显示时间轴)
  • 原文地址:https://www.cnblogs.com/lengyue365/p/5084128.html
Copyright © 2011-2022 走看看