写这个程序的目的是学习数据结构的时候方便调试,学习起来也比较直观。

这个是我测试SplayTree时候的gif

STEP 1

新建一个头文件,命名为DrawATree.hh, 将以下内容复制进去

#ifndef DRAWTREE_HH
#define DRAWTREE_HH #include <ostream>
#include <sstream>
#include <iostream>
#include <cmath>
#include <algorithm> namespace
{
#define lChild l_child_ //使用前将 l_child_ 更换为 自己树节点的左孩子的名字
#define rChild r_child_ //使用前将 r_child_ 更换为 自己树节点的右孩子的名字
#define data data_ //使用前将 data_ 更换为 自己树节点的数据的变量名
#define MAXN (1000) //这棵树的节点上限
#define PERID (2) //打印两个节点的横坐标间隔
unsigned int SUM; //统计当前遍历到第几个节点 #ifdef _WIN32
void clear() {system("cls"); }
#elif __linux__
void clear() { system("clear"); }
#endif // 将光标移动到 (X,Y)
std::string AXIS(int X, int Y) {
std::stringstream ss;
ss<< "\033["<< Y << ";" <<X<<"H";
return ss.str();
} struct DrawNode{
int x,y,dataSize;
}axisArray[MAXN]; //计算节点数据输出的长度
template <typename TreePtr>
int dataSize(TreePtr const& root) {
std::stringstream ss;
ss << (root->data);
return (ss.str()).length();
} //中序遍历, 从左往右画节点(不连线)
//横坐标通过全局变量SUM和上一个节点数据的输出长度算出
//纵坐标通过递归深度判断
//PERID 是两个节点间隔长度
template <typename TreePtr>
void buildDrawTree (TreePtr const& root, int deep) {
if(!root) return; //判断空节点,如果你的节点判空和我不一样,这里也要改, 比如我之前的判断空节点是(root->height_== -1). if(root->lChild) buildDrawTree(root->lChild, deep+1); axisArray[SUM] = (struct DrawNode){axisArray[SUM-1].x+axisArray[SUM-1].dataSize+PERID, deep, dataSize(root)};
std::cout << AXIS(axisArray[SUM].x, axisArray[SUM].y) << root->data;
++SUM; if(root->rChild) buildDrawTree(root->rChild, deep+1); } template <typename TreePtr>
void Draw (TreePtr const& t) { //画树函数
clear(); //清屏
SUM = 1;
int maxy = 0; buildDrawTree<TreePtr> (t, 2); //每个结点画出来 //画节点间连线,因为画的节点不会太多,所以就写了n^2的算法,比较好实现
//每个节点只有一个父节点,所以画出每个节点和自己父节点的连线即可
for(int i=1; i<SUM; i++) {
//x,y是子节点的坐标,p是父节点的axisArray数组的下标, px,py是父节点的坐标;
int x = axisArray[i].x, y = axisArray[i].y, p=0, px=0, py=y-1; if(y==1) continue; // 根结点没有父节点,跳过 for(int j=1; j<SUM; j++) { //循环找父节点
if(i==j) continue;
if((!p || abs(axisArray[j].x-x) < abs(px-x)) && axisArray[j].y+1 == y)
p = j, px = axisArray[j].x;
} int s = (2*x+axisArray[i].dataSize)>>1;
std::cout << AXIS(s,py) << '+';
if(s<px)
for(int i=s+1; i<px; i++) std::cout << AXIS(i,py) << '-';
else
for(int i=px+axisArray[p].dataSize;i<s; i++) std::cout << AXIS(i,py) << '-';
maxy = std::max(maxy, y);
}
std::cout << AXIS(1,maxy+1); //打印完把光标移到最下边.
// getchar();
}
} // namespace
#endif

STEP 2

修改头文件DrawATree.hh 第12,13,14,51行代码,如果需要的话. 代码中有注释说明怎么修改.

STEP 3

测试你的源代码.

 要保证你的节点数据可以用cout<<输出

#include "DrawATree.hh"
#include "YourTree.hh" int main() {
YourTreeType t;
Draw(t.root()); // 这里要传入你的根结点的指针!
}

实例:

树的头文件: Tree.hh

typedef struct TreeNode Node;
typedef Node* PtrNode; struct TreeNode{
char c_;
PtrNode l_child_, r_child_;
TreeNode(char c) : c_(c), l_child_(0), r_child_(0) {}
void Insert(PtrNode p, bool left);
}; void Node::Insert(PtrNode p, bool left) {
if(left) l_child_ = p;
else r_child_ = p;
}

源代码:

#include "Tree.hh"
#include "DrawATree.hh"
#define left (1)
#define right (0) int main() {
PtrNode root = new TreeNode('a');
root->Insert(new TreeNode('b'), left);
root->Insert(new TreeNode('c'), right);
Draw(root);
getchar();
}

效果:

C++ 命令行窗口打印二叉树(图形)的更多相关文章

  1. 【Python】解决Python脚本 在cmd命令行窗口运行时,中文乱码问题

    问题描述 python2.X,代码中指定了UTF-8,但是在cmd命令行窗口时,打印的中文仍然会乱码 在python3不存在该问题 运行结果: 原因 搜索得知,中文windows默认的输出编码为gbk ...

  2. <VS>MFC程序显示命令行窗口

    编写MFC程序时,想打印出调试信息,使用cout后,发现程序并没有像想象中那样自动弹出命令行窗口,要输出的信息也没地方去查看.百度后知道要手动调出命令行窗口,才可以看到输出的信息.   百度上介绍了两 ...

  3. 解决PowerShell命令行窗口中不显示光标的问题

    不知道什么原因,在有些系统上打开PowerShell命令行窗口后,光标无法显示.这种情况在Windows Server 2008/2012.Windows 8/9/10上都出现过,估计是由于某些系统软 ...

  4. 在windows中,如何使用cmd命令行窗口正确显示编码为utf-8格式的文字

    在windows中,如何使用cmd命令行窗口正确显示编码为utf-8格式的文字呢? 正确的步骤如下: 1, 打开cmd命令行窗口 2, 输入命令 >chcp 65001 数字65001代表的是c ...

  5. MySQL 遇到的问题:在服务里找不到自己的 MySQL,以及在命令行窗口中运行服务出现的问题。

    1.用数据库的时候在服务里找不到自己的 MySQL ,于是就想用命令行窗口去运行. ①.在开始里,键入 cmd ,打开命令行窗口. ②.输入:mysql -u root -p 回车,这时会提示请输入密 ...

  6. C#中隐式操作CMD命令行窗口

    原文:C#中隐式操作CMD命令行窗口 MS的CMD命令行是一种重要的操作界面,一些在C#中不那么方便完成的功能,在CMD中几个简单的命令或许就可以轻松搞定,如果能在C#中能完成CMD窗口的功能,那一定 ...

  7. 在windows命令行窗口下执行:查看所有的端口占用情况

    开始--运行--cmd 进入命令提示符 输入netstat -ano 即可看到所有连接的PID 之后在任务管理器中找到这个PID所对应的程序如果任务管理器中没有PID这一项,可以在任务管理器中选&qu ...

  8. Windows 桌面和文件夹的右键->打开命令行窗口

    Windows 桌面和文件夹的右键->打开命令行窗口 1.先按下shift,再点鼠标右键运行CMD,(不是管理员权限) 上图是我已经加了右键的,并且 系统设置了  ps代替cmd,所以是“在此处 ...

  9. 命令行窗口中用telnet测试HTTP协议

    1. 命令行窗口中用telnet测试HTTP协议 HTTP消息是由普通ASCII文本组成.消息包括消息头和数据体部分.消息头以行为单位,每行以CRLF(回车和换行)结束,消息头结束后,额外增加一个CR ...

随机推荐

  1. <c:if >标签的坑!!

    <c:if test="${trans.Transition}"> <input id="${trans.nextnode}" type=&q ...

  2. Xen入门系列二【使用 virt-install 安装虚拟机】

    系统环境:Centos 6.5 + Xen4Centos安装方式 相关链接:Xen4Centos方式安装Xen请查看:http://www.cnblogs.com/hackboy/p/3662432. ...

  3. Linux系统使用IBMV3700存储(可用)

    第一步:在存储上添加主机,主机采用ISCSI连接,此时需要主机的iqn 主机上获取IQN的命令如下: cat /etc/iscsi/initiatorname.iscsi 此时添加的主机状态处于脱机的 ...

  4. JVM简述

    JVM的东西太多了,我们刚开始学java的时候,就会接触堆.栈,还有方法区,因为我们要知道new出来的对象放在哪里,局部变量放在哪里,static修饰的变量放在哪里. 我从网上截一个图: 这里有三大部 ...

  5. Android7.0 USBCamera设备/dev/video0无读权限

    Android7.0的系统,具备root权限,执行 # adb shell # su # chmod 777 /dev/video0 在5.0的系统中可以预览图像,7.0返回无读权限 File fil ...

  6. 01_JDK的下载-安装-配置

    下载 https://www.oracle.com/technetwork/java/javase/downloads/index.html 安装 1.安装路径不要有空格(去除安装路径中的Progra ...

  7. FPGA开平方的实现

    3种方法: 1.JPL近似的实现方法 `timescale 1ns / 1ps )( clk, syn_rst, dataa, datab, ampout); input clk; :] dataa; ...

  8. tomcat部署项目方式

    三大部署方式1.   Context描述文件部署通过独立的Context文件描述清楚项目的访问路径和地址,tomcat在启动的时候会解析这个Context文件,创建一个Context对象. Conte ...

  9. Docker的部署安装(CentOS)

    环境准备 操作系统需求 为兼容企业级应用,学习选用Centos7做为部署安装Docker的系统平台 # 通过以下命令可查看系统版本和内核版本等信息 cat /etc/redhat-release #- ...

  10. Nginx笔记总结二十:nginx索引目录配置

    location / { autoindex on; autoindex_localtime on; }