15,615,774 members
Articles / Multimedia / GDI+
Article
Posted 23 Feb 2012

129.4K views
81 bookmarked

# Graphical BinaryTrees

Rate me:
7 Oct 2018CPOL3 min read
A graphical binary tree. Features: add, remove, or search for a node. Recursive algorithm has been used

## Introduction

This article is about binary trees. A Binary Tree contains unlimited number of nodes, the nodes can be removed, added, searched, etc. Here, we will discuss how to make a binary tree in C# code, and how to draw that on bitmap using GDI+.

Each node on the binary tree has a unique value. for example 776 on the top of the image is a unique value for the root node on the tree.

The rules of adding a new node to the tree are:
Starting from the root node:

1. if the node's value is less than the root's value, it would be added to the left node of root node
2. if the node's value is greater than the root's value, it would be added to the right node of root node

Consider that adding a node to any node would have the same process as 1 and 2.

The rules of removing a node from the binary tree are:

1. the node has no child => simply remove that node
2. the node just has a left child => the left child of the removing node will take its position on the tree
3. the node has right child, and the right child does not have any left child => the right child of the node will take the position of the removing node on the tree
4. the node has right child, and the right child also has left child => the most left child of the right child will be removed (removing this node will cause a recursive algorithm!) and take the position of the removing node

## Using the Code

When the application starts, it randomly adds some nodes to the tree. By pressing the add button (or pressing the enter key on `textbox`), the value of the `textbox` wil be added as a node to the binary tree. By pressing the create button, a new binary tree will be created. By pressing the remove button, the node containing the value of `textbox` will be removed from the tree.

By pressing the "Rnd Add" button, a random value will be added to the tree as a node. By pressing the save button, the current image on the `picturebox` will be saved on the disk.

A complete description of how to use the code and its methods is represented on the main source code as XML parts. To understand it completely, we prefer you read the main source code attached to this article.

It is easy to understand.

To create the tree and paint it, use these lines:

C#
```private BinaryTree tree;
tree = new BinaryTree();
PaintTree();```

To add a node with the unique number of `val`:

C#
`tree.Add(val); `

The `add() `method:

C#
```public void Add(int val)
{
if (val < Value)// add to left
{
if (Left == null)
Left = new Node(val);
else
IsChanged = true;
}
else if (val > Value) // add to right
{
IsChanged = true;
if (Right == null)
Right = new Node(val);
else
}
} ```

To remove a node with the value of `val`:

C#
```tree.Remove(val);
```

The `remove() `method works in the way described before. Removes the node containing the inserted value, also removes its children.

C#
```public bool Remove(int val, out bool containedOnMe)
{
Node nodeToRemove;
containedOnMe = false;
var isLeft = val < Value;
if (val < Value)
nodeToRemove = Left;
else if (val > Value)
nodeToRemove = Right;
else
{
if(Left!=null)
Left.IsChanged = true;
if (Right != null)
Right.IsChanged = true;
containedOnMe = true;
return false;
}

if (nodeToRemove == null)
return false;

bool containOnChild;
var result = nodeToRemove.Remove(val, out containOnChild);
if (containOnChild)
{
IsChanged = true;
if (nodeToRemove.Left == null && nodeToRemove.Right == null)// no child
{
if (isLeft) Left = null; else Right = null;
}
else if (nodeToRemove.Right == null)// left child
{
if (isLeft) Left = nodeToRemove.Left; else Right = nodeToRemove.Left;
}
else // left and right are not null
{
if (nodeToRemove.Right.Left == null)// no left child for right child of node
{
nodeToRemove.Right.Left = nodeToRemove.Left;
if (isLeft)
Left = nodeToRemove.Right;
else
Right = nodeToRemove.Right;
}
else // there is a left child for right child of node
{
Node nLeft = null;
for (var n = nodeToRemove.Right; n != null; n = n.Left)
if (n.Left == null)
nLeft = n;
bool temp;
var v = nLeft.Value;
Remove(nLeft.Value, out temp);
nodeToRemove.Value = v;
}
}
return true;
}
return result;
}```

