打印二叉树(1)

突然想着怎么打印一颗二叉树,本来想用控制台输出,但是直觉告诉我那太麻烦了,于是我使用了easyx图形库。

下面这段程序,首先随机生成一棵节点数为nums的二叉树,然后使用easyx图形库展示出来,开发工具VS2022。

程序

#include <iostream>
#include <graphics.h>
#include <conio.h>
#include <random>

const int width = 1000,height = 600,radius = 2;


//二叉树结构定义
struct node
{
    node(int val, struct node* left, struct node* right) :_val(val), _left(left), _right(right) {};
    int _val;
    struct node* _left, *_right;
};

class binary_tree
{
public:
    binary_tree(int nums) :_node_nums(nums), _root(create_tree(nums))//构造函数 创建一颗节点数量为 nums 的随机二叉树
    {

    }

    struct node*  create_tree(int nums) //创建节点数量为nums的二叉树
    {
        if (nums <= 0) return nullptr;
        //创建一个根节点
        
        std::random_device rd;
        // 使用随机设备生成随机数引擎
        std::mt19937 gen(rd());
        // 生成随机整数
        std::uniform_int_distribution<int> isback(1, 3); // 生成1到3之间的整数
        std::uniform_int_distribution<int> intval(1, 100); // 生成1到100之间的整数
       
        int val = intval(gen);
        struct node* root = new node(val,nullptr,nullptr);

        //随机创建树的左右孩子
        int dir = isback(gen);

        if (dir == 1)
        {
            nums = nums - 1;
            root->_left = create_tree(static_cast<int>(nums / 2));
            root->_right=create_tree(nums - static_cast<int>(nums / 2));
        }
        else if (dir == 2)
        {
            root->_left = create_tree(nums-1);
        }
        else
        {
            root->_right = create_tree(nums-1);
        }
        return root;
    }

    void destory_tree(struct node* root)
    {
        if (root == nullptr)
            return;

        destory_tree(root->_left);
        destory_tree(root->_right);

        _node_nums-=1;
        std::cout << " node with val of " << root->_val << " deleted. " << _node_nums << " nodes left. " << std::endl;
        delete root;
    }

    

    void show_tree() const
    {
        draw_one_node(_root,radius, 0 + radius, width - radius , radius);
    }
    ~binary_tree()
    {
        destory_tree(_root);
    }

private:
    void draw_one_node(struct node* root,int r , int left_bound, int right_bound , int depth) const  //绘制一个节点
    {
        if (root == nullptr) return;

        int x = (left_bound + right_bound) /2, y = depth;
        circle(x ,y ,r);//画当前节点
        //Sleep(500);
        TCHAR s[5];
        swprintf_s(s, _T("%d"), root->_val);
        outtextxy(x, y, s);
        if (root->_left)
        {
            line(x, y, (left_bound + x - r) / 2, depth + 30);
            draw_one_node(root->_left, r, left_bound, x - r, depth + 30);
        }
        if (root->_right)
        {
            line(x, y, (right_bound + x - r) / 2, depth + 30);
            draw_one_node(root->_right, r, x - r,right_bound , depth + 30);

        }
    }
private:
    int _node_nums;
    struct node* _root;
};


int main() {

    
    {
        binary_tree t(20);
        initgraph(width, height);
        t.show_tree();
        _getch();				// 按任意键继续
        closegraph();			// 关闭绘图窗口
    }
    _getch();
    return 0;
}

运行结果如下

可以看到,因为是随机生成的,有些节点混在一起,导致不能看清,这个问题等以后有时间再解决。

更改插入方法后,可能使得二叉树节点分布更加“均匀”

#include <iostream>
#include <graphics.h>
#include <conio.h>
#include <random>

const int width = 1000,height = 600,radius = 2;


//二叉树结构定义
struct node
{
    node(int val, struct node* left, struct node* right) :_val(val), _left(left), _right(right) {};
    int _val;
    struct node* _left, *_right;
};

class binary_tree
{
public:
    binary_tree(int nums) :_node_nums(nums), _root(create_tree(nums))//构造函数 创建一颗节点数量为 nums 的随机二叉树
    {

    }
    struct node* __create_tree(struct node* root,int val)
    {
        if (root == nullptr) return new node(val,nullptr,nullptr);
        std::random_device rd;
        // 使用随机设备生成随机数引擎
        std::mt19937 gen(rd());
        std::uniform_int_distribution<int> choice(0, 1);

        if (choice(gen)) root->_left = __create_tree(root->_left , val);
        else             root->_right = __create_tree(root->_right , val);

        return root;
    }
    struct node*  create_tree(int nums) //创建节点数量为nums的二叉树
    {
        if (nums <= 0) return nullptr;
        //创建一个根节点
        struct node* root = nullptr;
        std::random_device rd;
        // 使用随机设备生成随机数引擎
        std::mt19937 gen(rd());
        std::uniform_int_distribution<int> intval(1, 100); // 生成1到100之间的整数
        

        for (int i = 0; i < nums; ++i)
            root = __create_tree(root , intval(gen));
        
        return root;
    }

    void destory_tree(struct node* root)
    {
        if (root == nullptr)
            return;

        destory_tree(root->_left);
        destory_tree(root->_right);

        _node_nums-=1;
        std::cout << " node with val of " << root->_val << " deleted. " << _node_nums << " nodes left. " << std::endl;
        delete root;
    }

    

    void show_tree() const
    {
        draw_one_node(_root,radius, 0 + radius, width - radius , radius);
    }
    ~binary_tree()
    {
        destory_tree(_root);
    }

private:
    void draw_one_node(struct node* root,int r , int left_bound, int right_bound , int depth) const  //绘制一个节点
    {
        if (root == nullptr) return;

        int x = (left_bound + right_bound) /2, y = depth;
        circle(x ,y ,r);//画当前节点
        //Sleep(500);
        TCHAR s[5];
        swprintf_s(s, _T("%d"), root->_val);
        outtextxy(x, y, s);
        if (root->_left)
        {
            setlinecolor(RED);
            line(x, y, (left_bound + x - r) / 2, depth + 30);
            draw_one_node(root->_left, r, left_bound, x - r, depth + 30);
        }
        if (root->_right)
        {
            setlinecolor(GREEN);
            line(x, y, (right_bound + x - r) / 2, depth + 30);
            draw_one_node(root->_right, r, x - r,right_bound , depth + 30);

        }
    }
private:
    int _node_nums;
    struct node* _root;
};


int main() {
    {
        binary_tree t(200);
        initgraph(width, height);
        t.show_tree();
        _getch();				// 按任意键继续
        closegraph();			// 关闭绘图窗口
    }
    _getch();
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值