C# Display a Binary Search Tree in Console - c#

I have simple binary search tree
public class BNode
{
public int item;
public BNode right;
public BNode left;
public BNode(int item)
{
this.item = item;
}
}
public class BTree
{
private BNode _root;
private int _count;
private IComparer<int> _comparer = Comparer<int>.Default;
public BTree()
{
_root = null;
_count = 0;
}
public bool Add(int Item)
{
if (_root == null)
{
_root = new BNode(Item);
_count++;
return true;
}
else
{
return Add_Sub(_root, Item);
}
}
private bool Add_Sub(BNode Node, int Item)
{
if (_comparer.Compare(Node.item, Item) < 0)
{
if (Node.right == null)
{
Node.right = new BNode(Item);
_count++;
return true;
}
else
{
return Add_Sub(Node.right, Item);
}
}
else if (_comparer.Compare(Node.item, Item) > 0)
{
if (Node.left == null)
{
Node.left = new BNode(Item);
_count++;
return true;
}
else
{
return Add_Sub(Node.left, Item);
}
}
else
{
return false;
}
}
public void Print()
{
Print(_root, 4);
}
public void Print(BNode p, int padding)
{
if (p != null)
{
if (p.right != null)
{
Print(p.right, padding + 4);
}
if (padding > 0)
{
Console.Write(" ".PadLeft(padding));
}
if (p.right != null)
{
Console.Write("/\n");
Console.Write(" ".PadLeft(padding));
}
Console.Write(p.item.ToString() + "\n ");
if (p.left != null)
{
Console.Write(" ".PadLeft(padding) + "\\\n");
Print(p.left, padding + 4);
}
}
}
}
where I can insert values like
BTree btr = new BTree();
btr.Add(6);
btr.Add(2);
btr.Add(3);
btr.Add(11);
btr.Add(30);
btr.Add(9);
btr.Add(13);
btr.Add(18);
I want to display my tree within my console application. I have a btr.Print(); which displays my tree from left to right (6 is the root) - but I'm not happy with it.
Question: Is there a better way to display this tree within a console application? Even a improvement of this Print() would help me.