The paint operation is really easy: each node will draw itself and its child nodes, the method of drawing is recursive calling every child to draw itself, then passing the result to the parent so the parent can draw itself and this process happens for all the nodes.

C#
```/// <summary>
/// paints the node and it's childs
/// </summary>
public Image Draw(out int center)
{
center = _lastCenter;
if (!IsChanged)
return _lastImage;

var lCenter = 0;
var rCenter = 0;

Image lImg = null, rImg = null;
if (Left != null)
lImg = Left.Draw(out lCenter);
if (Right != null)
rImg = Right.Draw(out rCenter);

var me = new Bitmap(40, 40);
var g = Graphics.FromImage(me);
g.SmoothingMode = SmoothingMode.HighQuality;
var rcl = new Rectangle(0, 0, me.Width - 1, me.Height - 1);
g.FillRectangle(Brushes.White, rcl);
g.FillEllipse(new LinearGradientBrush(new Point(0, 0),
new Point(me.Width, me.Height), Color.Gold, Color.Black), rcl);

var lSize = new Size();
var rSize = new Size();
var under = (lImg != null) || (rImg != null);
if (lImg != null)
lSize = lImg.Size;
if (rImg != null)
rSize = rImg.Size;

var maxHeight = lSize.Height;
if (maxHeight < rSize.Height)
maxHeight = rSize.Height;

var resSize = new Size
{
Width = me.Size.Width + lSize.Width + rSize.Width,
Height = me.Size.Height + (under ? maxHeight + me.Size.Height : 0)
};

var result = new Bitmap(resSize.Width, resSize.Height);
g = Graphics.FromImage(result);
g.SmoothingMode = SmoothingMode.HighQuality;
g.FillRectangle(Brushes.White, new Rectangle(new Point(0, 0), resSize));
g.DrawImage(me, lSize.Width, 0);
g.DrawString(Value.ToString(), new Font("Tahoma", 14),
Brushes.White, lSize.Width + 5, me.Height / 2f - 12);

center = lSize.Width + me.Width / 2;
var pen = new Pen(Brushes.Black, 2.5f)
{
EndCap = LineCap.ArrowAnchor,
StartCap = LineCap.Round
};

float x1 = center;
float y1 = me.Height;
float y2 = me.Height * 2;
float x2 = lCenter;
var h = Math.Abs(y2 - y1);
var w = Math.Abs(x2 - x1);
if (lImg != null)
{
g.DrawImage(lImg, 0, me.Size.Height * 2);
var points1 = new List<PointF>
{
new PointF(x1, y1),
new PointF(x1 - w/6, y1 + h/3.5f),
new PointF(x2 + w/6, y2 - h/3.5f),
new PointF(x2, y2),
};
g.DrawCurve(pen, points1.ToArray(), 0.5f);
}
if (rImg != null)
{
g.DrawImage(rImg, lSize.Width + me.Size.Width, me.Size.Height * 2);
x2 = rCenter + lSize.Width + me.Width;
w = Math.Abs(x2 - x1);
var points = new List<PointF>
{
new PointF(x1, y1),
new PointF(x1 + w/6, y1 + h/3.5f),
new PointF(x2 - w/6, y2 - h/3.5f),
new PointF(x2, y2)
};
g.DrawCurve(pen, points.ToArray(), 0.5f);
}
IsChanged = false;
_lastImage = result;
_lastCenter = center;
return result;
}```

Finally the `BinaryTree `class uses the methods and creates an instance of the binary tree.

