Null Exception Errors - c#

This is my code for a binary tree program I am doing for an algorithms class. I keep getting a null exception error thrown, but I have no clue what's causing it.
namespace Tree
{
class CallTree
{
static void Main(string[] args)
{
BNode HE = new BNode(0, "House Entrance");
BNode LowerHallway = new BNode(0, "Lower Hallway");
BNode UpperHallway = new BNode(0, "Upper Hallway");
HE.setLeft(LowerHallway);
HE.setRight(UpperHallway);
BNode Lounge = new BNode(0, "Lounge");
BNode Kitchen = new BNode(0, "Kitchen");
LowerHallway.setLeft(Lounge);
LowerHallway.setRight(Kitchen);
BNode Balcony = new BNode(0, "Balcony");
Kitchen.setRight(Balcony);
BNode Study = new BNode(0, "Study");
BNode MasterBedroom = new BNode(0, "Master Bedroom");
UpperHallway.setLeft(Study);
UpperHallway.setRight(MasterBedroom);
BNode GuestBath = new BNode(0, "Guest Bath");
BNode GuestBedroom = new BNode(0, "Guest Bedroom");
Study.setLeft(GuestBath);
Study.setRight(GuestBedroom);
BNode PrivateBath = new BNode(0, "Private Bath");
BNode Closet = new BNode(0, "Closet");
MasterBedroom.setLeft(PrivateBath);
MasterBedroom.setRight(Closet);
HBinaryTree HBinaryTree = new HBinaryTree(HE);
BNode rootNode = HBinaryTree.GetRoot();
I get an exception for 'rootNode' here V
HBinaryTree.preOrder(rootNode);
//HBinaryTree.inOrder(rootNode);
//HBinaryTree.postOrder(rootNode);
Console.ReadKey();
}
}
//definition of node in a binary tree
public class BNode
{
public string room;
public int treasure;
public BNode left, right;//left child and right child
public BNode(int item, string room)
{
treasure = item;
left = null;
right = null;
}
public BNode(int item, string room, BNode leftNode, BNode rightNode)
{
treasure = item;
left = leftNode;
right = rightNode;
}
public void show()
{
Console.Write(treasure);
}
//Is it interial node?
public bool isInner()
{
return left != null || right != null;
}
//Is it a leaf node?
public bool isLeaf()
{
return left == null && right == null;
}
//Does it have a left child?
public bool hasLeft()
{
return left != null;
}
//Does it have a right child?
public bool hasRight()
{
return right != null;
}
//Set its left child to be newLeft
public void setLeft(BNode newLeft)
{
left = newLeft;
}
//Set its right child to be newRight
public void setRight(BNode newRight)
{
right = newRight;
}
//return data value
public int getValue()
{
return treasure;
}
//set data value
public void setValue(int newValue)
{
treasure = newValue;
}
}
//definition of a proper binary tree
class HBinaryTree
{
public BNode root; //root of the tree
public HBinaryTree()
{
root = null;
}
public BNode GetRoot()
{
return root;
}
public HBinaryTree(BNode rootNode) // constructor
{
root = rootNode;
}
// PreOrder traversal
public void preOrder(BNode root)
{
And more exception errors for 'root' in these 4 lines V
root.show();
if (root.isInner())
{
preOrder(root.left);
preOrder(root.right);
}
}
//// InOrder traversal
//public void inOrder(BNode root)
//{
// if (root.isInner())
// {
// inOrder(root.left);
// }
// root.show();
// if (root.isInner())
// {
// inOrder(root.right);
// }
//}
//PostOrder traversal
//public void postOrder(BNode root)
//{
// if (root.isInner())
// {
// postOrder(root.left);
// postOrder(root.right);
// }
// root.show();
//}
}
}
I would like it if someone could help me deduce what is causing the exceptions for 'root' and 'rootNode' to be thrown. It states they are null but I can't understand why it states that.

Your preOrder function recursively calls itself for the left and right nodes off every node in your tree if isInner returns true. isInner returns true if either of its nodes are non-null, but your kitchen has only a right branch, and its left is null. So when that function reaches the kitchen, it sees isInner is true and it calls itself with the left branch off kitchen which is null. You need to check for null for left and right individually.

