I tried displaying the nodes in my BST but they were not displaying, so i tried to check if they even were added in the BST in the first place by
using System;
namespace Binary_Search_Tree
{
class Program
{
static void Main(string[] args)
{
BinarySearchTree bst = new BinarySearchTree(7);
bst.Add(new int[] { 4, 15, 2, 6, 14, 16, 10 });
//bst.preOrderTraversal(bst.root);
Console.Write(bst.root.left.right);
}
}
}
but this is the error i got :
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
at Binary_Search_Tree.Program.Main(String[] args)
The nodes are not getting added in the Binary Search Tree.
this is the Binary Search Tree Class :
using System;
namespace Binary_Search_Tree
{
public class BinarySearchTree
{
public Node root { get; set; }
Node currentNode;
public BinarySearchTree(int data)
{
root = new Node(data);
currentNode = root;
}
public void Add(int data)
{
Node newNode = new Node(data);
currentNode = root;
while (currentNode != null)
{
if (newNode.data <= currentNode.data)
{
currentNode = currentNode.left;
}
else
{
currentNode = currentNode.right;
}
}
currentNode = newNode;
}
public void Add(int[] array)
{
for (int i = 0; i < array.Length; i++)
{
Add(array[i]);
}
}
public void preOrderTraversal(Node node)
{
if (node != null)
{
Console.Write(node.data + " ");
preOrderTraversal(node.left);
preOrderTraversal(node.right);
}
}
}
}
Edit:
Node Class :
namespace Binary_Search_Tree
{
public class Node
{
public int data { get; set; }
public Node left { get; set; }
public Node right { get; set; }
public Node(int data)
{
this.data = data;
left = null;
right = null;
}
}
}
Can you guys please tell what the problem is?
To start, there's some issues with your add node method. Also, consider having your console output its own method. Take a look at my pre-order traversal example here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BST
{
public class BinarySearchTree
{
public Node root;
public class Node //create a node class within our BinarySearchTree class
{
public int NodeData;
public Node Left;
public Node Right;
public void WriteNode(int i) //writes our current node value to the console
{
NodeData = i;
Console.Write(NodeData + "," + " ");
}
}
public BinarySearchTree() //BinarySearchTree construct
{
root = null; //assigns the root node within the construct of the BinarySearchTree class
}
public void Insert(int i)
{
Node newNode = new Node
{
NodeData = i
};
if (root == null) //begin tree traversal starting at root. Since its pre-order traversal, the order is root->left->right
{
root = newNode;
newNode.WriteNode(i);
}
else //root has a value, so begin traversing to find the next available node
{
Node current = root;
Node parent;
while(true)
{
parent = current;
if (i < current.NodeData) //traverse down the left side of the tree
{
current = current.Left;
if (current == null)
{
parent.Left = newNode;
newNode.WriteNode(i);
break;
}
else //left node has a value, lets traverse right
{
current = current.Right;
if (current == null)
{
parent.Right = newNode;
newNode.WriteNode(i);
break;
}
}
}
else if (i > current.NodeData) //current node value cannot be assigned to a left child node if its value is > than its parent or root node. Traverse right
{
current = current.Right;
if (current == null)
{
parent.Right = newNode;
newNode.WriteNode(i);
break;
}
}
}
}
}
static void Main(string[] args)
{
BinarySearchTree BSTnums = new BinarySearchTree();
int[] Numbers = { 45, 10, 32, 26, 8, 54, 32, 19, 12, 15, 18, 11, 35, 46 }; //Numbers array to build tree
int numLength = Numbers.Length;
for (int x = 0; x < numLength; x++) //iterates the length of the unsorted array, generates Binary Search Tree based on [] Numbers array.
{
BSTnums.Insert(Numbers[x]);
}
Console.Read();
}
}
}
The Add node is wrong. I'm not going to fix all the issues but the code should look something like below. The code below is not tested and just meant to show where the issue is located.
public void Add(int data)
{
Node newNode = new Node(data);
currentNode = root;
while (currentNode != null)
{
if (newNode.data <= currentNode.data)
{
currentNode.left = newNode;
}
else
{
currentNode.right = currentNode;
}
}
currentNode = newNode;
}
changed the Add function a bit and now its working, i still don't understand what the problem was in the first place
public void Add(int data)
{
Node newNode = new Node(data);
currentNode = root;
while (currentNode != null)
{
if (newNode.data <= currentNode.data)
{
if (currentNode.left == null)
{
currentNode.left = newNode;
return;
}
else
{
currentNode = currentNode.left;
}
}
else
{
if (currentNode.right == null)
{
currentNode.right = newNode;
return;
}
else
{
currentNode = currentNode.right;
}
}
}
Related
I am looking to create a depth tree where each number is connected to two numbers on its left and right on the row below it.
Likewise, each number will be linked to the two numbers on its left and right on the row above it, or just one if it is at an end of its row.
Then I have to calculate the largest sum from top to bottom.
The numbers need to be added dynamically (by a text file) so I cannot add them individually. The format of the text file will look like the image below, taking carriage returns and spaces into consideration. The tree needs to look like this:
I tried to do this a few different ways but I cannot seem to find the best way to do it. I tried 2 dimensional arrays and node trees but I am not proficient enough to do them. Below is a snippet of my Node Tree code that I tried. Please let me know if I need to do anything else here.
public class Node
{
public int value;
public Node left;
public Node right;
public Node parent;
public Node(int value)
{
this.value = value;
}
}
public static Node NewNode(int value)
{
Node node = new Node(value);
node.left = null;
node.right = null;
node.parent = null;
return node;
}
public static void Insert(Node root, Node newNode)
{
if (root == null)
{
root = newNode;
}
else
{
if (root.left == null)
{
root.left = newNode;
newNode.parent = root;
}
else if(root.right == null)
{
root.right = newNode;
newNode.parent = root;
}
else
{
if (root.left.left == null)
{
Insert(root.left, newNode);
}
else
{
Insert(root.right, newNode);
}
}
}
}
public static Node GetTree(string filePath)
{
Node rootNode = null;
string[] lines = File.ReadAllLines(filePath);
if (lines.Length == 0) return null;
foreach (string line in lines)
{
if (string.IsNullOrWhiteSpace(line)) return null;
string[] values = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (values.Length == 0) return null;
foreach (string value in values)
{
int number;
if (!int.TryParse(value, out number)) return null;
}
if (rootNode == null)
{
rootNode = NewNode(int.Parse(values[0]));
}
else
{
Node node = rootNode;
foreach (string value in values)
{
Node newNode = NewNode(int.Parse(value));
Insert(node, newNode);
node = newNode;
}
}
}
return rootNode;
}
Edit: The text file will look similar to this, expecting to have spaces and carriage returns:
3
7 6
2 4 9
1 4 8 2
Structure of Graph.txt (Number of node, Weight of node, left number node, right number node):
(1,3,2,3)
(2,7,4,5)
(3,6,5,6)
(4,2,7,8)
(5,4,8,9)
(6,9,9,10)
(7,1,,)
(8,4,,)
(9,8,,)
(10,2,,)
Code:
public class Node
{
public int Id { get; set; }
public int Weight { get; set; }
public string LeftId { get; set; }
public string RightId { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
var graphDefinition = File.ReadAllText("Graph.txt");
var regex = new Regex(#"\((?<Id>\d*),(?<Weight>\d*),(?<Left>\d*),(?<Right>\d*)\)");
var nodes = new List<Node>();
foreach (Match match in regex.Matches(graphDefinition))
{
nodes.Add(new Node
{
Id = int.Parse(match.Groups["Id"].Value),
Weight = int.Parse(match.Groups["Weight"].Value),
LeftId = match.Groups["Left"].Value,
RightId = match.Groups["Right"].Value
});
}
if (!nodes.Any())
return;
foreach (var node in nodes)
{
if (!string.IsNullOrEmpty(node.LeftId))
node.Left = nodes.FirstOrDefault(p => p.Id == int.Parse(node.LeftId));
if (!string.IsNullOrEmpty(node.RightId))
node.Right = nodes.FirstOrDefault(p => p.Id == int.Parse(node.RightId));
}
var root = nodes.First();
Depth(root, 0);
Console.WriteLine($"result calculation: {CalculatedMax}");
}
private static int CalculatedMax = int.MinValue;
private static void Depth(Node node, int currentSum)
{
if (node.Left == null && node.Right == null)
{
CalculatedMax = Math.Max(CalculatedMax, currentSum + node.Weight);
return;
}
Depth(node.Left, currentSum + node.Weight);
Depth(node.Right, currentSum + node.Weight);
}
}
Use table for input. Minus 1 is a node with no child. The table could be rows in a csv file.
After some thinking I realize you can build the tree from an array of numbers. You first create all the nodes in a list NODES with the values. Then you link the list into the binary tree.
class Program
{
static void Main(string[] args)
{
int[] data = { 3, 7, 6, 2, 4, 9, 1, 4, 8, 2 };
Node root = Node.BuildTree(data);
}
}
public class Node
{
int value { get; set; }
Node left { get; set; }
Node right { get; set; }
static List<Node> nodes { get; set; }
public static Node BuildTree(int[] input)
{
nodes = new List<Node>();
foreach(int i in input)
{
Node node = new Node();
node.left = null;
node.right = null;
node.value = i;
nodes.Add(node);
}
Node root = nodes[0];
int start = 0;
int row = 0;
while(start < nodes.Count)
{
int end = row + start;
for (int i = start; i < Math.Min(end + 1, nodes.Count); i++)
{
int col = i - start;
int leftChild = (end + 1 + col) < nodes.Count ? end + 1 + col : -1;
int rightChild = (end + 2 + col) < nodes.Count ? end + 2 + col : -1;
Console.WriteLine("row = {0}, col = {1}, left = {2}, right = {3}, start = {4}, end = {5}", row, col, leftChild, rightChild,start, end);
nodes[i].left = (leftChild == -1) ? null : nodes[leftChild];
nodes[i].right = (rightChild == -1) ? null : nodes[rightChild];
}
start = end + 1;
row++;
}
return root;
}
}
I am trying to do a simple inorder traversal of a BST and the BST builds properly but when I try to print the BST inorder it goes to the first left node and then doesn't go to any other nodes after that and creates an overflow.
Ive tried to do different inorder traversals with getLeft and getRight but it is still doing the same thing
class Program
{
static void Main(string[] args)
{
Tree tree = new Tree();
List<int> rands = new List<int>();
Random random = new Random();
int between = random.Next(20, 30);
for (int i = 0; i < between; i++)
{
rands.Add(random.Next(100));
}
for (int x = 0; x < rands.Count; x++)
{
tree.constructTree(rands[x]);
}
tree.Inorder(tree.returnRoot());
}
class Node
{
private int number;
public Node left;
public Node right;
public Node()
{
}
public Node getLeft()
{
return this.left;
}
public Node getRight()
{
return this.right;
}
public int GetSetNumber
{
get
{
return this.number;
}
set
{
this.number = value;
}
}
public Node GetSetLeft
{
get
{
return this.left;
}
set
{
this.left = value;
}
}
public Node GetSetRight
{
get
{
return this.right;
}
set
{
this.right = value;
}
}
}
class Tree
{
public Node root;
public Node returnRoot()
{
return this.root;
}
public void constructTree(int num)
{
Node t = new Node();
t.GetSetNumber = num;
if (root == null)
{
root = t;
}
else
{
Node cur = root;
Node top;
while (true)
{
top = cur;
if (num < top.GetSetNumber)
{
cur = cur.GetSetLeft;
if (cur == null)
{
top.GetSetLeft = t;
return;
}
}
else
{
cur = cur.GetSetRight;
if (cur == null)
{
top.GetSetRight = t;
return;
}
}
}
}
}
public void Inorder(Node Root)
{
if (root == null)
{
return;
}
Inorder(root.left);
Console.WriteLine(root.GetSetNumber + " ");
Inorder(root.right);
}
}
You are referencing root in Inorder, not Root. root (lower-case r) is the class variable containing the root of the entire tree, not the Node parameter you have passed in. Your code loops infinitely because you are calling Inorder on the same node forever.
If you capitalize your references to root in Inorder (or use a different variable name in the method to avoid confusion, like current) you should be able to make some progress.
public void Inorder(Node Root)
{
if (Root == null)
{
return;
}
Inorder(Root.left);
Console.WriteLine(Root.GetSetNumber + " ");
Inorder(Root.right);
}
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();
}
}
I'm trainee and have a problem with that I can't solve this problem alone. So please help me. I found many topics but I could not find a solution.
I just start to learn C# and I'm not sure how to do this. I know that is a simple job but realy I need to understand and solve it. I try to do something but it is only some code. I did my binary tree with some values, have a node class and print method.
Please tell me how to write a code that can read a tree from the Console, because I don't want to have any hardcorde. And then how to find a lowest common ancestor - I see the BFS and DFS algorithms so maybe I can find something, but I'm not sure.
I've read much about this but I can not explain many things. Her
Here is the my code:
class Program
{
static void Main(string[] args)
{
var binatyTree = new BinaryTree<int>(1,
new BinaryTree<int>(2,
new BinaryTree<int>(4),
new BinaryTree<int>(5)),
new BinaryTree<int>(3,
new BinaryTree<int>(6,
new BinaryTree<int>(9),
new BinaryTree<int>(10)),
new BinaryTree<int>(7))
);
Console.WriteLine("Binary Tree:");
binatyTree.Print();
}
}
my binary tree and print method:
public class BinaryTree<T>
{
public T Value { get; set; }
public BinaryTree<T> LeftChildren { get; set; }
public BinaryTree<T> RightChildren { get; set; }
public BinaryTree(T value, BinaryTree<T> leftChildren = null, BinaryTree<T> rightChildren = null)
{
this.Value = value;
this.LeftChildren = leftChildren;
this.RightChildren = rightChildren;
}
public void Print (int indent = 0)
{
Console.Write(new string (' ', 2*indent));
Console.WriteLine(this.Value);
if (this.LeftChildren != null)
{
this.LeftChildren.Print(indent + 1);
}
if (this.RightChildren != null)
{
this.RightChildren.Print(indent + 1);
}
}
my class Node:
class Node
{
private int data;
private Node left;
private Node right;
public Node(int data = 0)
{
this.data = 0;
left = null;
right = null;
}
}
So please I realy need to understand every connections so please if you can explain for me and help.
So here is my Binary tree code.
using System;
namespace MyBinaryTree
{
// Creates a binary tree
// Finds the lowest common ancestor in a binary tree
class МainSolution
{
static void Main(string[] args)
{
// Initialises binary tree view
var btView = new ViewBinaryTree();
btView.BinaryTreeView();
// Initialises new binary tree
BinarySearchTree tree = new BinarySearchTree();
// Reads the desired number of nodes
Console.Write("Enter how many nodes you want: ");
int number = int.Parse(Console.ReadLine());
Console.WriteLine();
// Reads the nodes' values
for (int i = 1; i <= number; i++)
{
Console.Write($"Enter name of {i} node: ");
string nodeName = Console.ReadLine().ToUpper();
tree.Insert(nodeName);
}
// Lowest common ancestor - reads the two required values
// Checks the values
// Prints the lowest common ancestor
bool isValid = true;
while (isValid)
{
Console.WriteLine();
Console.Write("Please enter the first node value: ");
string nameOne = Console.ReadLine().ToUpper();
Console.Write("Please enter the second node value: ");
string nameTwo = Console.ReadLine().ToUpper();
if (tree.Find(nameOne) == true && tree.Find(nameTwo) == true)
{
Console.WriteLine();
var result = tree.SearchLCA(tree.root, nameOne, nameTwo);
Console.WriteLine($"Lowest common ancestor: {result} ");
Console.WriteLine();
isValid = false;
}
else
{
Console.WriteLine();
Console.WriteLine("Please enter a valid name!");
}
}
}
}
}
Create a class Node:
// Creates the node structure
class Node
{
public string Data { get; set; }
public Node RightChild { get; set; }
public Node LeftChild { get; set; }
public Node(string data, Node left = null, Node right = null)
{
this.Data = data;
this.LeftChild = left;
this.RightChild = right;
}
}
Here is my logic
// Creates a binary tree.
class BinarySearchTree
{
public Node root; // Creates a root node.
public BinarySearchTree()
{
this.root = null;
}
// Adds a node in the binary tree.
public void Insert(string inputValue)
{
Node newNode = new Node(inputValue); // Creates a new node.
if (root == null) // If the tree is empty, inserts the new node as root
{
root = newNode;
return;
}
//Determins where to place the new node in the binary tree.
Node current = root;
Node parent = null;
while (true)
{
parent = current;
if (inputValue.CompareTo(current.Data) < 0)
{
current = current.LeftChild;
if (current == null)
{
parent.LeftChild = newNode;
return;
}
}
else
{
current = current.RightChild;
if (current == null)
{
parent.RightChild = newNode;
return;
}
}
}
}
// Checks if the node exists in the binary tree
public bool Find(string inputValue)
{
Node current = root;
while (current != null)
{
if (current.Data.Equals(inputValue))
{
return true;
}
else if (current.Data.CompareTo(inputValue) > 0)
{
current = current.LeftChild;
}
else
{
current = current.RightChild;
}
}
return false;
}
// Creates a method to find the lowest common ancestor(LCA).
public object SearchLCA(Node searchTree, string compareValue1, string compareValue2)
{
if (searchTree == null)
{
return null;
}
if (searchTree.Data.CompareTo(compareValue1) > 0 && searchTree.Data.CompareTo(compareValue2) > 0)
{
return SearchLCA(searchTree.LeftChild, compareValue1, compareValue2);
}
if (searchTree.Data.CompareTo(compareValue1) < 0 && searchTree.Data.CompareTo(compareValue2) < 0)
{
return SearchLCA(searchTree.RightChild, compareValue1, compareValue2);
}
return searchTree.Data;
}
}
"Thank you!"
I am trying to implement a basic Binary search tree.
I was able to create a Node and I have problems with the AddNode() function. It is supposed to add a new node to the existing tree but it replaces it.
Any ideas what should be done in the AddNode() function ?
class Node
{
public int value { get; set; }
public Node left { get; set; }
public Node right { get; set; }
public Node(int i)
{
this.value = i;
this.left = null;
this.right = null;
}
}
class Tree
{
public Node root { get; set; }
public Tree(Node n)
{
root = n;
}
public void AddNode(int valueToBeInserted)
{
if (this.root == null)
{
this.root = new Node(valueToBeInserted);
// problem here : existing tree is destroyed.
// a new one is created.
// instead it should add a new node to the end of the tree if its null
}
if (valueToBeInserted < this.root.value)
{
this.root = this.root.left;
this.AddNode(valueToBeInserted);
}
if (valueToBeInserted > this.root.value)
{
this.root = this.root.right;
this.AddNode(valueToBeInserted);
}
}
public void printTree()
{
// print recursively the values here.
}
}
class TreeTest
{
public void Test()
{
var tree = new Tree(new Node(100));
tree.AddNode(20);
tree.AddNode(100);
}
}
Thanks.
These lines replace the root:
this.root = this.root.left;
this.root = this.root.right;
You should instead pass a parameter to your recursive function.
You can also remove the this quantifiers - they're only necessary when you have a local variable with the same name or perhaps in some other corner cases.
Adding a helper function is useful / necessary since the root must be catered for separately.
Updated code:
public void AddNode(int valueToBeInserted)
{
if (root == null)
{
root = new Node(valueToBeInserted);
}
else
{
AddNode(valueToBeInserted, root);
}
}
private void AddNode(int valueToBeInserted, Node current)
{
if (valueToBeInserted < current.value)
{
if (current.left == null)
current.left = new Node(valueToBeInserted);
else
AddNode(valueToBeInserted, current.left);
}
if (valueToBeInserted > current.value)
{
if (current.right == null)
current.right = new Node(valueToBeInserted);
else
AddNode(valueToBeInserted, current.right);
}
}
This statement will only be true the first time you run your code.
if (this.root == null)
{
this.root = new Node(valueToBeInserted);
}
Nowhere does the this.root get set to null again...
Normally you would code the add like this:
public void AddNode(int valueToBeInserted)
{
if (this.root == null)
{
this.root = new Node(valueToBeInserted);
}
if (valueToBeInserted < this.root.value)
{
this.root.left = this.AddNode(valueToBeInserted);
this.root = this.root.left;
}
if (valueToBeInserted > this.root.value)
{
this.root.right = this.AddNode(valueToBeInserted);
this.root = this.root.right;
}
}