数据结构的老师写了一个显示二叉树的程序.用C语言实现.在二叉树的基本操作的基础上,利用绘图函数实现了二叉树在屏幕上的输出,并可以通过键盘控制树的显示比例,字体大小,等等.
我觉得这个程序很有趣,就用C#重写了一次.基本实现了与老师那个相同的功能.不过他的是控制台应用程序,我的是窗体应用程序.而且程序代码完全不同.
这个是程序的截图:
下面是程序的具体代码:
程序主要由四个类组成:
BinaryTree : 实现基本的二叉树数据结构.是程序的底层.
TreeGraph: 实现绘图的操作.是连接底层数据结构和窗体显示的桥梁.程序的中间层.
Form_Tree: 窗体类.
Setting: 在其中设置程序运行时的变量,方便修改.
类图:
下面是各个文件的代码
Setting.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace BinaryTree
{
/// <summary>
/// Setting 类用于设定环境变量
/// </summary>
class Setting
{
public static int[] initTree = new int[] { 50, 33, 89, 20, 45, 60, 95, 10, 25, 40 }; // 用以初始化Tree
public static int distanceHeight = 50; // 两个节点之间的高度差
public static int distanceWidth = 20; // 两个节点之间的宽度差
public static int disHChange = 3; // 高度差的变化幅度
public static int disWChange = 1; // 宽度差的变化幅度
public static int nodeRadius = 15; // 节点圆圈的半径
public static int radiusChange = 2; // 节点圆圈半径的变化幅度
public static int radiusMin = 15; // 节点圆圈半径所允许的最小值
public static int middleX = 300; // 绘图中心点的横坐标
public static int middleY = 260; // 绘图中心点的纵坐标
public static int screenH = 350; // 屏幕高度
public static int screenW = 600; // 屏幕宽度
public static Color backColor = Color.LightSteelBlue; // 背景颜色
private static Color fontColor = Color.Black; // 字体颜色
public static Brush fontBrush = new SolidBrush(fontColor);
private static Color lineColor = Color.Orange; // 线条颜色
public static SolidBrush cirBrush = new SolidBrush(lineColor);
public static Pen myPen = new Pen(lineColor);
public static float myPenChange = 1F;
public static Font myFont = new Font("Arial", 18, FontStyle.Regular, GraphicsUnit.Pixel);
public static float fontChange = 2.8F;
}
}
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace BinaryTree
{
/// <summary>
/// Setting 类用于设定环境变量
/// </summary>
class Setting
{
public static int[] initTree = new int[] { 50, 33, 89, 20, 45, 60, 95, 10, 25, 40 }; // 用以初始化Tree
public static int distanceHeight = 50; // 两个节点之间的高度差
public static int distanceWidth = 20; // 两个节点之间的宽度差
public static int disHChange = 3; // 高度差的变化幅度
public static int disWChange = 1; // 宽度差的变化幅度
public static int nodeRadius = 15; // 节点圆圈的半径
public static int radiusChange = 2; // 节点圆圈半径的变化幅度
public static int radiusMin = 15; // 节点圆圈半径所允许的最小值
public static int middleX = 300; // 绘图中心点的横坐标
public static int middleY = 260; // 绘图中心点的纵坐标
public static int screenH = 350; // 屏幕高度
public static int screenW = 600; // 屏幕宽度
public static Color backColor = Color.LightSteelBlue; // 背景颜色
private static Color fontColor = Color.Black; // 字体颜色
public static Brush fontBrush = new SolidBrush(fontColor);
private static Color lineColor = Color.Orange; // 线条颜色
public static SolidBrush cirBrush = new SolidBrush(lineColor);
public static Pen myPen = new Pen(lineColor);
public static float myPenChange = 1F;
public static Font myFont = new Font("Arial", 18, FontStyle.Regular, GraphicsUnit.Pixel);
public static float fontChange = 2.8F;
}
}
Tree.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace BinaryTree
{
/// <summary>
/// 实现基本的数据结构
/// 提供二叉树的基本操作
/// 包括构造一个空树,插入,查找,删除
/// </summary>
public class BinaryTree
{
public TreeNode root; //根节点
bool found = false; //默认查找不存在
/// <summary>
/// 构造函数-构造一个空树
/// </summary>
public BinaryTree()
{
root = null;
}
public TreeNode TreeNode
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
internal TreeGraph TreeGraph
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
/// <summary>
/// 获得树的高度
/// </summary>
/// <returns></returns>
public int Height()
{
if (root == null)
{
return 1;
}
return Math.Max(Height(root.LeftNode), Height(root.RightNode)) + 1;
}
/// <summary>
/// 删除元素
/// </summary>
/// <param name="data">要删除的元素的值</param>
public void Remove(int data)
{
if (root == null)
{
return;
}
if (!Search(data))
{
return;
}
if (root.data == data)
{
TreeNode tmp = Min(root.RightNode);
if (tmp == null)
{
root = root.LeftNode;
}
else
{
root.data = tmp.data;
Remove(root, root.RightNode, 1, tmp.data);
}
}
else if (root.data < data)
{
Remove(root, root.RightNode, 1, data);
}
else
{
Remove(root, root.LeftNode, 0, data);
}
}
/// <summary>
/// 查找是否存在该元素
/// </summary>
/// <param name="data">要查找的元素的值</param>
/// <returns></returns>
public bool Search(int data)
{
if (root == null)
{
return false;
}
bool temp = false;
found = false;
if (root.data == data)
{
temp = true;
}
else
{
temp = Search(root, data);
}
return temp;
}
/// <summary>
/// 插入元素
/// </summary>
/// <param name="data">要插入的元素的值</param>
public void Insert(int data)
{
if (Search(data))
{
return;
}
if (root == null)
{
root = new TreeNode();
root.data = data;
}
else
{
Insert(root, data);
}
}
/// <summary>
/// 打印
/// </summary>
public void Print()
{
if (root == null)
{
Console.WriteLine("Empty");
}
else
{
Print(root);
Console.WriteLine();
}
}
/// <summary>
/// 获得树的高度,递归
/// </summary>
/// <param name="parent"></param>
/// <returns></returns>
private int Height(TreeNode parent)
{
if (parent == null)
{
return 0;
}
return Math.Max(Height(parent.LeftNode), Height(parent.RightNode)) + 1;
}
/// <summary>
/// 获得该节点最小右子女,用于删除元素使用
/// </summary>
/// <param name="parent"></param>
/// <returns></returns>
private TreeNode Min(TreeNode parent)
{
TreeNode temp = parent;
while (temp != null)
{
if (temp.LeftNode == null)
return temp;
else
temp = temp.LeftNode;
}
return null;
}
/// <summary>
/// 删除元素递归
/// </summary>
/// <param name="parent"></param>
/// <param name="cur"></param>
/// <param name="direction"></param>
/// <param name="data"></param>
private void Remove(TreeNode parent, TreeNode cur, int direction, int data)
{
if (cur == null)
{
return;
}
if (cur.data == data)
{
if (cur.LeftNode == null)
{
if (direction == 0)
parent.LeftNode = cur.RightNode;
else
parent.RightNode = cur.RightNode;
}
else if (cur.RightNode == null)
{
if (direction == 0)
parent.LeftNode = cur.LeftNode;
else
parent.RightNode = cur.LeftNode;
}
else
{
TreeNode tmp = Min(cur.RightNode);
cur.data = tmp.data;
Remove(cur, cur.RightNode, 1, tmp.data);
}
}
else if (cur.data > data)
{
Remove(cur, cur.LeftNode, 0, data);
}
else
{
Remove(cur, cur.RightNode, 1, data);
}
}
/// <summary>
/// 查找是否存在该元素,递归
/// </summary>
/// <param name="node"></param>
/// <param name="data"></param>
/// <returns></returns>
private bool Search(TreeNode node, int data)
{
if (node.data == data)
{
found = true;
}
else
{
if (node.data > data)
{
if (node.LeftNode != null)
{
Search(node.LeftNode, data);
}
}
else
{
if (node.RightNode != null)
{
Search(node.RightNode, data);
}
}
}
return found;
}
/// <summary>
/// 插入元素,递归
/// </summary>
/// <param name="node"></param>
/// <param name="data"></param>
private void Insert(TreeNode node, int data)
{
if (node.data > data)
{
if (node.LeftNode == null)
{
TreeNode temp = new TreeNode();
temp.data = data;
node.LeftNode = temp;
}
else
{
Insert(node.LeftNode, data);
}
}
else
{
if (node.RightNode == null)
{
TreeNode temp = new TreeNode();
temp.data = data;
node.RightNode = temp;
}
else
{
Insert(node.RightNode, data);
}
}
}
/// <summary>
/// 打印,递归
/// </summary>
/// <param name="node"></param>
private void Print(TreeNode node)
{
if (node == null)
{
return;
}
Console.Write(node.data);
Console.Write(" ");
Print(node.LeftNode);
Print(node.RightNode);
}
}
/// <summary>
/// 树类型的节点
/// </summary>
public class TreeNode
{
public int data; //节点数据
public TreeNode LeftNode; //左子女
public TreeNode RightNode; //右子女
///
/// 构造函数,初始化左右子女为空
///
public TreeNode()
{
LeftNode = RightNode = null;
}
}
}
using System.Collections.Generic;
using System.Text;
namespace BinaryTree
{
/// <summary>
/// 实现基本的数据结构
/// 提供二叉树的基本操作
/// 包括构造一个空树,插入,查找,删除
/// </summary>
public class BinaryTree
{
public TreeNode root; //根节点
bool found = false; //默认查找不存在
/// <summary>
/// 构造函数-构造一个空树
/// </summary>
public BinaryTree()
{
root = null;
}
public TreeNode TreeNode
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
internal TreeGraph TreeGraph
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
/// <summary>
/// 获得树的高度
/// </summary>
/// <returns></returns>
public int Height()
{
if (root == null)
{
return 1;
}
return Math.Max(Height(root.LeftNode), Height(root.RightNode)) + 1;
}
/// <summary>
/// 删除元素
/// </summary>
/// <param name="data">要删除的元素的值</param>
public void Remove(int data)
{
if (root == null)
{
return;
}
if (!Search(data))
{
return;
}
if (root.data == data)
{
TreeNode tmp = Min(root.RightNode);
if (tmp == null)
{
root = root.LeftNode;
}
else
{
root.data = tmp.data;
Remove(root, root.RightNode, 1, tmp.data);
}
}
else if (root.data < data)
{
Remove(root, root.RightNode, 1, data);
}
else
{
Remove(root, root.LeftNode, 0, data);
}
}
/// <summary>
/// 查找是否存在该元素
/// </summary>
/// <param name="data">要查找的元素的值</param>
/// <returns></returns>
public bool Search(int data)
{
if (root == null)
{
return false;
}
bool temp = false;
found = false;
if (root.data == data)
{
temp = true;
}
else
{
temp = Search(root, data);
}
return temp;
}
/// <summary>
/// 插入元素
/// </summary>
/// <param name="data">要插入的元素的值</param>
public void Insert(int data)
{
if (Search(data))
{
return;
}
if (root == null)
{
root = new TreeNode();
root.data = data;
}
else
{
Insert(root, data);
}
}
/// <summary>
/// 打印
/// </summary>
public void Print()
{
if (root == null)
{
Console.WriteLine("Empty");
}
else
{
Print(root);
Console.WriteLine();
}
}
/// <summary>
/// 获得树的高度,递归
/// </summary>
/// <param name="parent"></param>
/// <returns></returns>
private int Height(TreeNode parent)
{
if (parent == null)
{
return 0;
}
return Math.Max(Height(parent.LeftNode), Height(parent.RightNode)) + 1;
}
/// <summary>
/// 获得该节点最小右子女,用于删除元素使用
/// </summary>
/// <param name="parent"></param>
/// <returns></returns>
private TreeNode Min(TreeNode parent)
{
TreeNode temp = parent;
while (temp != null)
{
if (temp.LeftNode == null)
return temp;
else
temp = temp.LeftNode;
}
return null;
}
/// <summary>
/// 删除元素递归
/// </summary>
/// <param name="parent"></param>
/// <param name="cur"></param>
/// <param name="direction"></param>
/// <param name="data"></param>
private void Remove(TreeNode parent, TreeNode cur, int direction, int data)
{
if (cur == null)
{
return;
}
if (cur.data == data)
{
if (cur.LeftNode == null)
{
if (direction == 0)
parent.LeftNode = cur.RightNode;
else
parent.RightNode = cur.RightNode;
}
else if (cur.RightNode == null)
{
if (direction == 0)
parent.LeftNode = cur.LeftNode;
else
parent.RightNode = cur.LeftNode;
}
else
{
TreeNode tmp = Min(cur.RightNode);
cur.data = tmp.data;
Remove(cur, cur.RightNode, 1, tmp.data);
}
}
else if (cur.data > data)
{
Remove(cur, cur.LeftNode, 0, data);
}
else
{
Remove(cur, cur.RightNode, 1, data);
}
}
/// <summary>
/// 查找是否存在该元素,递归
/// </summary>
/// <param name="node"></param>
/// <param name="data"></param>
/// <returns></returns>
private bool Search(TreeNode node, int data)
{
if (node.data == data)
{
found = true;
}
else
{
if (node.data > data)
{
if (node.LeftNode != null)
{
Search(node.LeftNode, data);
}
}
else
{
if (node.RightNode != null)
{
Search(node.RightNode, data);
}
}
}
return found;
}
/// <summary>
/// 插入元素,递归
/// </summary>
/// <param name="node"></param>
/// <param name="data"></param>
private void Insert(TreeNode node, int data)
{
if (node.data > data)
{
if (node.LeftNode == null)
{
TreeNode temp = new TreeNode();
temp.data = data;
node.LeftNode = temp;
}
else
{
Insert(node.LeftNode, data);
}
}
else
{
if (node.RightNode == null)
{
TreeNode temp = new TreeNode();
temp.data = data;
node.RightNode = temp;
}
else
{
Insert(node.RightNode, data);
}
}
}
/// <summary>
/// 打印,递归
/// </summary>
/// <param name="node"></param>
private void Print(TreeNode node)
{
if (node == null)
{
return;
}
Console.Write(node.data);
Console.Write(" ");
Print(node.LeftNode);
Print(node.RightNode);
}
}
/// <summary>
/// 树类型的节点
/// </summary>
public class TreeNode
{
public int data; //节点数据
public TreeNode LeftNode; //左子女
public TreeNode RightNode; //右子女
///
/// 构造函数,初始化左右子女为空
///
public TreeNode()
{
LeftNode = RightNode = null;
}
}
}
TreeGraph.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace BinaryTree
{
/// <summary>
/// 绘图函数
/// 是连接底层数据结构和窗体显示的桥梁
/// </summary>
class TreeGraph
{
/// <summary>
/// 绘图相关变量
/// </summary>
private int distanceHeight; // 两个节点之间的高度差
private int distanceWidth; // 两个节点之间的宽度差
private int nodeRadius; // 节点圆圈的半径
private Point middlePoint; // 绘图的中心点
private Graphics myGraphics;
private Color backColor; // 窗体的背景颜色
private Brush fontBrush; // 字体颜色
private SolidBrush cirBrush; // 圆圈的颜色
private Pen myPen; // 连线的颜色
private Font myFont; // 字体
/// <summary>
/// 数据(树)相关变量
/// </summary>
private BinaryTree myBT = new BinaryTree();
/// <summary>
/// 构造函数
/// </summary>
/// <param name="gc"></param>
public TreeGraph(Graphics gc)
{
/* 初始化绘图相关变量 */
distanceHeight = Setting.distanceHeight;
distanceWidth = Setting.distanceWidth;
nodeRadius = Setting.nodeRadius;
middlePoint = new Point(Setting.middleX, Setting.middleY);
myGraphics = gc;
backColor = Setting.backColor;
cirBrush = Setting.cirBrush;
fontBrush = Setting.fontBrush;
myPen = Setting.myPen;
myFont = Setting.myFont;
/* 初始化树 */
foreach (int i in Setting.initTree)
{
myBT.Insert(i);
}
}
public Form_Tree Form_Tree
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
/// <summary>
/// 增加节点
/// </summary>
/// <param name="data">要增加的节点的值</param>
public void AddNode(int data)
{
myBT.Insert(data);
}
/// <summary>
/// 删除节点
/// </summary>
/// <param name="data">要删除的节点的值</param>
public void DelNode(int data)
{
myBT.Remove(data);
}
/// <summary>
/// 删除整个树
/// </summary>
public void DestoryTree()
{
myBT = new BinaryTree();
}
/// <summary>
/// 设置字体颜色
/// </summary>
/// <param name="color"></param>
public void SetFontColor(Color color)
{
fontBrush = new SolidBrush(color);
}
/// <summary>
/// 设置圆圈颜色
/// </summary>
/// <param name="color"></param>
public void SetLineColor(Color color)
{
myPen.Color = color;
cirBrush.Color = color;
}
/// <summary>
/// 设置背景颜色
/// </summary>
/// <param name="color"></param>
public void SetBackColor(Color color)
{
backColor = color;
}
/// <summary>
/// 绘图
/// </summary>
public void Draw()
{
myGraphics.Clear(backColor);
int high = myBT.Height() * distanceHeight;
Point top = new Point(middlePoint.X, middlePoint.Y - high / 2);
Draw(myBT.root, top, top, myBT.Height()-2);
}
/// <summary>
/// 增加两个节点之间的高度差
/// </summary>
public void IncreaseDisH()
{
int high = (myBT.Height()-1) * distanceHeight;
if (high + nodeRadius > Setting.screenH)
{
return;
}
distanceHeight += Setting.disHChange;
}
/// <summary>
/// 减少两个节点之间的高度差
/// </summary>
public void ReduceDisH()
{
if (distanceHeight <= nodeRadius * 2)
{
return;
}
distanceHeight -= Setting.disHChange;
}
/// <summary>
/// 增加两个节点之间的宽度差
/// </summary>
public void IncreaseDisW()
{
int h = myBT.Height()-1;
int w = distanceWidth;
int r = nodeRadius;
int width = (r + w) * (int)(Math.Pow(2.0, (double)h) - 1);
if (width*2+nodeRadius*2 > Setting.screenW)
{
return;
}
distanceWidth += Setting.disWChange;
}
/// <summary>
/// 减少两个节点之间的宽度差
/// </summary>
public void ReduceDisW()
{
if (distanceWidth <= 0)
{
return;
}
distanceWidth -= Setting.disWChange;
}
/// <summary>
/// 增加节点圆圈的半径
/// </summary>
public void IncreaseRadius()
{
int h = distanceHeight;
int w = distanceWidth + nodeRadius;
if (nodeRadius*2 > h ||
nodeRadius*2 > w ||
nodeRadius * nodeRadius*4 > h*h + w*w)
{
return;
}
h = myBT.Height() - 1;
w = distanceWidth;
int r = nodeRadius;
int width = (r + w) * (int)(Math.Pow(2.0, (double)h) - 1);
if (width * 2 + nodeRadius * 2 > Setting.screenW)
{
return;
}
nodeRadius += Setting.radiusChange;
/* 字体 */
float currentSize = myFont.Size;
currentSize += Setting.fontChange;
myFont = new Font(myFont.Name, currentSize, myFont.Style, myFont.Unit);
myPen.Width += Setting.myPenChange;
}
/// <summary>
/// 减少节点圆圈的半径
/// </summary>
public void ReduceRadius()
{
if (nodeRadius <= Setting.radiusMin)
{
return;
}
nodeRadius -= Setting.radiusChange;
/* 字体 */
float currentSize = myFont.Size;
currentSize -= Setting.fontChange;
myFont = new Font(myFont.Name, currentSize, myFont.Style, myFont.Unit);
myPen.Width -= Setting.myPenChange;
}
/// <summary>
/// 绘制树的图形,递归
/// </summary>
/// <param name="parent">要绘制的节点</param>
/// <param name="cur">要绘制的位置</param>
/// <param name="last">上一次绘制的位置</param>
/// <param name="deep">深度,用以确定位置</param>
private void Draw(TreeNode parent, Point cur, Point last, int deep)
{
if (parent == null)
{
return;
}
/* 画圆圈 */
Size size = new Size(nodeRadius*2, nodeRadius*2);
Point center = new Point();
center.X = cur.X - nodeRadius;
center.Y = cur.Y - nodeRadius;
Rectangle rec = new Rectangle(center, size);
myGraphics.FillEllipse(cirBrush, rec);
/* 画线 */
myGraphics.DrawLine(myPen, cur, last);
/* 绘制左右子树 */
Point left = new Point();
int len = (int)Math.Pow(2.0, (double)deep);
//left.X = cur.X - (distanceWidth + nodeRadius) * deep - distanceWidth;
//left.X = cur.X - (nodeRadius + distanceWidth) * deep;
left.X = cur.X - (nodeRadius + distanceWidth) * len;
left.Y = cur.Y + distanceHeight;
Draw(parent.LeftNode, left, cur, deep-1);
Point right = new Point();
//right.X = cur.X + (distanceWidth + nodeRadius) * deep + distanceWidth;
//right.X = cur.X + (nodeRadius + distanceWidth) * deep;
right.X = cur.X + (nodeRadius + distanceWidth) * len;
right.Y = cur.Y + distanceHeight;
Draw(parent.RightNode, right, cur, deep-1);
/* 写字 */
center.X = cur.X - nodeRadius * 9 / 10;
center.Y = cur.Y - nodeRadius * 9 / 10;
myGraphics.DrawString(parent.data.ToString(), myFont, fontBrush, center);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace BinaryTree
{
/// <summary>
/// 绘图函数
/// 是连接底层数据结构和窗体显示的桥梁
/// </summary>
class TreeGraph
{
/// <summary>
/// 绘图相关变量
/// </summary>
private int distanceHeight; // 两个节点之间的高度差
private int distanceWidth; // 两个节点之间的宽度差
private int nodeRadius; // 节点圆圈的半径
private Point middlePoint; // 绘图的中心点
private Graphics myGraphics;
private Color backColor; // 窗体的背景颜色
private Brush fontBrush; // 字体颜色
private SolidBrush cirBrush; // 圆圈的颜色
private Pen myPen; // 连线的颜色
private Font myFont; // 字体
/// <summary>
/// 数据(树)相关变量
/// </summary>
private BinaryTree myBT = new BinaryTree();
/// <summary>
/// 构造函数
/// </summary>
/// <param name="gc"></param>
public TreeGraph(Graphics gc)
{
/* 初始化绘图相关变量 */
distanceHeight = Setting.distanceHeight;
distanceWidth = Setting.distanceWidth;
nodeRadius = Setting.nodeRadius;
middlePoint = new Point(Setting.middleX, Setting.middleY);
myGraphics = gc;
backColor = Setting.backColor;
cirBrush = Setting.cirBrush;
fontBrush = Setting.fontBrush;
myPen = Setting.myPen;
myFont = Setting.myFont;
/* 初始化树 */
foreach (int i in Setting.initTree)
{
myBT.Insert(i);
}
}
public Form_Tree Form_Tree
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
/// <summary>
/// 增加节点
/// </summary>
/// <param name="data">要增加的节点的值</param>
public void AddNode(int data)
{
myBT.Insert(data);
}
/// <summary>
/// 删除节点
/// </summary>
/// <param name="data">要删除的节点的值</param>
public void DelNode(int data)
{
myBT.Remove(data);
}
/// <summary>
/// 删除整个树
/// </summary>
public void DestoryTree()
{
myBT = new BinaryTree();
}
/// <summary>
/// 设置字体颜色
/// </summary>
/// <param name="color"></param>
public void SetFontColor(Color color)
{
fontBrush = new SolidBrush(color);
}
/// <summary>
/// 设置圆圈颜色
/// </summary>
/// <param name="color"></param>
public void SetLineColor(Color color)
{
myPen.Color = color;
cirBrush.Color = color;
}
/// <summary>
/// 设置背景颜色
/// </summary>
/// <param name="color"></param>
public void SetBackColor(Color color)
{
backColor = color;
}
/// <summary>
/// 绘图
/// </summary>
public void Draw()
{
myGraphics.Clear(backColor);
int high = myBT.Height() * distanceHeight;
Point top = new Point(middlePoint.X, middlePoint.Y - high / 2);
Draw(myBT.root, top, top, myBT.Height()-2);
}
/// <summary>
/// 增加两个节点之间的高度差
/// </summary>
public void IncreaseDisH()
{
int high = (myBT.Height()-1) * distanceHeight;
if (high + nodeRadius > Setting.screenH)
{
return;
}
distanceHeight += Setting.disHChange;
}
/// <summary>
/// 减少两个节点之间的高度差
/// </summary>
public void ReduceDisH()
{
if (distanceHeight <= nodeRadius * 2)
{
return;
}
distanceHeight -= Setting.disHChange;
}
/// <summary>
/// 增加两个节点之间的宽度差
/// </summary>
public void IncreaseDisW()
{
int h = myBT.Height()-1;
int w = distanceWidth;
int r = nodeRadius;
int width = (r + w) * (int)(Math.Pow(2.0, (double)h) - 1);
if (width*2+nodeRadius*2 > Setting.screenW)
{
return;
}
distanceWidth += Setting.disWChange;
}
/// <summary>
/// 减少两个节点之间的宽度差
/// </summary>
public void ReduceDisW()
{
if (distanceWidth <= 0)
{
return;
}
distanceWidth -= Setting.disWChange;
}
/// <summary>
/// 增加节点圆圈的半径
/// </summary>
public void IncreaseRadius()
{
int h = distanceHeight;
int w = distanceWidth + nodeRadius;
if (nodeRadius*2 > h ||
nodeRadius*2 > w ||
nodeRadius * nodeRadius*4 > h*h + w*w)
{
return;
}
h = myBT.Height() - 1;
w = distanceWidth;
int r = nodeRadius;
int width = (r + w) * (int)(Math.Pow(2.0, (double)h) - 1);
if (width * 2 + nodeRadius * 2 > Setting.screenW)
{
return;
}
nodeRadius += Setting.radiusChange;
/* 字体 */
float currentSize = myFont.Size;
currentSize += Setting.fontChange;
myFont = new Font(myFont.Name, currentSize, myFont.Style, myFont.Unit);
myPen.Width += Setting.myPenChange;
}
/// <summary>
/// 减少节点圆圈的半径
/// </summary>
public void ReduceRadius()
{
if (nodeRadius <= Setting.radiusMin)
{
return;
}
nodeRadius -= Setting.radiusChange;
/* 字体 */
float currentSize = myFont.Size;
currentSize -= Setting.fontChange;
myFont = new Font(myFont.Name, currentSize, myFont.Style, myFont.Unit);
myPen.Width -= Setting.myPenChange;
}
/// <summary>
/// 绘制树的图形,递归
/// </summary>
/// <param name="parent">要绘制的节点</param>
/// <param name="cur">要绘制的位置</param>
/// <param name="last">上一次绘制的位置</param>
/// <param name="deep">深度,用以确定位置</param>
private void Draw(TreeNode parent, Point cur, Point last, int deep)
{
if (parent == null)
{
return;
}
/* 画圆圈 */
Size size = new Size(nodeRadius*2, nodeRadius*2);
Point center = new Point();
center.X = cur.X - nodeRadius;
center.Y = cur.Y - nodeRadius;
Rectangle rec = new Rectangle(center, size);
myGraphics.FillEllipse(cirBrush, rec);
/* 画线 */
myGraphics.DrawLine(myPen, cur, last);
/* 绘制左右子树 */
Point left = new Point();
int len = (int)Math.Pow(2.0, (double)deep);
//left.X = cur.X - (distanceWidth + nodeRadius) * deep - distanceWidth;
//left.X = cur.X - (nodeRadius + distanceWidth) * deep;
left.X = cur.X - (nodeRadius + distanceWidth) * len;
left.Y = cur.Y + distanceHeight;
Draw(parent.LeftNode, left, cur, deep-1);
Point right = new Point();
//right.X = cur.X + (distanceWidth + nodeRadius) * deep + distanceWidth;
//right.X = cur.X + (nodeRadius + distanceWidth) * deep;
right.X = cur.X + (nodeRadius + distanceWidth) * len;
right.Y = cur.Y + distanceHeight;
Draw(parent.RightNode, right, cur, deep-1);
/* 写字 */
center.X = cur.X - nodeRadius * 9 / 10;
center.Y = cur.Y - nodeRadius * 9 / 10;
myGraphics.DrawString(parent.data.ToString(), myFont, fontBrush, center);
}
}
}
Form_Tree.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace BinaryTree
{
public partial class Form_Tree : Form
{
TreeGraph myTreeGraph;
public Form_Tree()
{
InitializeComponent();
myTreeGraph = new TreeGraph(this.CreateGraphics());
comboBox_color.SelectedIndex = 0;
}
private void Form_Tree_Shown(object sender, EventArgs e)
{
myTreeGraph.Draw();
}
/** 按钮"上"的事件--增加两个节点之间的高度差 **/
private void btn_DisUp_Click(object sender, EventArgs e)
{
myTreeGraph.IncreaseDisH();
myTreeGraph.Draw();
}
/** 按钮"下"的事件--减少两个节点之间的高度差 **/
private void btn_DisDown_Click(object sender, EventArgs e)
{
myTreeGraph.ReduceDisH();
myTreeGraph.Draw();
}
/** 按钮"左"的事件--减少两个节点之间的宽度差 **/
private void btn_DisLeft_Click(object sender, EventArgs e)
{
myTreeGraph.ReduceDisW();
myTreeGraph.Draw();
}
/** 按钮"右"的事件--增加两个节点之间的宽度差 **/
private void btn_DisRight_Click(object sender, EventArgs e)
{
myTreeGraph.IncreaseDisW();
myTreeGraph.Draw();
}
/** 按钮"+"的事件--增加节点的半径 **/
private void btn_Rincrese_Click(object sender, EventArgs e)
{
myTreeGraph.IncreaseRadius();
myTreeGraph.Draw();
}
/** 按钮"-"的事件--减少节点的半径 **/
private void btn_Rdecrese_Click(object sender, EventArgs e)
{
myTreeGraph.ReduceRadius();
myTreeGraph.Draw();
}
/** 按钮"增加节点"的事件 **/
private void btn_addNode_Click(object sender, EventArgs e)
{
int data = Convert.ToInt32(this.textBox_Key.Text);
myTreeGraph.AddNode(data);
myTreeGraph.Draw();
}
/** 按钮删除节点"的事件 **/
private void btn_delNode_Click(object sender, EventArgs e)
{
int data = Convert.ToInt32(this.textBox_Key.Text);
myTreeGraph.DelNode(data);
myTreeGraph.Draw();
}
/** 按钮"删除树"的事件 **/
private void btn_desTree_Click(object sender, EventArgs e)
{
myTreeGraph.DestoryTree();
myTreeGraph.Draw();
}
/** 设置颜色 **/
private void btn_fontColor_Click(object sender, EventArgs e)
{
colorDialog1.ShowDialog();
Color myColor = colorDialog1.Color;
switch (comboBox_color.SelectedIndex)
{
case 0: // 字体
myTreeGraph.SetFontColor(myColor);
break;
case 1: // 圆圈
myTreeGraph.SetLineColor(myColor);
break;
case 2: // 背景
myTreeGraph.SetBackColor(myColor);
this.BackColor = myColor;
break;
default:
break;
}
myTreeGraph.Draw();
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace BinaryTree
{
public partial class Form_Tree : Form
{
TreeGraph myTreeGraph;
public Form_Tree()
{
InitializeComponent();
myTreeGraph = new TreeGraph(this.CreateGraphics());
comboBox_color.SelectedIndex = 0;
}
private void Form_Tree_Shown(object sender, EventArgs e)
{
myTreeGraph.Draw();
}
/** 按钮"上"的事件--增加两个节点之间的高度差 **/
private void btn_DisUp_Click(object sender, EventArgs e)
{
myTreeGraph.IncreaseDisH();
myTreeGraph.Draw();
}
/** 按钮"下"的事件--减少两个节点之间的高度差 **/
private void btn_DisDown_Click(object sender, EventArgs e)
{
myTreeGraph.ReduceDisH();
myTreeGraph.Draw();
}
/** 按钮"左"的事件--减少两个节点之间的宽度差 **/
private void btn_DisLeft_Click(object sender, EventArgs e)
{
myTreeGraph.ReduceDisW();
myTreeGraph.Draw();
}
/** 按钮"右"的事件--增加两个节点之间的宽度差 **/
private void btn_DisRight_Click(object sender, EventArgs e)
{
myTreeGraph.IncreaseDisW();
myTreeGraph.Draw();
}
/** 按钮"+"的事件--增加节点的半径 **/
private void btn_Rincrese_Click(object sender, EventArgs e)
{
myTreeGraph.IncreaseRadius();
myTreeGraph.Draw();
}
/** 按钮"-"的事件--减少节点的半径 **/
private void btn_Rdecrese_Click(object sender, EventArgs e)
{
myTreeGraph.ReduceRadius();
myTreeGraph.Draw();
}
/** 按钮"增加节点"的事件 **/
private void btn_addNode_Click(object sender, EventArgs e)
{
int data = Convert.ToInt32(this.textBox_Key.Text);
myTreeGraph.AddNode(data);
myTreeGraph.Draw();
}
/** 按钮删除节点"的事件 **/
private void btn_delNode_Click(object sender, EventArgs e)
{
int data = Convert.ToInt32(this.textBox_Key.Text);
myTreeGraph.DelNode(data);
myTreeGraph.Draw();
}
/** 按钮"删除树"的事件 **/
private void btn_desTree_Click(object sender, EventArgs e)
{
myTreeGraph.DestoryTree();
myTreeGraph.Draw();
}
/** 设置颜色 **/
private void btn_fontColor_Click(object sender, EventArgs e)
{
colorDialog1.ShowDialog();
Color myColor = colorDialog1.Color;
switch (comboBox_color.SelectedIndex)
{
case 0: // 字体
myTreeGraph.SetFontColor(myColor);
break;
case 1: // 圆圈
myTreeGraph.SetLineColor(myColor);
break;
case 2: // 背景
myTreeGraph.SetBackColor(myColor);
this.BackColor = myColor;
break;
default:
break;
}
myTreeGraph.Draw();
}
}
}