Related

DoublyLinkedList C# Removelast two elements

i tried to fix a code, which is a LinkedList. The task is to Remove the last X elements of the list.
I tried it with RemoveRange, but VS don't accept my solution and says, that RemoveRange doesn't exist.
var list = new DoublyLinkedList<string>();
list.Add("A");
list.Add("B");
list.Add("C");
list.Add("D");
list.Add("E");
list.RemoveLast(2);
This is the Code in the Program (Main).
In a second class there should be the method RemoveLast, but i dont get a working code. Can someone explain me, how i get the RemoveLast?
using System;
using System.Collections;
using System.Collections.Generic;
namespace Test
{
public class DoublyLinkedList<T> : IEnumerable<T>
{
public void RemoveLast(int v)
{
int remove = Math.Max(0, this.Count - v);
this.RemoveRange(v, this.Count - v);
}
}
}
RemoveRange is red underlined
Thank you for your help!
Full DoublyLinkedList:
`using System;
using System.Collections;
using System.Collections.Generic;
namespace Test
{
public class DoublyLinkedList<T> : IEnumerable<T>
{
public void RemoveLast(int v)
{
int remove = Math.Max(0, this.Count - v);
this.RemoveRange(v, this.Count - v);
}
private sealed class Node
{
public T Item { get; set; }
public Node Previous { get; set; }
public Node Next { get; set; }
}
private Node first, last;
public int Count { get; private set; }
public void Add(T item)
{
Node newItem = new Node() { Item = item, Next = null, Previous = null };
if (first == null)
{
first = newItem;
last = newItem;
}
else
{
last.Next = newItem;
newItem.Previous = last;
last = newItem;
}
Count++;
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
Node node = first;
while (node != null)
{
yield return node.Item;
node = node.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<T>)this).GetEnumerator();
}
public override string ToString()
{
string s = "";
Node node = first;
while (node != null)
{
s += node.Item.ToString() + " -> ";
node = node.Next;
}
s += "Count: " + Count.ToString();
return s;
}
private Node find(T item)
{
Node node = first;
while (node != null)
{
if (node.Item.Equals(item))
return node;
node = node.Next;
}
return null;
}
private Node findPrevious(T item)
{
Node previousNode = null;
Node node = first;
while (node != null)
{
if (node.Item.Equals(item))
return previousNode;
previousNode = node;
node = node.Next;
}
return null;
}
}
}`
You do know there is already a double linked list class, don't you?
System.Collections.Generic.LinkedList? My advice would be to use that class.
If it is too much work to redesign your code, for instance because your DoublyLinkedList is already used a lot, my advice would be to make DoublyLinkedList an adapter for LinkedList:
class DoublyLinkedList<T> : IEnumerable<T>, IEnumerable
{
private readonly LinkedList<T> linkedList = new LinkedList<T>();
public int Count => this.linkedList.Count;
public void Add(T item)
{
this.LinkedList.Add(item);
}
public IEnumerator<T> GetEnumerator()
{
return this.LinkedList.GetEnumerator();
}
... // etc.
}
You need to add a method to remove the last N items from your list. For example
RemoveLast(10) is supposed to remove the last 10 elements from your doubly linked list. If your list has 10 or less elements, this would clear your complete list.
void Clear()
{
this.LinkedList.Clear();
}
void RemoveLast()
{
if (this.LinkedList.Count != 0)
this.linkedList.RemoveLast();
}
void RemoveLast(int removeCount)
{
if (this.Count <= removeCount)
{
this.linkedList.Clear();
}
else
{
for (int i=0; i<removeCount; ++i)
{
this.RemoveLast();
}
}
}
It might be that your supervisor is stubborn and does not follow your advise to reuse fully tested trustworthy .NET classes. In that case you'll have to change the RemoveLast() method.
void Clear()
{
this.first = null;
this.last = null;
this.count = 0;
}
void RemoveLast()
{
switch (this.Count)
{
case 0:
// empty list; do nothing
break;
case 1:
// removing the last element of the list
this.Clear();
break;
default:
var lastNode = this.last;
// because more than one element I'm certain there is a previous node
var previousNode = lastNode.Previous;
var previousNode.Next = null;
this.last = previousNode;
--this.count;
break;
}
}
Here is how you can implement RemoveLast(int n) in your DoublyLinkedList:
// Removes last "n" elements.
public void RemoveLast(int n)
{
for (int i = 0; i < n; i++)
RemoveLast();
}
// Removes the last element.
public void RemoveLast()
{
// List is empty. No need to remove elements.
if (first == null)
{
return;
}
// List contains only one element. Remove it.
else if (first == last)
{
first = null;
last = null;
}
// List contains more than one element. Remove the last.
else
{
// The next two lines make "last" to point to the element before the last.
last = last.Previous;
last.Next = null;
}
Count--;
}
Here is complete sample.
If RemoveRange is not available, you can easiliy roll your own implementation that works on any enumerable without Linq in this way (this code is an idea as I do not have access to all your code).
using System;
using System.Collections;
using System.Collections.Generic;
public void RemoveRange(int count)
{
if (count > this.Count)
throw new ArgumentOutOfRangeException(nameof(count));
while (count > 0)
{
RemoveTail();
count--;
}
}
private void RemoveTail()
{
if (this.Count == 0)
return;
var previous = last.Previous;
if (previous != null)
{
previous.Next = null;
last = previous;
this.Count--;
}
else
{
// this implies count == 1
last = null;
first = null;
this.Count = 0;
}
}
Essentially, you can expose your RemoveRange method and then perform an agnostic removal of the last node (tail) one by one.
This answer has been edited to reflect the code changes.