C#
```class BinaryTree
{
public Node RootNode { get; private set; }

public BinaryTree()//int rootValue)
{
RootNode = new Node(-1);//rootValue);
}

public List<int> Items { get; private set; }

/// <summary>
/// adds an item to tree
/// </summary>
public void Add(int value)
{
}
/// <summary>
/// Removes the node containing the inserted value and also it's childs,
/// returns true if could find and remove the node.
/// return false if the inserted value is on rootNode, or the value does not exist on any of nodes.
/// </summary>
public bool Remove(int value)
{
bool isRootNode;
var res = RootNode.Remove(value, out isRootNode);
return !isRootNode && res;// return false if the inserted value is on rootNode,
// or the value does not exist on any of nodes
}
// draw
public Image Draw()
{
int temp;
return RootNode.Right == null ? null : RootNode.Right.Draw(out temp);
}
} ```

## History

You may find out many samples about binaryTrees! But the way of viewing them visually and on C# code is what we wanted to show.

Written By
Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

## Comments and Discussions

 First PrevNext
 looking for AVL tree GUI project Member 1405202614-Nov-18 10:10 Member 14052026 14-Nov-18 10:10
 Binary trees Member 1301270128-Feb-17 21:49 Member 13012701 28-Feb-17 21:49
 My vote of 5 Gun Gun Febrianza26-Mar-16 15:50 Gun Gun Febrianza 26-Mar-16 15:50
 tutorial for visual Binary search tree Member 1221427917-Dec-15 8:54 Member 12214279 17-Dec-15 8:54
 Newick Format Abolfazl Ghavidel1-Aug-14 18:54 Abolfazl Ghavidel 1-Aug-14 18:54
 Great work THANK YOU BondageMaster28-May-13 4:25 BondageMaster 28-May-13 4:25
 Re: Great work THANK YOU Member 1320730421-May-17 18:03 Member 13207304 21-May-17 18:03
 My vote of 5 losvce13-Oct-12 8:16 losvce 13-Oct-12 8:16
 My vote of 5 Kanasz Robert30-Jul-12 3:28 Kanasz Robert 30-Jul-12 3:28
 Reference to drawing function Matthew So (Hong Kong)22-Apr-12 21:30 Matthew So (Hong Kong) 22-Apr-12 21:30
 Re: Reference to drawing function Mojtaba Hosseini23-Apr-12 17:09 Mojtaba Hosseini 23-Apr-12 17:09
 Re: Reference to drawing function Matthew So (Hong Kong)23-Apr-12 18:21 Matthew So (Hong Kong) 23-Apr-12 18:21
 graphical bst sumkhan16-Apr-12 21:36 sumkhan 16-Apr-12 21:36
 Re: graphical bst Mojtaba Hosseini23-Apr-12 10:19 Mojtaba Hosseini 23-Apr-12 10:19
 Tree traversal (Inorder Preorder Postorder). fyfy_ictm31-Mar-12 16:52 fyfy_ictm 31-Mar-12 16:52
 My vote of 5 RC_Sebastien_C19-Mar-12 16:13 RC_Sebastien_C 19-Mar-12 16:13
 My vote of 5 Anirudha_Gohokar15-Mar-12 3:39 Anirudha_Gohokar 15-Mar-12 3:39
 My vote of 5 Ștefan-Mihai MOGA11-Mar-12 15:46 Ștefan-Mihai MOGA 11-Mar-12 15:46
 Re: My vote of 5 Mojtaba Hosseini13-Mar-12 4:36 Mojtaba Hosseini 13-Mar-12 4:36
 Re: My vote of 5 reggaeguitar12-Feb-15 8:37 reggaeguitar 12-Feb-15 8:37
 Look Great! chenandczh5-Mar-12 13:54 chenandczh 5-Mar-12 13:54
 My vote of 5 SledgeHammer012-Mar-12 10:44 SledgeHammer01 2-Mar-12 10:44
 Binary Search Tree Sunarya29-Feb-12 12:37 Sunarya 29-Feb-12 12:37
 Type-o David Crow27-Feb-12 10:49 David Crow 27-Feb-12 10:49
 Re: Type-o Mojtaba Hosseini1-Mar-12 6:29 Mojtaba Hosseini 1-Mar-12 6:29
 Last Visit: 31-Dec-99 18:00     Last Update: 30-Mar-23 20:51 Refresh 12 Next ᐅ

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.