利用PHP实现二叉树的图形显示
来源:互联网 发布:电子阅读器软件 编辑:程序博客网 时间:2024/06/11 09:00
前言:
最近老师布置了一个作业:理解并实现平衡二叉树和红黑树,本来老师是说用C#写的,但是我学的C#基本都还给老师了,怎么办?那就用现在最熟悉的语言PHP来写吧!
有一个问题来了,书上在讲解树的时候基本上会给出形象的树形图。但是当我们自己试着实现某种树,在调试、输出的时候确只能以字符的形式顺序地输出。这给调试等方面带来了很大的不便。然后在各种百度之后,我发现利用PHP实现二叉树的图形显示的资源几乎是零!好吧,那我就自己个儿实现一个!
效果显示:
如果我是直接在这一步摆代码的话,估计大家会比较烦闷,那我就直接上结果吧,后面在补代码,先激发激发大家的阅读兴趣:
1、搜索二叉树:
2、平衡二叉树:
3、红黑树:
上代码:
我们给图片创建一个类吧,显得稍微的小高级:
#image.php 文件<?php/** * author:LSGOZJ * time:2016/10/24 12:38 * description: 绘制二叉树图像 */class image{ //树相关设置 //每层之间的间隔高度 private $level_high = 100; //最底层叶子结点之间的宽度 private $leaf_width = 50; //结点圆的半径 private $rad = 20; //根节点离边框顶端距离 private $leave = 20; //树(保存树对象的引用) private $tree; //树的层数 private $level; //完全二叉树中最底层叶子结点数量(计算图像宽度时用到,论如何实现图片大小自适应) private $maxCount; //图像相关设置 //画布宽度 private $width; //画布高度 private $height; //画布背景颜色(RGB) private $bg = array( 220, 220, 220 ); //节点颜色(搜索二叉树和平衡二叉树时用) private $nodeColor = array( 255, 192, 203 ); //图像句柄 private $image; /** * 构造函数,类属性初始化 * @param $tree 传递一个树的对象 * @return null */ public function __construct($tree) { $this->tree = $tree; $this->level = $this->getLevel(); $this->maxCount = $this->GetMaxCount($this->level); $this->width = ($this->rad * 2 * $this->maxCount) + $this->maxCount * $this->leaf_width; $this->height = $this->level * ($this->rad * 2) + $this->level_high * ($this->level - 1) + $this->leave; //1.创建画布 $this->image = imagecreatetruecolor($this->width, $this->height); //新建一个真彩色图像,默认背景是黑色 //填充背景色 $bgcolor = imagecolorallocate($this->image, $this->bg[0], $this->bg[1], $this->bg[2]); imagefill($this->image, 0, 0, $bgcolor); } /** * 返回传进来的树对象对应的完全二叉树中最底层叶子结点数量 * @param $level 树的层数 * @return 结点数量 */ function GetMaxCount($level) { return pow(2, $level - 1); } /** * 获取树对象的层数 * @param null * @return 树的层数 */ function getLevel() { return $this->tree->Depth(); } /** * 显示二叉树图像 * @param null * @return null */ public function show() { $this->draw($this->tree->root, 1, 0, 0); header("Content-type:image/png"); imagepng($this->image); imagedestroy($this->image); } /** * (递归)画出二叉树的树状结构 * @param $root,根节点(树或子树) $i,该根节点所处的层 $p_x,父节点的x坐标 $p_y,父节点的y坐标 * @return null */ private function draw($root, $i, $p_x, $p_y) { if ($i <= $this->level) { //当前节点的y坐标 $root_y = $i * $this->rad + ($i - 1) * $this->level_high; //当前节点的x坐标 if (!is_null($parent = $root->parent)) { if ($root == $parent->left) { $root_x = $p_x - $this->width / (pow(2, $i)); } else { $root_x = $p_x + $this->width / (pow(2, $i)); } } else { //根节点 $root_x = (1 / 2) * $this->width; $root_y += $this->leave; } //画结点(确定所画节点的类型(平衡、红黑、排序)和方法) $method = 'draw' . get_class($this->tree) . 'Node'; $this->$method($root_x, $root_y, $root); //将当前节点和父节点连线(黑色线) $black = imagecolorallocate($this->image, 0, 0, 0); if (!is_null($parent = $root->parent)) { imageline($this->image, $p_x, $p_y, $root_x, $root_y, $black); } //画左子节点 if (!is_null($root->left)) { $this->draw($root->left, $i + 1, $root_x, $root_y); } //画右子节点 if (!is_null($root->right)) { $this->draw($root->right, $i + 1, $root_x, $root_y); } } } /** * 画搜索二叉树结点 * @param $x,当前节点的x坐标 $y,当前节点的y坐标 $node,当前节点的引用 * @return null */ private function drawBstNode($x, $y, $node) { //节点圆的线颜色 $black = imagecolorallocate($this->image, 0, 0, 0); $nodeColor = imagecolorallocate($this->image, $this->nodeColor[0], $this->nodeColor[1], $this->nodeColor[2]); //画节点圆 imageellipse($this->image, $x, $y, $this->rad * 2, $this->rad * 2, $black); //节点圆颜色填充 imagefill($this->image, $x, $y, $nodeColor); //节点对应的数字 imagestring($this->image, 4, $x, $y, $node->key, $black); } /** * 画平衡二叉树结点 * @param $x,当前节点的x坐标 $y,当前节点的y坐标 $node,当前节点的引用 * @return null */ private function drawAvlNode($x, $y, $node) { $black = imagecolorallocate($this->image, 0, 0, 0); $nodeColor = imagecolorallocate($this->image, $this->nodeColor[0], $this->nodeColor[1], $this->nodeColor[2]); imageellipse($this->image, $x, $y, $this->rad * 2, $this->rad * 2, $black); imagefill($this->image, $x, $y, $nodeColor); imagestring($this->image, 4, $x, $y, $node->key . '(' . $node->bf . ')', $black); } /** * 画红黑树结点 * @param $x,当前节点的x坐标 $y,当前节点的y坐标 $node,当前节点的引用 * @return null */ private function drawRbtNode($x, $y, $node) { $black = imagecolorallocate($this->image, 0, 0, 0); $gray = imagecolorallocate($this->image, 180, 180, 180); $pink = imagecolorallocate($this->image, 255, 192, 203); imageellipse($this->image, $x, $y, $this->rad * 2, $this->rad * 2, $black); if ($node->IsRed == TRUE) { imagefill($this->image, $x, $y, $pink); } else { imagefill($this->image, $x, $y, $gray); } imagestring($this->image, 4, $x, $y, $node->key, $black); }}
好,现在我们来看看在客户端如何调用:
#client.phpclass Client{ public static function Main() { try { //实现文件的自动加载 function autoload($class) { include strtolower($class) . '.php'; } spl_autoload_register('autoload'); $arr = array(62, 88, 58, 47, 35, 73, 51, 99, 37, 93);// $tree = new Bst(); //搜索二叉树 $tree = new Avl(); //平衡二叉树// $tree = new Rbt(); //红黑树 $tree->init($arr); //树的初始化// $tree->Delete(62);// $tree->Insert(100);// $tree->MidOrder(); //树的中序遍历(这也是调试的一个手段,看看数字是否从小到大排序) $image = new image($tree); $image->show(); //显示图像 } catch (Exception $e) { echo $e->getMessage(); } }}Client::Main();
注:这里用到的那三个树的类大家可以参照我的另外三篇博客:《PHP二叉树(一):二叉搜索树》、《PHP二叉树(二):平衡二叉树(AVL)》、《PHP二叉树(三):红黑树》
好了,终于实现了,由于对图像这方面不是太熟悉,加上坐标的计算比较复杂,这个显示功能我也差不多做了两天。所以大神就不要喷我了!
2 0
- 利用PHP实现二叉树的图形显示
- 二叉树的图形显示
- 利用Matlab实现二叉树的树形显示
- 用C++实现二叉树的字符图形显示
- 二叉树图形显示(VC)
- PHP-利用二叉堆实现TopK-算法
- PHP-利用二叉堆实现TopK-算法
- PHP-利用二叉堆实现TopK-算法
- 利用C语言实现sin(x)曲线与cos(x)曲线图形的同时显示
- php实现二叉树
- PHP实现二叉树的遍历
- PHP实现排序二叉树的基本功能
- 利用图形页实现动画的方法
- 利用 annotation 命令实现图形的标注
- python图形化显示非搜索二叉树
- 利用GNUplot图形化显示cyclictest的数据
- 利用二叉树的排序算法c#实现
- 利用栈实现二叉树的后序遍历算法
- Scala语言扫盲第一篇
- python ssh 公钥私钥 密码认证 sftp 服务器文件下载上传
- 怎么测试另一台机器的某个端口是否开放
- 99%的人都理解错了 HTTP 中 GET 与 POST 的区别
- 四种基本的排序方法:冒泡排序,选择排序,插入排序,快速排序
- 利用PHP实现二叉树的图形显示
- 顺序容器之list
- mycomponent-connector.js
- MinGW下载地址
- AFNetWorking NSParameterAssert(URLString)为空
- keil5中文乱码的解决
- 为何 Boost 的 Asio 要使用 Proactor 模式实现?
- ECS 服务器远程登陆日志查询方法
- 第8周项目5-计数的模式匹配