Queue Implementation using Linked List: C#

I am learning Data Structure. Today, I wanted to implement Queue using Linked List. As we have FRONT and REAR first index of the entry point of the Queue. If someone asks me to implement a Queue with Linked List, please confirm my below implementation (I am able to achieve the Queue objective without the REAR object.)
Is this implementation valid?
class Queue
{
Node head;
class Node
{
public int Value;
public Node next;
public Node()
{
next = null;
}
}
public void addElement(int val)
{
if (head == null)
{
Node temp = new Node();
temp.Value = val;
head = temp;
return;
}
Node tempNode = head;
while (tempNode.next != null)
{
tempNode = tempNode.next;
}
Node newElement = new Node();
newElement.Value = val;
tempNode.next = newElement;
}
public void Dequeue()
{
if (head != null)
{
if (head.next != null)
{
head = head.next;
return;
}
head = null;
}
}
}
class Program
{
static void Main(string[] args)
{
Queue queue = new Queue();
queue.addElement(10);
queue.addElement(20);
queue.addElement(30);
queue.addElement(40);
queue.Dequeue();
queue.Dequeue();
queue.Dequeue();
queue.Dequeue();
}
}
Well, if we want to have front and rear ends, let's have them:
private Node m_Head;
private Node m_Tail;
You have just one Node head; field and that's why your implementation at least inefficient: you have O(N) time complexity to addElement:
...
while (tempNode.next != null)
{
tempNode = tempNode.next;
}
...
When you can easily have O(1)
I suggest using typical names like Enqueue instead of addElement and have Try methods (often, we don't want exceptions if queue is empty). Finally, let's use generics: MyQueue<T> where T is item's type.
public class MyQueue<T> {
private class Node {
public Node(Node next, T value) {
Next = next;
Value = value;
}
public Node Next { get; internal set; }
public T Value { get; }
}
private Node m_Head;
private Node m_Tail;
public void Enqueue(T item) {
Node node = new Node(null, item);
if (m_Tail == null) {
m_Head = node;
m_Tail = node;
}
else {
m_Tail.Next = node;
m_Tail = node;
}
}
public bool TryPeek(out T item) {
if (m_Head == null) {
item = default(T);
return false;
}
item = m_Head.Value;
return true;
}
public T Peek() {
if (m_Head == null)
throw new InvalidOperationException("Queue is empty.");
return m_Head.Value;
}
public bool TryDequeue(out T item) {
if (m_Head == null) {
item = default(T);
return false;
}
item = m_Head.Value;
m_Head = m_Head.Next;
return true;
}
public T Dequeue() {
if (m_Head == null)
throw new InvalidOperationException("Queue is empty.");
T item = m_Head.Value;
m_Head = m_Head.Next;
return item;
}
}

How do I create and then declare a linked list in a linked list in c# using classes?

So, I'm trying to create a linked list inside each element of a linked list but I have no idea how to fill up the inner list with elements.
I first declare the outer list like this
RoomList<int> room = new RoomList<int>();
This is the class structure I use (not sure if even this is correct)
public class RoomList<T>
{
DailyList head;
public class DailyList
{
DailyListElement head;
DailyListElement next;
class DailyListElement
{
public T data;
public DailyListElement next;
}
}
}
And this is a function I use to create a DailyList object
public void DailyListCreate()
{
DailyList newDailyList = new DailyList();
}
But I don't know how to add a DailyListElement. I hope this makes sense.
So I want to find out how to fill up the DailyList with DailyListElements.
I tried a linked list within a linked list based on your provided code. In there I have added the methods to add a new node and get all nodes at both levels (outer and inner linked lists). Please find the code below for the linked list structure as well as the client code:
The linked list structure
public class RoomList<T> where T : class
{
private DailyList current;
private DailyList head;
public void Add(DailyList newItem)
{
if(current != null)
current.next = newItem;
current = newItem;
if(head == null)
head = current;
}
public IEnumerable<DailyList> GetAllNodes()
{
DailyList current = head;
List<DailyList> lst = new List<DailyList>();
while (current != null)
{
lst.Add(current);
current = current.next;
}
return lst;
}
public class DailyList
{
public DailyList next;
private DailyListElement head;
private DailyListElement current;
public void Add(DailyListElement newItem)
{
if(current != null)
current.next = newItem;
current = newItem;
if(head == null)
head = current;
}
public IEnumerable<DailyListElement> GetAllNodes()
{
DailyListElement current = head;
List<DailyListElement> lst = new List<DailyListElement>();
while (current != null)
{
lst.Add(current);
current = current.next;
}
return lst;
}
public class DailyListElement
{
public T data;
public DailyListElement next;
}
}
}
The client code:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var lst =new RoomList<string>();
var upperNode = new RoomList<string>.DailyList();
var element = new RoomList<string>.DailyList.DailyListElement();
element.data = "first";
upperNode.Add(element);
element = new RoomList<string>.DailyList.DailyListElement();
element.data = "second";
upperNode.Add(element);
lst.Add(upperNode);
upperNode = new RoomList<string>.DailyList();
element = new RoomList<string>.DailyList.DailyListElement();
element.data = "third";
upperNode.Add(element);
element = new RoomList<string>.DailyList.DailyListElement();
element.data = "fourth";
upperNode.Add(element);
lst.Add(upperNode);
foreach(var item in lst.GetAllNodes())
{
foreach(var child in item.GetAllNodes())
{
Console.WriteLine(child.data);
}
}
}
}
You need to implement a method that will add a new element.
You could do this by traversing the elements until you reach the first one where next is null, then assign the new element to next.
Or you could maybe also maintain a pointer to the last element and access it directly.
You need to add methods Add to your RoomList and DailyList classes.
public class RoomList<T>
{
public DailyList head;
public DailyList Add()
{
var newItem = new DailyList();
if (head != null) head.next = newItem;
head = newItem;
return newItem;
}
public class DailyList
{
public DailyList next;
public DailyListElement head;
public DailyListElement Add()
{
var newItem = new DailyListElement();
if (head != null) head.next = newItem;
head = newItem;
return newItem;
}
public class DailyListElement
{
public T data;
public DailyListElement next;
}
}
}
Usage example:
var roomList = new RoomList<string>();
var dailyList = roomList.Add();
var dailyListElement = dailyList.Add();
dailyListElement.data = "StackOverflow rocks!";
Console.WriteLine(roomList.head.head.data);
Output:
StackOverflow rocks!