I've ended up with the following method that allows you to print arbitrary subtree:
public static class BTreePrinter
{
class NodeInfo
{
public BNode Node;
public string Text;
public int StartPos;
public int Size { get { return Text.Length; } }
public int EndPos { get { return StartPos + Size; } set { StartPos = value - Size; } }
public NodeInfo Parent, Left, Right;
}
public static void Print(this BNode root, string textFormat = "0", int spacing = 1, int topMargin = 2, int leftMargin = 2)
{
if (root == null) return;
int rootTop = Console.CursorTop + topMargin;
var last = new List<NodeInfo>();
var next = root;
for (int level = 0; next != null; level++)
{
var item = new NodeInfo { Node = next, Text = next.item.ToString(textFormat) };
if (level < last.Count)
{
item.StartPos = last[level].EndPos + spacing;
last[level] = item;
}
else
{
item.StartPos = leftMargin;
last.Add(item);
}
if (level > 0)
{
item.Parent = last[level - 1];
if (next == item.Parent.Node.left)
{
item.Parent.Left = item;
item.EndPos = Math.Max(item.EndPos, item.Parent.StartPos - 1);
}
else
{
item.Parent.Right = item;
item.StartPos = Math.Max(item.StartPos, item.Parent.EndPos + 1);
}
}
next = next.left ?? next.right;
for (; next == null; item = item.Parent)
{
int top = rootTop + 2 * level;
Print(item.Text, top, item.StartPos);
if (item.Left != null)
{
Print("/", top + 1, item.Left.EndPos);
Print("_", top, item.Left.EndPos + 1, item.StartPos);
}
if (item.Right != null)
{
Print("_", top, item.EndPos, item.Right.StartPos - 1);
Print("\\", top + 1, item.Right.StartPos - 1);
}
if (--level < 0) break;
if (item == item.Parent.Left)
{
item.Parent.StartPos = item.EndPos + 1;
next = item.Parent.Node.right;
}
else
{
if (item.Parent.Left == null)
item.Parent.EndPos = item.StartPos - 1;
else
item.Parent.StartPos += (item.StartPos - 1 - item.Parent.EndPos) / 2;
}
}
}
Console.SetCursorPosition(0, rootTop + 2 * last.Count - 1);
}
private static void Print(string s, int top, int left, int right = -1)
{
Console.SetCursorPosition(left, top);
if (right < 0) right = left + s.Length;
while (Console.CursorLeft < right) Console.Write(s);
}
}
As you can see, I've added some parameters that affect the formatting. By default it produces the most compact representation.
In order to play with it, I've modified the BTree class as follows:
public class BTree
{
// ...
public BNode Root { get { return _root; } }
public void Print()
{
Root.Print();
}
}
Using your sample data, here are some results:
btr.Root.Print();
btr.Root.Print(textFormat: "(0)", spacing: 2);
UPDATE: IMO the default format above is compact and readable, but just for fun, adjusted the algorithm to produce more "graphical" output (textFormat and spacing parameters removed):
public static class BTreePrinter
{
class NodeInfo
{
public BNode Node;
public string Text;
public int StartPos;
public int Size { get { return Text.Length; } }
public int EndPos { get { return StartPos + Size; } set { StartPos = value - Size; } }
public NodeInfo Parent, Left, Right;
}
public static void Print(this BNode root, int topMargin = 2, int leftMargin = 2)
{
if (root == null) return;
int rootTop = Console.CursorTop + topMargin;
var last = new List<NodeInfo>();
var next = root;
for (int level = 0; next != null; level++)
{
var item = new NodeInfo { Node = next, Text = next.item.ToString(" 0 ") };
if (level < last.Count)
{
item.StartPos = last[level].EndPos + 1;
last[level] = item;
}
else
{
item.StartPos = leftMargin;
last.Add(item);
}
if (level > 0)
{
item.Parent = last[level - 1];
if (next == item.Parent.Node.left)
{
item.Parent.Left = item;
item.EndPos = Math.Max(item.EndPos, item.Parent.StartPos);
}
else
{
item.Parent.Right = item;
item.StartPos = Math.Max(item.StartPos, item.Parent.EndPos);
}
}
next = next.left ?? next.right;
for (; next == null; item = item.Parent)
{
Print(item, rootTop + 2 * level);
if (--level < 0) break;
if (item == item.Parent.Left)
{
item.Parent.StartPos = item.EndPos;
next = item.Parent.Node.right;
}
else
{
if (item.Parent.Left == null)
item.Parent.EndPos = item.StartPos;
else
item.Parent.StartPos += (item.StartPos - item.Parent.EndPos) / 2;
}
}
}
Console.SetCursorPosition(0, rootTop + 2 * last.Count - 1);
}
private static void Print(NodeInfo item, int top)
{
SwapColors();
Print(item.Text, top, item.StartPos);
SwapColors();
if (item.Left != null)
PrintLink(top + 1, "┌", "┘", item.Left.StartPos + item.Left.Size / 2, item.StartPos);
if (item.Right != null)
PrintLink(top + 1, "└", "┐", item.EndPos - 1, item.Right.StartPos + item.Right.Size / 2);
}
private static void PrintLink(int top, string start, string end, int startPos, int endPos)
{
Print(start, top, startPos);
Print("─", top, startPos + 1, endPos);
Print(end, top, endPos);
}
private static void Print(string s, int top, int left, int right = -1)
{
Console.SetCursorPosition(left, top);
if (right < 0) right = left + s.Length;
while (Console.CursorLeft < right) Console.Write(s);
}
private static void SwapColors()
{
var color = Console.ForegroundColor;
Console.ForegroundColor = Console.BackgroundColor;
Console.BackgroundColor = color;
}
}
and the result is:

This is my take at it:
I've added PrintPretty to BNode, and I've removed the second Print function you had in BTree.
(Edit: I made the tree more lisible by changing the original chars to draw the branches of the tree)
static void Main(string[] args)
{
BTree btr = new BTree();
btr.Add(6);
btr.Add(2);
btr.Add(3);
btr.Add(11);
btr.Add(30);
btr.Add(9);
btr.Add(13);
btr.Add(18);
btr.Print();
}
public class BNode
{
public int item;
public BNode right;
public BNode left;
public BNode(int item)
{
this.item = item;
}
public void PrintPretty(string indent, bool last)
{
Console.Write(indent);
if (last)
{
Console.Write("└─");
indent += " ";
}
else
{
Console.Write("├─");
indent += "| ";
}
Console.WriteLine(item);
var children = new List<BNode>();
if (this.left != null)
children.Add(this.left);
if (this.right != null)
children.Add(this.right);
for (int i = 0; i < children.Count; i++)
children[i].PrintPretty(indent, i == children.Count - 1);
}
}
public class BTree
{
private BNode _root;
private int _count;
private IComparer<int> _comparer = Comparer<int>.Default;
public BTree()
{
_root = null;
_count = 0;
}
public bool Add(int Item)
{
if (_root == null)
{
_root = new BNode(Item);
_count++;
return true;
}
else
{
return Add_Sub(_root, Item);
}
}
private bool Add_Sub(BNode Node, int Item)
{
if (_comparer.Compare(Node.item, Item) < 0)
{
if (Node.right == null)
{
Node.right = new BNode(Item);
_count++;
return true;
}
else
{
return Add_Sub(Node.right, Item);
}
}
else if (_comparer.Compare(Node.item, Item) > 0)
{
if (Node.left == null)
{
Node.left = new BNode(Item);
_count++;
return true;
}
else
{
return Add_Sub(Node.left, Item);
}
}
else
{
return false;
}
}
public void Print()
{
_root.PrintPretty("", true);
}
}
This is the result (more compact, as I mentioned):
Edit: the following code has been modified in order to show the info about left-right:
static void Main(string[] args)
{
BTree btr = new BTree();
btr.Add(6);
btr.Add(2);
btr.Add(3);
btr.Add(11);
btr.Add(30);
btr.Add(9);
btr.Add(13);
btr.Add(18);
btr.Print();
}
public enum NodePosition
{
left,
right,
center
}
public class BNode
{
public int item;
public BNode right;
public BNode left;
public BNode(int item)
{
this.item = item;
}
private void PrintValue(string value, NodePosition nodePostion)
{
switch (nodePostion)
{
case NodePosition.left:
PrintLeftValue(value);
break;
case NodePosition.right:
PrintRightValue(value);
break;
case NodePosition.center:
Console.WriteLine(value);
break;
default:
throw new NotImplementedException();
}
}
private void PrintLeftValue(string value)
{
Console.ForegroundColor = ConsoleColor.Magenta;
Console.Write("L:");
Console.ForegroundColor = (value == "-") ? ConsoleColor.Red : ConsoleColor.Gray;
Console.WriteLine(value);
Console.ForegroundColor = ConsoleColor.Gray;
}
private void PrintRightValue(string value)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("R:");
Console.ForegroundColor = (value == "-") ? ConsoleColor.Red : ConsoleColor.Gray;
Console.WriteLine(value);
Console.ForegroundColor = ConsoleColor.Gray;
}
public void PrintPretty(string indent, NodePosition nodePosition, bool last, bool empty)
{
Console.Write(indent);
if (last)
{
Console.Write("└─");
indent += " ";
}
else
{
Console.Write("├─");
indent += "| ";
}
var stringValue = empty ? "-" : item.ToString();
PrintValue(stringValue, nodePosition);
if(!empty && (this.left != null || this.right != null))
{
if (this.left != null)
this.left.PrintPretty(indent, NodePosition.left, false, false);
else
PrintPretty(indent, NodePosition.left, false, true);
if (this.right != null)
this.right.PrintPretty(indent, NodePosition.right, true, false);
else
PrintPretty(indent, NodePosition.right, true, true);
}
}
}
public class BTree
{
private BNode _root;
private int _count;
private IComparer<int> _comparer = Comparer<int>.Default;
public BTree()
{
_root = null;
_count = 0;
}
public bool Add(int Item)
{
if (_root == null)
{
_root = new BNode(Item);
_count++;
return true;
}
else
{
return Add_Sub(_root, Item);
}
}
private bool Add_Sub(BNode Node, int Item)
{
if (_comparer.Compare(Node.item, Item) < 0)
{
if (Node.right == null)
{
Node.right = new BNode(Item);
_count++;
return true;
}
else
{
return Add_Sub(Node.right, Item);
}
}
else if (_comparer.Compare(Node.item, Item) > 0)
{
if (Node.left == null)
{
Node.left = new BNode(Item);
_count++;
return true;
}
else
{
return Add_Sub(Node.left, Item);
}
}
else
{
return false;
}
}
public void Print()
{
_root.PrintPretty("", NodePosition.center, true, false);
}
}
The result:

If your tree is in the form of a QuickGraph IBidirectionalGraph, you could print it recursively like this:
static void PrintVertex<TVertex>(IBidirectionalGraph<TVertex, IEdge<TVertex>> graph, TVertex vertex, Func<TVertex, string> labelSelector, bool[] isLastVertexIntendations = null)
{
var prefix = string.Concat(Enumerable.Concat(
/*up to last*/isLastVertexIntendations.NeverNull().Reverse().Skip(1).Reverse().Select(isLast => isLast ? " " : "│ "),
/*last*/isLastVertexIntendations.NeverNull().Reverse().Take(1).Select(isLast => isLast ? "└─" : "├─")
));
Console.Write(prefix);
Console.WriteLine(labelSelector(vertex));
var edges = graph.OutEdges(vertex);
foreach (var edge in edges)
{
PrintVertex(graph, edge.Target, labelSelector, isLastVertexIntendations: isLastVertexIntendations.NeverNull().Concat(new[] { edge == edges.Last() }).ToArray());
}
}

Related

Creating A Linked List. C#

I've tried creating linked list/node classes and I'm not sure where to go next. My attempts haven't went well because after creating the classes I'm just not sure what the next step is.
I'm trying to create a program that has a dinosaur node which saves information about the dinosaur such as id, species etc and I want to allow the user to create and remove dinosaurs from the list. So I need to allow the user to input data, I assume there's a way to make dino id get set automatically but I'm not to sure.
I've included the LinkedList.cs and the Node.cs so you can see where I'm going but I have no idea what to do within my program class to utilise the linked list and achieve what I'm trying to do.
Added Program.cs class incase that helps identify/show where I am within the program/what I need to do.
Linked List Class:
using System;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using System.Text;
namespace JurrasicFinal
{
public class LinkedList
{
private Node head;
private int count;
public LinkedList()
{
this.head = null;
this.count = 0;
}
public bool Empty
{
get { return this.count == 0; }
}
public int Count
{
get { return this.count; }
}
public object this[int index]
{
get { return this.Get(index); }
}
public object Add(int index, object o)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (index > count)
index = count;
Node current = this.head;
if (this.Empty || index == 0)
{
this.head = new Node(o, this.head);
}
else
{
for (int i = 0; i < index - 1; i++)
{
current = current.Next;
current.Next = new Node(o, current.Next);
}
}
count++;
return o;
}
public object Add(object o)
{
return this.Add(count, o);
}
public object Remove(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return null;
if (index >= this.count)
index = count - 1;
Node current = this.head;
object result = null;
if (index == 0)
{
result = current.Data;
this.head = current.Next;
}
else
{
for (int i = 0; index < index - 1; i++) ;
current = current.Next;
result = current.Next.Data;
current.Next = current.Next.Next;
}
count--;
return result;
}
public void Clear()
{
this.head = null;
this.count = 0;
}
public int IndexOf(object o)
{
Node current = this.head;
for (int i = 0; i < this.count; i++)
{
if (current.Data.Equals(o))
return i;
current = current.Next;
}
return -1;
}
public bool Contains(object o)
{
return this.IndexOf(o) >= 0;
}
public object Get(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return null;
if (index >= this.count)
index = this.count - 1;
Node current = this.head;
for (int i = 0; i < index; i++)
current = current.Next;
return current.Data;
}
}
}
Node Class:
using System;
using System.Collections.Generic;
using System.Text;
namespace JurrasicFinal
{
public class Node
{
private object data;
private Node next;
private string DinoSpecies;
private string DinoName;
public Node(object data, Node next)
{
this.data = data;
this.next = next;
}
public object Data
{
get { return this.data; }
set { this.data = value; }
}
public Node Next
{
get { return this.next; }
set { this.next = value; }
}
}
}
Program Class:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq.Expressions;
namespace JurrasicFinal
{
class Program
{
class Dinosaur
{
public string Name;
public string Classification;
public char Sex;
}
static void Main(string[] args)
{
LinkedList<Dinosaur> DinoList = new LinkedList<Dinosaur>();
Dinosaur Dino1 = new Dinosaur();
Dino1.Name = "Tyrannosaurus Rex";
Dino1.Classification = "Carnivorous";
Dino1.Sex = 'M';
Dinosaur Dino2 = new Dinosaur();
Dino2.Name = "Velociraptor";
Dino2.Classification = "Carnivorous";
Dino2.Sex = 'F';
Dinosaur Dino3 = new Dinosaur();
Dino3.Name = "Procompsognathus";
Dino3.Classification = "Carnivorous";
Dino3.Sex = 'M';
void printList()
{
Console.WriteLine("Current Queue: ");
Console.WriteLine("\n");
foreach (Dinosaur d in DinoList)
{
Console.WriteLine("Name: " + d.Name);
Console.WriteLine("Classification: " + d.Classification);
Console.WriteLine("Sex " + d.Sex);
Console.WriteLine("\n");
}
Console.WriteLine(Dino1.Name + Dino1.Sex);
}
DinoList.AddLast(Dino1);
DinoList.AddLast(Dino2);
DinoList.AddLast(Dino3);
printList();
Console.WriteLine(DinoList.Count);
FileStream fileStream = File.OpenWrite("E:/Work/Dinosaur.txt");
BinaryWriter writer = new BinaryWriter(fileStream);
foreach (Dinosaur d in DinoList)
{
writer.Write(d.Name);
writer.Write(d.Classification);
writer.Write(d.Sex);
}
writer.Close();
Console.WriteLine("Reading Back From File");
FileStream file = File.OpenRead("E:/Work/Dinosaur.txt");
BinaryReader reader = new BinaryReader(file);
for (int i = 1; i < 3; i++)
{
Dinosaur d = new Dinosaur();
d.Name = reader.ReadString();
d.Classification = reader.ReadString();
d.Sex = reader.ReadChar();
DinoList.AddLast(d);
}
reader.Close();
Console.ReadKey();
}
}
}
I think you might be looking for something like this, which hangs on user input and tries to do simple validation. I made it a bit overly complex to demonstrate some options.
class Sample
{
private static int index = 0;
static void Main(string[] args)
{
LinkedList<Dinosaur> DinoList = new LinkedList<Dinosaur>();
while (true)
{
var dino = new Dinosaur();
dino.Name = GetInput("Enter dino name (q to quit): ");
if (dino.Name == "q" || dino.Name == "Q")
{
break;
}
dino.Classification = GetInput("Enter dino classification: ");
char[] sexes = new char[] {'F', 'f', 'M', 'm'};
while (true)
{
Console.WriteLine("Enter dino sex (M/F): ");
dino.Sex = (char) Console.Read();
if (sexes.Contains(dino.Sex))
{
break;
}
}
int inputIndex = default;
while (true)
{
var indexString = GetInput($"Enter 0-index list position (max {DinoList.Count})");
inputIndex = Convert.ToInt32(indexString);
if (inputIndex <= DinoList.Count)
{
break;
}
}
DinoList.Add(inputIndex, dino);
index++;
Console.WriteLine("Dinosaurs:");
Console.WriteLine(new string('-', 30));
for (var i = 0; i < DinoList.Count; i++)
{
var dinosaur = (Dinosaur) DinoList.Get(i);
Console.WriteLine("Name: " + dinosaur.Name);
Console.WriteLine("Classification: " + dinosaur.Classification);
Console.WriteLine("Sex: " + dinosaur.Sex);
}
}
}
private static string GetInput(string prompt)
{
Console.WriteLine(prompt);
var input = Console.ReadLine();
while (string.IsNullOrWhiteSpace(input))
{
input = Console.ReadLine();
}
return input;
}
}
Note that you have to make your LinkedList and Node into LinkedList<T> and Node<T> but they converted directly, so it's just a bit of typing.
Hope it helps!
Edit: Add classes provided in question, modified to be generic.
public class Node<T>
{
private object data;
private Node<T> next;
private string DinoSpecies;
private string DinoName;
public Node(object data, Node<T> next)
{
this.data = data;
this.next = next;
}
public object Data
{
get { return this.data; }
set { this.data = value; }
}
public Node<T> Next
{
get { return this.next; }
set { this.next = value; }
}
}
public class LinkedList<T>
{
private Node<T> head;
private int count;
public LinkedList()
{
this.head = null;
this.count = 0;
}
public bool Empty
{
get { return this.count == 0; }
}
public int Count
{
get { return this.count; }
}
public object this[int index]
{
get { return this.Get(index); }
}
public object Add(int index, object o)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (index > count)
index = count;
Node<T> current = this.head;
if (this.Empty || index == 0)
{
this.head = new Node<T>(o, this.head);
}
else
{
for (int i = 0; i < index - 1; i++)
{
current = current.Next;
current.Next = new Node<T>(o, current.Next);
}
}
count++;
return o;
}
public object Add(object o)
{
return this.Add(count, o);
}
public object Remove(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return null;
if (index >= this.count)
index = count - 1;
Node<T> current = this.head;
object result = null;
if (index == 0)
{
result = current.Data;
this.head = current.Next;
}
else
{
for (int i = 0; index < index - 1; i++) ;
current = current.Next;
result = current.Next.Data;
current.Next = current.Next.Next;
}
count--;
return result;
}
public void Clear()
{
this.head = null;
this.count = 0;
}
public int IndexOf(object o)
{
Node<T> current = this.head;
for (int i = 0; i < this.count; i++)
{
if (current.Data.Equals(o))
return i;
current = current.Next;
}
return -1;
}
public bool Contains(object o)
{
return this.IndexOf(o) >= 0;
}
public object Get(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return null;
if (index >= this.count)
index = this.count - 1;
Node<T> current = this.head;
for (int i = 0; i < index; i++)
current = current.Next;
return current.Data;
}
}

