突然想着怎么打印一颗二叉树,本来想用控制台输出,但是直觉告诉我那太麻烦了,于是我使用了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;
}