Recursive Insertion in a Binary Tree

Why reason the member variables LEFT and RIGHT never change when i make the recursive call?
Here's the Source Code:
public class C_Nodo
{
int dato;
C_Nodo left;
C_Nodo right;
public int DATO
{
get { return dato; }
set { dato = value; }
}
public C_Nodo LEFT
{
get { return this.left; }
set { this.left= value; }
}
public C_Nodo RIGHT
{
get { return this.right; }
set { this.right = value; }
}
public C_Nodo(int inf)
{
this.dato = inf;
this.left = null;
this.right = null;
}
}
public class C_Arbol_Bin
{
C_Nodo root;
public C_Arbol_Bin()
{
root = null;
}
Simple insertion in the root or make the recursive call
public void inserta(int dat)
{
if (root == null)
{
root = new C_Nodo(dat);
}
else
{
insert_Order(this.root, dat);
}
}
Here i make the recursive insertion in ordered way depending of the value that contains the father node but RIGH and LEFT never change.
public void insert_Order(C_Nodo tree, int inf)
{
if (tree == null)
{
tree = new C_Nodo(inf);
}
else
{
if (tree.DATO > inf)
{
insert_Order(tree.LEFT, inf);
}
else
{
insert_Order(tree.RIGHT, inf);
}
}
}
}
Declare the function like
public void insert_Order( ref C_Nodo tree, int inf );
Also as this function is an auxiliary function for function inserta then it could be declared like private
What Vlad said...
Basically the reason that the LEFT/RIGHT parts are always null is because you are passing a reference-type object by value, and then call new C_Nodo() on it - this creates a pointer to a new location for your object.
So you can either use Vlad's solution and pass it by reference, or you can change your insert and insert_Order methods to return the Node object and save it in the root node:
public void inserta(int dat)
{
if (root == null)
{
root = new C_Nodo(dat);
}
else
{
this.root = insert_Order(this.root, dat);
}
}
private C_Nodo insert_Order(C_Nodo tree, int inf)
{
if (tree == null)
{
tree = new C_Nodo(inf);
}
else
{
if (tree.DATO > inf)
{
tree.LEFT = insert_Order(tree.LEFT, inf);
}
else
{
tree.RIGHT = insert_Order(tree.RIGHT, inf);
}
}
return tree;
}
Check out this article for more info on references: https://msdn.microsoft.com/en-us/library/s6938f28.aspx

