I'm trying to create a function InsertInOrder() that inserts an item in the correct place without disturbing the order.
Ex:
LinkedList before [3,5,6] after inserting 4 ---> [3,4,5,6].
I have created the function but some reason it's not working as expected.
I'm testing the code on a Windows form application by entering ISBNs,
What went wrong:
First I inserted 23, then I inserted 10, expecting to be placed before 23 but here's what happened (image below):
What went wrong
Please find the code below:
LinkListGen Class
class LinkListGen<T> where T : IComparable
{
private LinkGen<T> list;
public LinkListGen()
{
list = null;
}
public void AddItem(T item)
{
list = new LinkGen<T>(item, list); //create a new link on the front of the list
}
public void AppendItem(T item)
{
LinkGen<T> temp = list;
if (temp == null)
{
list = new LinkGen<T>(item);
}
else
{
while (temp.Next != null)
{
temp = temp.Next;
}
temp.Next = new LinkGen<T>(item);
}
}
public string DisplayList()
{
string buffer = "";
LinkGen<T> temp = list; //temp starts beginning of list
while (temp != null) //not at end of list
{
buffer = buffer + temp.Data.ToString() + ",";
temp = temp.Next; //move along a link
}
return buffer;
}
public void RemoveItem(T item)
{
LinkGen<T> temp = list;
LinkListGen<T> newList = new LinkListGen<T>();
while (temp != null)
{
if (item.CompareTo(temp.Data) != 0)
{
newList.AppendItem(temp.Data);
}
temp = temp.Next;
}
list = newList.list;
}
public void InsertInOrder (T item)
{
LinkGen<T> temp = list;
LinkListGen<T> newList = new LinkListGen<T>();
if (list == null)
{
AppendItem(item);
}
else
{
while (temp != null)
{
if(list.Data.CompareTo(item) < 0)
{
newList.AppendItem(list.Data);
temp = temp.Next;
}
else if(list.Data.CompareTo(item) > 0)
{
newList.AppendItem(item);
newList.AppendItem(list.Data);
temp = temp.Next;
}
newList.AppendItem(list.Data);
temp = temp.Next;
}
}
}
}
Windows Form App code
public partial class Form1 : Form
{
LinkListGen<Book> ISBNList = new LinkListGen<Book>();
public Form1()
{
InitializeComponent();
}
private void AddButton_Click(object sender, EventArgs e)
{
double insertedISBN = Convert.ToDouble(ISBNTextBox.Text);
Book newBook = new Book(insertedISBN);
ISBNList.InsertInOrder(newBook);
DisplayLabel.Text = ISBNList.DisplayList();
}
private void RemoveButton_Click(object sender, EventArgs e)
{
double insertedISBN = Convert.ToDouble(ISBNTextBox.Text);
Book removeBook = new Book(insertedISBN);
ISBNList.RemoveItem(removeBook);
DisplayLabel.Text = ISBNList.DisplayList();
}
}
Your problem, that you call AppendItem at InsertInOrder, which adds element to the end of the list, instead pure pointer manipulation.
At the same time, you shouldn't recreate list at InsertInOrder to avoid memory/time overhead.
Try next code, not tested:
public void InsertInOrder(T item)
{
var node = new LinkGen<T>(item);
if (list == null)
{
list = node;
return;
}
var current = list;
while (current != null)
{
if (current.Data.CompareTo(item) < 0)
{
// current is last element
if (current.Next == null)
{
current.Next = node;
break;
}
// current.Next.Data is equal or greater than new value
// so set new node.Next to current.Next and current.Next to new node
if (current.Next.Data.CompareTo(item) >= 0)
{
node.Next = current.Next;
current.Next = node;
break;
}
}
current = current.Next;
}
}
Related
public bool add(int e)
{
if(head == null)
{
Node n = new Node
{
element = e
};
head = n;
return true;
}
Node t = head;
if(t.next == null)
{
if(t.element == e)
{ return false; }
Node n = new Node
{
element = e
};
t.next = n;
return true;
}
t = t.next;
this.add(e);
return true;
}
This is a code to add a new node in set. No duplicated values allowed. There is Main Class called Sets and one inner class called Nodes.
I know Node t = head; is creating a problem is there anyway to make this recursive? Even passing extra optional parameters doesn't help.
If I understood your question correctly, to make it recursive you would need to split it into two functions, a public one for handling the head == null case, and a private one for handling n.next == null and is recursive.
public bool add(int e)
{
if (head == null)
{
head = new Node { element = e };
return true;
}
return add(head, e);
}
private bool add(Node n, int e) {
if (n.element == e)
return false;
if (n.next == null) {
n.next = new Node { element = e };
return true;
}
return add(n.next, e);
}
However, I would suggest instead doing something akin to the following which does everything in one function:
public bool add(int e)
{
if (head == null)
{
head = new Node { element = e };
return true;
}
if (head.element == e)
return false;
Node n = head;
while (n.next != null) {
if (n.element == e)
return false;
n = n.next;
}
n.next = new Node { element = e };
return true;
}
I'm having problems trying to write a reverse recursive method for a LinkedList class I created in C#.
The LinkedList has 2 pointers in it one for the head and the other for the tail:
public class Node
{
public object data;
public Node next;
public Node(object Data)
{
this.data = Data;
}
}
public class LinkedList
{
Node head;
Node tail;
public void Add(Node n)
{
if (head == null)
{
head = n;
tail = head;
}
else
{
tail.next = n;
tail = tail.next;
}
}
Now, the recursive reverse function goes like this:
public void reverse_recursive()
{
Node temp_head = head;
if (temp_head == tail)
{
return;
}
while (temp_head != null)
{
if (temp_head.next == tail)
{
tail.next = temp_head;
tail = temp_head;
reverse_recursive();
}
temp_head = temp_head.next;
}
}
I'm having 2 troubles with it: first, a logic problem, I know that head doesn't point to the first node after the reverse. The second problem is that i probably do something wrong with the null pointer so the program crashes.
I also give you the main program:
class Program
{
static void Main(string[] args)
{
LinkedList L = new LinkedList();
L.Add(new Node("first"));
L.Add(new Node("second"));
L.Add(new Node("third"));
L.Add(new Node("forth"));
L.PrintNodes();
L.reverse_recursive();
L.PrintNodes();
Console.ReadLine();
}
}
Thank you for helping!!
public void Reverse()
{
this.Reverse(this.head);
}
private void Reverse(Node node)
{
if (node != null && node.next != null)
{
// Create temporary references to the nodes,
// because we will be overwriting the lists references.
Node next = node.next;
Node afterNext = node.next.next;
Node currentHead = this.head;
// Set the head to whatever node is next from the current node.
this.head = next;
// Reset the next node for the new head to be the previous head.
this.head.next = currentHead;
// Set the current nodes next node to be the previous next nodes next node :)
node.next = afterNext;
// Keep on trucking.
this.Reverse(node);
}
else
{
this.tail = node;
}
}
public void reverse()
{
reverse_recursive(tail);
Node tmp = tail;
tail = head;
head = tmp;
}
public void reverse_recursive(Node endNode)
{
Node temp_head = head;
if (temp_head == endNode)
{
return;
}
while (temp_head != null)
{
if (temp_head.next == endNode)
{
break;
}
temp_head = temp_head.next;
}
endNode.next = temp_head;
temp_head.next = null;
reverse_recursive(temp_head);
}
See also this
Another option over here.
class Program{
static void Main(string[] args)
{
LinkedList L = new LinkedList();
L.Add(new Node("first"));
L.Add(new Node("second"));
L.Add(new Node("third"));
L.Add(new Node("forth"));
L.PrintNodes();
L.reverse_recursive();
Console.WriteLine("---------------------");
L.PrintNodes();
Console.ReadLine();
}
}
public class Node
{
public object data;
public Node next;
public Node(object Data)
{
this.data = Data;
}
}
public class LinkedList
{
Node head;
Node tail;
public void Add(Node n)
{
if (head == null)
{
head = n;
tail = head;
}
else
{
tail.next = n;
tail = tail.next;
}
}
public void PrintNodes()
{
Node temp = head;
while (temp != null)
{
Console.WriteLine(temp.data);
temp = temp.next;
}
}
private LinkedList p_reverse_recursive(Node first)
{
LinkedList ret;
if (first.next == null)
{
Node aux = createNode(first.data);
ret = new LinkedList();
ret.Add(aux);
return ret;
}
else
{
ret = p_reverse_recursive(first.next);
ret.Add(createNode(first.data));
return ret;
}
}
private Node createNode(Object data)
{
Node node = new Node(data);
return node;
}
public void reverse_recursive()
{
if (head != null)
{
LinkedList aux = p_reverse_recursive(head);
head = aux.head;
tail = aux.tail;
}
}
}
Hope it helps
A second variant
private void p_reverse_recursive2(Node node)
{
if (node != null)
{
Node aux = node.next;
node.next = null;
p_reverse_recursive2(aux);
if (aux != null)
aux.next = node;
}
}
public void reverse_recursive()
{
if (head != null)
{
Node aux = head;
head = tail;
tail = aux;
p_reverse_recursive2(tail);
}
}
Variation on a theme...
public Node Reverse(Node head)
{
if(head == null)
{
return null;
}
Node reversedHead = null;
ReverseHelper(head, out reversedHead);
return reversedHead;
}
public Node ReverseHelper(Node n, out Node reversedHead)
{
if(n.Next == null)
{
reversedHead = n;
return n;
}
var reversedTail = ReverseHelper(n.Next, out reversedHead);
reversedTail.Next = n;
n.Next = null;
return n;
}
}
I was just playing with similar brain teaser with the only difference that LinkedList class only has a definition for head and all the rest of the nodes are linked there. So here is my quick and dirty recursive solution:
public Node ReverseRecursive(Node root)
{
Node temp = root;
if (root.next == null)
return root;
else
root = ReverseRecursive(root.next);
temp.next = null;
Node tail = root.next;
if (tail == null)
root.next = temp;
else
while (tail != null)
{
if (tail.next == null)
{
tail.next = temp;
break;
}
else
tail = tail.next;
}
return root;
}
I am building a WPF Application which contains three ListBox elements bound to either an ISet, SortedSet or custom class (not sure). I came to this conclusion based on former Java experience and because I require the following constraints:
Needs to sort on add, keeping performance in mind
No duplicates should be included
After visiting MSDN to see which interfaces ObservableCollection uses, I figured I would do something like this:
public class ObservableSortedSet<T> : SortedSet<T>, INotifyCollectionChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
public override bool Add(T item)
{
bool result = base.Add(item);
OnCollectionChanged(NotifyCollectionChangedAction.Add);
return true;
}
private void OnCollectionChanged(NotifyCollectionChangedAction action)
{
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(action));
}
}
The ObservableCollection class in .NET inspired me to make an ObservableSortedSet, but apparently in C# you use virtual, override, and new keywords, so since SortedSet doesn't have a virtual add method, I cannot do it like above. So my question now is how would I make a SortedSet or what .NET class would provide the features I need? I suppose I could create my own SortedSet class, but that seems like something that should be in the .NET framework.
UPDATE
If anyone wants something like I described above, I went ahead and made one. I have been using it in my project for a while and it seems quite stable. I took a linked list implementation I made a long time ago and tailored it to work as a sorted set. This allows me to preform sorts fast.
Here's the code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
namespace Conquest.Collections {
public class OrderedSet<T> : IEnumerable<T>, INotifyCollectionChanged where T : IComparable<T> {
private Node<T> head;
private Node<T> tail;
public OrderedSet() {
Count = 0;
}
public OrderedSet(IEnumerable<T> enumerable) {
Count = 0;
foreach (T element in enumerable)
Add(element);
}
public T First {
get { return (head == null) ? default(T) : head.Datum; }
}
public T Last {
get { return (tail == null) ? default(T) : tail.Datum; }
}
public int Count { get; private set; }
public IEnumerator<T> GetEnumerator() {
return new OrderedSetEnumerator<T>(this);
}
IEnumerator IEnumerable.GetEnumerator() {
return new OrderedSetEnumerator<T>(this);
}
private void InsertNodeBefore(Node<T> insertingNode, Node<T> here) {
insertingNode.Next = here;
insertingNode.Previous = here.Previous;
if (here == head)
head = insertingNode;
else
here.Previous.Next = insertingNode;
here.Previous = insertingNode;
insertingNode.Index = here.Index;
for (Node<T> n = here; n != null; n = n.Next)
n.Index++;
}
private void InsertNodeAfter(Node<T> insertNode, Node<T> here) {
insertNode.Previous = here;
insertNode.Next = here.Next;
if (here == tail)
tail = insertNode;
else
here.Next.Previous = insertNode;
here.Next = insertNode;
insertNode.Index = here.Index + 1;
for (Node<T> n = insertNode.Next; n != null; n = n.Next)
n.Index++;
}
private bool IsNodeSorted(Node<T> node) {
if (Count == 1)
return true;
return (node == head && node.Next.Datum.CompareTo(node.Datum) > 0) ||
(node == tail && node.Previous.Datum.CompareTo(node.Datum) < 0) ||
(node != tail && node != head && node.Next.Datum.CompareTo(node.Datum) > 0 &&
node.Previous.Datum.CompareTo(node.Datum) < 0);
}
private void RemoveNode(Node<T> node) {
if (node == head)
head = node.Next;
else
node.Previous.Next = node.Next;
if (node == tail)
tail = node.Previous;
else
node.Next.Previous = node.Previous;
for (Node<T> n = node.Next; n != null; n = n.Next)
n.Index--;
Count--;
}
private void SortNodeLeft(Node<T> node) {
// Unlink
RemoveNode(node);
Count++;
for (Node<T> currentNode = node.Previous; currentNode != null; currentNode = currentNode.Previous) {
int compareResult = currentNode.Datum.CompareTo(node.Datum);
if (compareResult < 0) {
// Link
InsertNodeAfter(node, currentNode);
return;
}
}
InsertNodeBefore(node, head);
}
private void SortNodeRight(Node<T> node) {
// Unlink
RemoveNode(node);
Count++;
for (Node<T> currentNode = node.Next; currentNode != null; currentNode = currentNode.Next) {
int compareResult = currentNode.Datum.CompareTo(node.Datum);
if (compareResult > 0) {
// Link
InsertNodeBefore(node, currentNode);
return;
}
}
InsertNodeAfter(node, tail);
}
public bool Add(T item) {
var node = new Node<T>(item);
int index = 0;
if (head == null) {
head = node;
tail = head;
}
else {
for (Node<T> currentNode = head; currentNode != null; currentNode = currentNode.Next, index++) {
int compareResult = currentNode.Datum.CompareTo(item);
if (compareResult == 0)
return false;
else if (compareResult > 0) {
InsertNodeBefore(node, currentNode);
break;
}
// if so, make node the new tail
else if (currentNode == tail) {
InsertNodeAfter(node, tail);
index++;
break;
}
}
}
Count++;
NotifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
node.Index = index;
node.PropertyChanged += Sort;
return true;
}
/// <summary>
/// If the nodes datum changes state, this function ensures
/// the set remains sorted.
/// </summary>
/// <param name="sender">The node</param>
/// <param name="e">The property that changed</param>
private void Sort(object sender, PropertyChangedEventArgs e) {
var node = (Node<T>) sender;
int index = node.Index;
// Check if node is still in correct spot
if (IsNodeSorted(node))
return;
if (node.Previous == null || (node.Previous.Datum.CompareTo(node.Datum) < 0))
SortNodeRight(node);
else
SortNodeLeft(node);
NotifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, node.Datum,
node.Index, index));
}
public bool Remove(T item) {
if (head == null)
return false;
for (Node<T> node = head; node != null; node = node.Next) {
if (node.Datum.CompareTo(item) == 0) {
RemoveNode(node);
NotifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,
item, node.Index));
return true;
}
}
return false;
}
#region INotifyCollectionChanged
public event NotifyCollectionChangedEventHandler CollectionChanged;
private void NotifyCollectionChanged(NotifyCollectionChangedEventArgs args) {
if (CollectionChanged != null)
CollectionChanged(this, args);
}
#endregion
#region Enumerator
private class OrderedSetEnumerator<U> : IEnumerator<U> where U : IComparable<U> {
private readonly OrderedSet<U> set;
private OrderedSet<U>.Node<U> current;
public OrderedSetEnumerator(OrderedSet<U> set) {
this.set = set;
current = null;
}
public U Current {
get { return (current == null) ? default(U) : current.Datum; }
}
Object IEnumerator.Current {
get { return (current == null) ? null : (Object) current.Datum; }
}
public bool MoveNext() {
current = current == null ? set.head : current.Next;
return (current != null);
}
public void Reset() {
current = null;
}
public void Dispose() {
current = null;
}
}
#endregion
private class Node<U> : INotifyPropertyChanged {
public Node(U datum) {
Datum = datum;
var flagObserveChanges = datum as INotifyPropertyChanged;
if (flagObserveChanges != null)
flagObserveChanges.PropertyChanged += NotifySet;
}
public Node<U> Next { get; set; }
public Node<U> Previous { get; set; }
public int Index { get; set; }
public U Datum { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifySet(object sender, PropertyChangedEventArgs e) {
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
}
}
And of course I made some test cases, simple ones, so you might want to expand :)
using System.Linq;
using Conquest.Collections;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.ComponentModel;
using System;
namespace Conquest.Test.Collections
{
[TestClass]
public class OrderedSetTest
{
private class Department : INotifyPropertyChanged, IComparable<Department> {
private string name;
public string Name {
get { return name; }
set {
name = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public int CompareTo(Department other) {
return String.Compare(this.Name, other.Name, StringComparison.OrdinalIgnoreCase);
}
}
[TestMethod]
public void TestAddSingleItem()
{
var set = new OrderedSet<int> {1};
Assert.AreEqual(set.First, 1, "Head points to correct location");
Assert.AreEqual(set.Count, 1, "Correct Size");
Assert.AreEqual(set.Last, 1, "Tail points to correct location");
}
[TestMethod]
public void TestAddHead()
{
var set = new OrderedSet<int> {2, 1};
Assert.AreEqual(set.First, 1, "Head points to correct value");
}
[TestMethod]
public void TestAddTail()
{
var set = new OrderedSet<int> {1, 2};
Assert.AreEqual(set.Last, 2, "Tail points to correct value");
Assert.AreEqual(set.Count, 2, "Correct Size");
}
[TestMethod]
public void TestAddDuplicationItems()
{
var set = new OrderedSet<int> {1, 1};
Assert.IsTrue(1 == set.Count);
}
[TestMethod]
public void TestAddMultipleItems()
{
var set = new OrderedSet<int> {3, 2, 4, 1, 5};
int expected = 1;
bool worked = true;
foreach (int i in set)
{
if (i != expected)
{
worked = false;
break;
}
expected++;
}
Assert.IsTrue(worked, "Multiple Items");
}
[TestMethod]
public void TestRemoveSingleItem()
{
var set = new OrderedSet<int> {1};
set.Remove(1);
Assert.AreEqual(set.Count, 0, "Removed single item");
Assert.AreEqual(set.First, 0, "Head does not point to anything");
Assert.AreEqual(set.Last, 0, "Tail does not point to anything");
}
[TestMethod]
public void TestRemoveHead()
{
var set = new OrderedSet<int> {1, 2};
set.Remove(1);
Assert.AreEqual(set.Count, 1, "Removed head with more than one item in set");
Assert.AreEqual(set.First, 2, "Head points to the next value in set");
}
[TestMethod]
public void TestRemoveTail()
{
var set = new OrderedSet<int> {1, 2};
set.Remove(2);
Assert.AreEqual(set.Count, 1, "Removed tail with more than one item in set");
Assert.AreEqual(set.Last, 1, "Tail points to the previous value in set");
}
[TestMethod]
public void TestRemoveItem()
{
var set = new OrderedSet<int> {1, 2, 3};
Assert.IsTrue(set.Remove(2), "Remove correct value");
Assert.IsTrue(set.Count == 2, "Removed item");
int sum = set.Sum();
Assert.AreEqual(4, sum, "Remove correctly relinked adjacent nodes");
}
[TestMethod]
public void TestSortOnAdd()
{
var test = new Queue<int>();
for (int i = 0; i < 10; i++)
test.Enqueue(i);
var set = new OrderedSet<int> {5, 4, 3, 7, 2, 8, 1, 9, 0, 6};
var worked = set.All(i => i == test.Dequeue());
Assert.IsTrue(worked, "Sorted on Add");
}
[TestMethod]
public void TestSortOnEdit()
{
var dep1 = new Department
{
Name = "Test"
};
var dep2 = new Department
{
Name = "Test2"
};
var set = new OrderedSet<Department> {dep1, dep2};
dep2.Name = "Hello";
var e = set.GetEnumerator();
e.MoveNext();
Assert.AreEqual("Hello", e.Current.Name, "Swaped tail to head on edit");
dep1.Name = "Abc";
e = set.GetEnumerator();
e.MoveNext();
Assert.AreEqual("Abc", e.Current.Name, "Verified integrity of node linkage");
var dep3 = new Department
{
Name = "Test3"
};
set.Add(dep3);
dep3.Name = "Cat";
e = set.GetEnumerator();
e.MoveNext();
bool correctOrder = e.Current.Name == "Abc";
e.MoveNext();
correctOrder = correctOrder && e.Current.Name == "Cat";
Assert.IsTrue(correctOrder, "Moved item to the left");
dep1.Name = "Dad";
e = set.GetEnumerator();
e.MoveNext();
correctOrder = e.Current.Name == "Cat";
e.MoveNext();
correctOrder = correctOrder && e.Current.Name == "Dad";
Assert.IsTrue(correctOrder, "Moved item to the right");
}
}
}
You can change your class to have this declaration...
public class ObservableSortedSet<T> : INotifyCollectionChanged, ISet<T>
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
private readonly SortedSet<T> _sortedSet;
public ObservableSortedSet()
{
_sortedSet = new SortedSet<T>();
}
public bool Add(T item)
{
bool result = _sortedSet.Add(item);
OnCollectionChanged(NotifyCollectionChangedAction.Add);
return true;
}
private void OnCollectionChanged(NotifyCollectionChangedAction action)
{
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(action));
}
// all the rest of ISet implementation goes here...
}
This approach, although more verbose and arguably overkill, will give the behaviour you are after. The coding drill should take about 20 minutes.
I am seeing following errors :
Object reference not set to an instance of an object!
Check to determinate if the object is null before calling the method!
I made a small test program for Sorted Linked Lists.
Here is the code where the error comes!
public void Insert(double data)
{
Link newLink = new Link(data);
Link current = first;
Link previous = null;
if (first == null)
{
first = newLink;
}
else
{
while (data > current.DData && current != null)
{
previous = current;
current = current.Next;
}
previous.Next = newLink;
newLink.Next = current;
}
}
It says that the current referenc is null while (data > current.DData && current != null), but I assigned it: current = first;
The rest is the complete code of the Program!
class Link
{
double dData;
Link next=null;
public Link Next
{
get { return next; }
set { next = value; }
}
public double DData
{
get { return dData; }
set { dData = value; }
}
public Link(double dData)
{
this.dData = dData;
}
public void DisplayLink()
{
Console.WriteLine("Link : "+ dData);
}
}
class SortedList
{
Link first;
public SortedList()
{
first = null;
}
public bool IsEmpty()
{
return (this.first == null);
}
public void Insert(double data)
{
Link newLink = new Link(data);
Link current = first;
Link previous = null;
if (first == null)
{
first = newLink;
}
else
{
while (data > current.DData && current != null)
{
previous = current;
current = current.Next;
}
previous.Next = newLink;
newLink.Next = current;
}
}
public Link Remove()
{
Link temp = first;
first = first.Next;
return temp;
}
public void DisplayList()
{
Link current;
current = first;
Console.WriteLine("Display the List!");
while (current != null)
{
current.DisplayLink();
current = current.Next;
}
}
}
class SortedListApp
{
public void TestSortedList()
{
SortedList newList = new SortedList();
newList.Insert(20);
newList.Insert(22);
newList.Insert(100);
newList.Insert(1000);
newList.Insert(15);
newList.Insert(11);
newList.DisplayList();
newList.Remove();
newList.DisplayList();
}
}
You are perhaps assuming that the while loop is breaking on the first iteration which it's not it's the assignment in the while loop that eventually breaks it.
Eventually current is NULL based on your code, you even test for it - change it to this and it should be fine:
while (current != null && data > current.DData)
{
previous = current;
current = current.Next;
}
Agree that you have done
current = first;
but then the beginning of your class first is null
class SortedList
{
Link first;
please assign something to first else it will be null
class Node
{
public int data;
public Node left, right;
public Node(int data)
{
this.data = data;
left = null;
right = null;
}
}
class BinaryTreeImp
{
Node root;
static int count = 0;
public BinaryTreeImp()
{
root = null;
}
public Node addNode(int data)
{
Node newNode = new Node(data);
if (root == null)
{
root = newNode;
}
count++;
return newNode;
}
public void insertNode(Node root,Node newNode )
{
Node temp;
temp = root;
if (newNode.data < temp.data)
{
if (temp.left == null)
{
temp.left = newNode;
}
else
{
temp = temp.left;
insertNode(temp,newNode);
}
}
else if (newNode.data > temp.data)
{
if (temp.right == null)
{
temp.right = newNode;
}
else
{
temp = temp.right;
insertNode(temp,newNode);
}
}
}
public void displayTree(Node root)
{
Node temp;
temp = root;
if (temp == null)
return;
displayTree(temp.left);
System.Console.Write(temp.data + " ");
displayTree(temp.right);
}
static void Main(string[] args)
{
BinaryTreeImp btObj = new BinaryTreeImp();
Node iniRoot= btObj.addNode(5);
btObj.insertNode(btObj.root,iniRoot);
btObj.insertNode(btObj.root,btObj.addNode(6));
btObj.insertNode(btObj.root,btObj.addNode(10));
btObj.insertNode(btObj.root,btObj.addNode(2));
btObj.insertNode(btObj.root,btObj.addNode(3));
btObj.displayTree(btObj.root);
System.Console.WriteLine("The sum of nodes are " + count);
Console.ReadLine();
}
}
This is the code for implementation.The code works fine but if in the displayTree function , i replace it with
public void displayTree(Node root)
{
Node temp;
temp = root;
while(temp!=null)
{
displayTree(temp.left);
System.Console.Write(temp.data + " ");
displayTree(temp.right);
}
}
an infinite loop is caused. I don't understand what is causing this.Also i would like to know if there is a better way of implementing a BST in C#.
I'm not sure why you need this loop, but answering your question:
while(temp!=null)
{
displayTree(temp.left);
System.Console.Write(temp.data + " ");
displayTree(temp.right);
}
this code checks if temp is not null, but it will never become null, cause inside the loop you act only on the leafs of the temp. That's why you have an infinit loop.
You don't need a while loop nor a temp variable, let recursion do the work for you:
public void displayTree(Node root)
{
if(root == null) return;
displayTree(root.left);
System.Console.Write(root.data + " ");
displayTree(root.right);
}
temp is set to root at the beginning, and after that its value never changes
what about rewriting your function as
public void displayTree(Node root)
{
if (root == null)
return;
displayTree(root.left);
Console.Write(...);
displayTree(root.right);
}
try this
public void displayTree(Node root)
{
Node temp;
temp = root;
if (temp != null)
{
displayTree(temp.left);
Console.WriteLine(temp.data + " ");
displayTree(temp.right);
}
}
I was just thinking that you as well also could use recursion for the add function. It could look something like this
private void Add(BinaryTree node, ref BinaryTree rootNode)
{
if (rootNode == null)
{
rootNode = node;
}
if (node.value > rootNode.value)
{
Add(node, ref rootNode.right);
}
if (node.value < rootNode.value)
{
Add(node, ref rootNode.left);
}
}
See https://msdn.microsoft.com/en-us/library/ms379572%28v=vs.80%29.aspx.
See the example code in the section "Traversing the Nodes of a BST"
Also... don't forget to check out SortedDictionary, etc. They may have the BST that you need all ready to go! https://msdn.microsoft.com/en-us/library/f7fta44c.aspx
Complete Binary Search Tree ... With Code to check whether Tree is balanced or not
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace BinarySearchTree
{
public class Node
{
public Node(int iData)
{
data = iData;
leftNode = null;
rightNode= null;
}
public int data{get; set;}
public Node leftNode{get; set;}
public Node rightNode{get; set;}
};
public class Program
{
public static Node root = null;
public static void Main(string[] args)
{
//Your code goes here
Console.WriteLine("Hello, world!");
root = new Node(20);
InsertNode(root, new Node(10));
InsertNode(root, new Node(15));
InsertNode(root, new Node(13));
InsertNode(root, new Node(11));
InsertNode(root, new Node(12));
InsertNode(root, new Node(25));
InsertNode(root, new Node(22));
InsertNode(root, new Node(23));
InsertNode(root, new Node(27));
InsertNode(root, new Node(26));
if(CheckIfTreeIsBalanced(root))
{
Console.WriteLine("Tree is Balanced!");
}
else
{
Console.WriteLine("Tree is Not Balanced!");
}
PrintTree(root);
}
public static void PrintTree(Node root)
{
if(root == null) return;
Node temp = root;
PrintTree(temp.leftNode);
System.Console.Write(temp.data + " ");
PrintTree(temp.rightNode);
}
public static bool CheckIfTreeIsBalanced(Node root)
{
if(root != null)
{
if(root.leftNode != null && root.rightNode!= null)
{
if(root.leftNode.data < root.data && root.rightNode.data > root.data)
{
return CheckIfTreeIsBalanced(root.leftNode)&&CheckIfTreeIsBalanced(root.rightNode);
}
else
{
return false;
}
}
else if(root.leftNode != null)
{
if(root.leftNode.data < root.data)
{
return CheckIfTreeIsBalanced(root.leftNode);
}
else
{
return false;
}
}
else if(root.rightNode != null)
{
if(root.rightNode.data > root.data)
{
return CheckIfTreeIsBalanced(root.rightNode);
}
else
{
return false;
}
}
}
return true;
}
public static void InsertNode(Node root, Node newNode )
{
Node temp;
temp = root;
if (newNode.data < temp.data)
{
if (temp.leftNode == null)
{
temp.leftNode = newNode;
}
else
{
temp = temp.leftNode;
InsertNode(temp,newNode);
}
}
else if (newNode.data > temp.data)
{
if (temp.rightNode == null)
{
temp.rightNode = newNode;
}
else
{
temp = temp.rightNode;
InsertNode(temp,newNode);
}
}
}
}
}
Output :
Hello, world!
Tree is Balanced!
10 11 12 13 15 20 22 23 25 26 27