How to connect leafs and returning a List for nodes around the BST

This is my implementation for BST (Binary Search Tree). Can Anyone help me to create two methods, one to Connect Leafs and one to return a List of Nodes around the Tree, for example: Connecting Leaf Example In this picture it shows how the leafs should be connected, Nodes that should be stored in List and the way the nodes stored in List need to be in this way where the root is the first element and going to the left passing down to leafs going back to root from the right. In my example it should be 8(root), 3, 1, 4, 7, 13, 14, 10, 8(root).
Thank You!
**class Node
{
private int VL;
private int Niv;
public Node Parent, LC, RC;
public Node()
{
this.Parent = this.LC = this.RC = null;
this.Niv = -1;
}
public Node(int x)
{
this.VL = x;
this.Parent = this.LC = this.RC = null;
this.Niv = -1;
}
public int Vlera
{
get { return this.VL; }
set { this.VL = value; }
}
public int Niveli
{
get { return this.Niv; }
set { this.Niv = value; }
}
}
class BSTree
{
public Node Root;
private int MaxNiv;
public BSTree()
{
this.Root = null;
this.MaxNiv = -1;
}
public void Insert(int x)
{
Node tmp = new Node(x);
if (this.Root == null)
{
tmp.Niveli = 0;
this.Root = tmp;
}
else InsertNode(tmp);
if (tmp.Niveli > this.MaxNiv) MaxNiv = tmp.Niveli;
}
public void ConnectLeafs()
{
//TODO
}
public List<T> ReturnNodesAroundTheTree()
{
//TODO
}
public Node GoTo_Node(Node nd)
{
return GoTo_Node_Rec(this.Root, nd);
}
public Node GoTo_Node(int x)
{
return GoTo_Node_Rec(this.Root, x);
}
private Node GoTo_Node_Rec(Node root, Node nd)
{
if (root.Vlera == nd.Vlera) return root;
if (root.Vlera > nd.Vlera) return GoTo_Node_Rec(root.LC, nd);
else return GoTo_Node_Rec(root.RC, nd);
}
private Node GoTo_Node_Rec(Node root, int x)
{
if (root.Vlera == x) return root;
if (root.Vlera > x) return GoTo_Node_Rec(root.LC, x);
else return GoTo_Node_Rec(root.RC, x);
}
private void InsertNode(Node nd)
{
Node tmp = InsertRecNode(this.Root, nd.Vlera);
if (nd.Vlera >= tmp.Vlera) tmp.RC = nd;
else tmp.LC = nd;
nd.Parent = tmp;
nd.Niveli = nd.Parent.Niveli++;
//if (nd.Niveli > this.MaxNiv) MaxNiv = nd.Niveli;
}
private Node InsertRecNode(Node root, int x)
{
if (x >= root.Vlera)
if (root.RC != null) return InsertRecNode(root.RC, x);
else return root;
else
if (root.LC != null) return InsertRecNode(root.LC, x);
else return root;
}
private bool IsRoot(Node nd)
{
if (nd.Parent == null) return true;
return false;
}
private bool IsLeaf(Node nd)
{
if (nd.LC == null && nd.RC == null) return true;
return false;
}**
Here is the easy way to do this. I created a List of all the node. When you create a new node add node to list. See code below
class BSTree
{
public Node Root;
private int MaxNiv;
private List<Node> nodes = new List<Node>();
public BSTree()
{
this.Root = null;
this.MaxNiv = -1;
}
public void Insert(int x)
{
Node tmp = new Node(x);
nodes.Add(tmp);
if (this.Root == null)
{
tmp.Niveli = 0;
this.Root = tmp;
}
else InsertNode(tmp);
if (tmp.Niveli > this.MaxNiv) MaxNiv = tmp.Niveli;
}
public void ConnectLeafs()
{
//TODO
}
public List<Node> ReturnNodesAroundTheTree()
{
return nodes.Where(x => IsLeaf(x)).ToList();
}
}

Hash table conversion

I have uncommon question/request. I am learning about hash tables and have a hash table with open addressing when using the square hash function, and I'm trying to figure out how could I transform it to hash table with list? Is it possible to do from the code provided? Sorry if the question is too broad or unclear, trying to learn:
`
class HMap<K, V>
{
public static int DEFAULT_INITIAL_CAPACITY = 16;
public static float DEFAULT_LOAD_FACTOR = 0.75f;
Entry<K, V>[] table;
protected int size = 0;
protected float loadFactor;
protected int rehashesCounter = 0;
protected int index;
public HMap()
{
loadFactor = DEFAULT_LOAD_FACTOR;
this.table = new Entry<K, V>[DEFAULT_INITIAL_CAPACITY];
}
public HMap(int initialCapacity)
{
loadFactor = 0.75F;
this.table = new Entry<K, V>[initialCapacity];
}
public Boolean IsEmpty()
{
return size == 0;
}
public int Size()
{
return size;
}
public void Clear()
{
for(int i = 0; i < table.Length; i++)
{
table[i] = null;
}
size = 0;
rehashesCounter = 0;
}
public V Put(K key, V value)
{
if (key == null || value == null)
{
throw new Exception("Key or value is null in put(Key key, Value value)");
}
index = FindPosition(key);
if (index == -1)
{
return default(V);
}
table[index] = new Entry<K, V>(key, value);
size++;
if (size > table.Length * loadFactor)
{
Rehash(table[index]);
}
return value;
}
public V Get(K key)
{
if (key == null)
{
throw new Exception("Key is null in get(Key key)");
}
index = FindPosition(key);
return (table[index] != null) ? table[index].value : default(V);
}
public Boolean Contains(K key)
{
return Get(key) != null;
}
public Boolean ContainsValue(V value)
{
foreach (Entry<K, V> e in table)
{
if (e != null)
{
if (e.value.Equals(value))
{
return true;
}
}
}
return false;
}
private void Rehash(Entry<K, V> entry)
{
HMap<K, V> map = new HMap<K, V>(table.Length * 2);
for (int i = 0; i < table.Length; i++)
{
if (table[i] != null)
{
map.Put(table[i].key, table[i].value);
}
}
table = map.table;
rehashesCounter++;
}
private int Hash(K key)
{
int h = key.GetHashCode();
return Math.Abs(h) % table.Length;
}
private int FindPosition(K key)
{
index = Hash(key);
int indexO = index;
int i = 0;
for (int j = 0; j < table.Length; j++)
{
if (table[index] == null || table[index].key.Equals(key))
{
return index;
}
i++;
index = (indexO + i * Hash2(key)) % table.Length;
}
return -1;
}
private int Hash2(K key)
{
return 7 - (Math.Abs(key.GetHashCode()) % 7);
}
public override String ToString()
{
StringBuilder result = new StringBuilder();
foreach (Entry<K, V> entry in table)
{
if (entry == null)
{
result.Append("null").Append("\n");
}
else
{
result.Append(entry.toString()).Append("\n");
}
}
return result.ToString();
}
public void ToFile(string fileName)
{
using(StreamWriter file = new StreamWriter(#fileName))
{
foreach (Entry<K, V> entry in table)
{
if (entry == null)
{
file.WriteLine("null");
}
else
{
file.WriteLine(entry.toString());
}
}
}
}
class Entry<Key, Value>
{
public Key key;
public Value value;
public Entry(Key key, Value value)
{
this.key = key;
this.value = value;
}
public String toString()
{
return key + "=" + value;
}
}
}
`

how to delete first IntNode

class IntNode
{
public int value { get; set; }
public IntNode next { get; set; }
public IntNode(int value)
{
this.value = value;
this.next = null;
}
public IntNode(int value, IntNode next)
{
this.value = value;
this.next = next;
}
public bool HasNext()
{
return (next != null);
}
public override string ToString()
{
if (this.HasNext())
return value + "-->" + next;
else
return value + "";
}
}
so if I wanted to remove the 4th node with given list starts with head:
IntNode pos = head.next;
IntNode prev = head;
int counter = 0;
while (pos != null)
{
if (counter == 4) prev.next = pos.next;
prev = pos;
pos = pos.next;
}
But I want to remove the first node (when counter is 0). How can I do this? Thanks.
Something like this should do it for you:
while (pos != null)
{
if ( counter == 0 )
{
head = head.next;
prev = head;
}
else
{
prev.next = pos.next;
}
}
public void Remove(int index) {
if(head != null)
{
if(index == 0)
{
head = head.next;
}
else
{
IntNode pos = head.next;
IntNode prev = head;
while (pos != null)
{
--index;
if (index == 0)
{
prev.next = pos.next;
break;
}
prev = pos;
pos = pos.next;
}
}
}
}

Queue in generic linked list

I'm new at this and trying to write this code for a queue but it doesn't work. I'm stuck, I wrote queue for a linked list and I can't find where I'm wrong here, any help is great. Thank you in advance.
class Queue
{
public Node<T> head { get; set; }
public Node<T> tail { get; set; }
public int size { get; set; }
public Queue()
{
head = null;
tail = null;
}
public void Enqueue(T value)
{
if (head == null)
{
head = new Node<T>(value);
tail = head;
}
else
{
tail.sljedeci = new Node<T>(value);
tail = tail.next;
}
size++;
}
public T Dequeue()
{
if (size == 0)
{
throw new IndexOutOfRangeException();
}
else if (size == 1)
{
T value = head.value;
size--;
head = tail = null;
return value;
}
else
{
T value = head.value;
head = head.next;
size--;
return value;
}
}
public void Peek()
{
if (size == 0)
{
Console.WriteLine("List is empty");
}
else
{
Node<T> temp = head;
Console.Write("{ ");
while (temp.next != null)
{
Console.Write("{0}, ", temp.value);
temp = temp.next;
}
Console.Write(temp.valuet + " }");
}
}

Categories

Resources