c# object loses reference when removed from list

I have a very strange issue. Basically I have created a class called TreeNode that represents a node in a tree. I then create the tree by adding all the nodes to a List.
class TreeNode
{
private TreeNode parent, lChild, rChild;
private int key, val;
public int Key
{
get { return key; }
set { key = value; }
}
public int Val
{
get { return val; }
set { val = value; }
}
public TreeNode Parent
{
get { return parent; }
set { parent = value; }
}
public TreeNode LChild
{
get { return lChild; }
}
public TreeNode RChild
{
get { return rChild; }
}
public TreeNode(int k, int v)
{
key = k;
val = v;
}
public void SetChild(TreeNode leftChild, TreeNode rightChild)
{
this.lChild = leftChild;
this.rChild = rightChild;
}
public bool isLeaf()
{
if (this.lChild == null && this.rChild == null)
{
return true;
} else
{
return false;
}
}
public bool isParent()
{
if (this.parent == null)
{
return true;
}
else
{
return false;
}
}
public void SetParent(TreeNode Parent)
{
this.parent = Parent;
}
}
So if i put a breakpoint just after the creation of the tree and hover over the list in Visual Studio I can see the structure of the tree - with all the references working perfectly from the root down to the leaves.
If however I do the following:
TreeNode test = newTree[newTree.Count - 1];
please note:
private List<TreeNode> newTree = new List<TreeNode>();
which returns the root node - and hover over again I can do down one level (i.e. left child or right child) but these children do not have any references for their children after that.
I'm wondering if I'm losing the reference in memory to the other nodes in the list as the test node is not part of the list?
Any help would be greatly appreciated.
Thanks
Tom
you sure you don't have (note no space between new and tree in your code)
TreeNode test = new Tree[newTree.Count - 1];
Which would create a new empty array of tree (probably not what you intended), and leave your original tree un-rooted and inaccessible.
Can you make sure your code is correct, please?
Seems as though I found the issue - I wasn't correctly updating some of the parent nodes with their relevant child nodes - problem solved.
Thanks for your help
Tom

Categories

Resources