Traversing a linked-list - c#

I created a simple node class, and solution class with an insert method, a display method, along with Main. I am trying to insert 4 numbers into the linked-list and have it display the entire list. At most I am only able to have it display 2 of the numbers. The issue is most likely in my insert method. I've spent hours trying to figure out what the issue is. What could be wrong with my code?
public static Node insert(Node head, int data)
{
Node newNode = new Node(data);
if (head == null)
{
head = newNode;
}
else
{
while (head.next != null)
{
head = head.next;
}
head.next = newNode;
}
return head;
}
public static void display(Node head)
{
Node start = head;
while (start != null)
{
Console.Write(start.data + " ");
start = start.next;
}
}
static void Main(String[] args)
{
Node head = null;
int[] numbers = new int[]{2, 3, 4, 1};
for (int i = 0; i < numbers.Length; i++)
{
int data = numbers[i];
head = insert(head, data);
}
display(head);
Console.ReadLine();
}
class Node
{
public int data;
public Node next;
public Node(int d)
{
data = d;
next = null;
}
public Node() { }
}

Yes, the problem is in the insert method:
while (head.next != null)
{
// From now on you have the initial head got lost
head = head.next;
}
Quick amendment is to change while into for:
public static Node insert(Node head, int data) {
Node newNode = new Node(data);
if (head == null) {
head = newNode;
}
else {
// we loop on last, keeping head intact
for (Node last = head; ; last = last.next)
if (last.next == null) {
last.next = newNode;
break;
}
}
return head;
}
we can simplify it further:
public static Node insert(Node head, int data) {
Node newNode = new Node(data);
for (Node last = head; last != null; last = last.next)
if (last.next == null) {
last.next = newNode;
return head;
}
return newNode;
}

Related

How can i implement a pop method for a generic stack without traversing the list

I have a generic stack that I will use in a console application. I need the stack to behave like a .Net stack but with extra functionality. Below is part of the code for the stack
class DynamicGenericStack<T>
{
private class Node
{
public T element { get; private set; }
public Node Next { get; set; }
public Node(T element, Node prevNode)
{
this.element = element;
Next = null;
Previous = null;
if (prevNode != null) //if this is not the first node
prevNode.Next = this;
}
}
private Node head, tail;
public int Count { get; private set; } //Count
public DynamicStack()
{
this.head = null;
this.tail = null;
this.Count = 0;
}
public void Push(T item)
{
if (this.head == null)
this.head = this.tail = new Node(item, null);
else
tail = new Node(item, tail);
Count++;
} Push
public T Peek()
{
return tail.element;
} Peek
public T Pop()
{
if (Count > 0)
{
T item = tail.element;
Node prev = null, current = head;
while (current != tail)
{
prev = current;
current = current.Next;
}
tail = prev;
Count--;
return item;
}
return default(T);
}
}
How can I implement the pop method above to remove the tail node without having to traverse the entire list as I did in the above code using the while loop? Is there any way in which track the tail node and remove it directly?
A single linked list is good enough for a stack, and only a head reference is needed.
To push onto the stack:
create new_node
new_node.next = head;
head = new_node;
count++;
To pop from the stack:
if(count == 0)
return null;
tmp_node = head;
head = head.next;
count--;
return tmp_node.element;
In a stack you are not really interested in the bottom. You have three main methods:
push: adds a new item over the top
pop: removes the top
top: reads the top
Change 1: next -> prev
You will need to always track what the top is and therefore you will need to know what are the previous elements.
public Node Prev { get; set; }
Change 2: Apply the same idea for Node constructor
public Node(T element, Node prevNode)
{
this.element = element;
Next = null;
Previous = null;
if (prevNode != null) //if this is not the first node
prevNode.Prev = this;
}
Change 3: Apply this logic at Pop
public T Pop()
{
T element = default(T);
if (Count > 0)
{
element = tail.element;
if (tail.Prev != null) {
tail = tail.Prev;
} else {
head = tail = null;
}
}
return element;
}

AddFront in LinkedList with tail and reference to previous node from the tail (tail.Previous)

Could you please help to understand, how I can modify AddFront method in LinkedList and set a tail and reference to the previous node (for example tail.Previous)? The tail should point out the first added element (last element in the LinkedList) and tail.Previous to second added element (second element from the end) and be able to access elements from tail to the head using Previous property.
Thanks.
public class Node
{
public int Data;
public Node Next;
public Node Previous;
public Node(int x)
{
Data = x;
Next = null;
Previous = null;
}
public class MyLinkedList
{
private int Length { get; set; }
private Node head = null;
private Node tail = null;
public void AddFront(int x)
{
var newNode = new Node(x);
newNode.Next = head;
if (head != null)
{
head.Previous = newNode;
}
//Somewhere here tail and tail.Previous should be set
head = newNode;
Length++;
}
}
Just add the else case:
if (head != null)
{
head.Previous = newNode;
}
else
{
tail = newNode;
}

Need help to figure out the error in this search program

I have this linked list c# codes. I couldn't figure out the error for not printing any output. I have an error message saying that LinkedList.LinkedList doesn't contain a definition for PrintNodes. Can anyone pointed out why I am getting that error, and where I am doing mistake.
public class Node
{
public object data;
public Node next;
public Node(object data)
{
this.data = data;
}
}
public class LinkedList
{
Node head;
Node current;
public Node Head
{
get { return head; }
}
public void Add(Node n)
{
if (head == null)
{
head = n;
current = head;
}
else
{
current.next = n;
current = current.next;
}
}
public void MergeSortedList(Node first, Node second)
{
if (Convert.ToInt32(first.next.data.ToString())
> Convert.ToInt32(second.data.ToString()))
{
Node t = first;
first = second;
second = t;
}
head = first;
while ((first.next != null) && (second != null))
{
if (Convert.ToInt32(first.next.data.ToString())
< Convert.ToInt32(second.data.ToString()))
{
first = first.next;
}
else
{
Node n = first.next;
Node t = second.next;
first.next = second;
second.next = n;
first = first.next;
second = t;
}
}
if (first.next == null)
first.next = second;
}
static void Main()
{
LinkedList l1 = new LinkedList();
l1.Add(new Node("2"));
l1.Add(new Node("3"));
l1.Add(new Node("4"));
l1.Add(new Node("5"));
l1.Add(new Node("8"));
l1.Add(new Node("100"));
l1.Add(new Node("120"));
LinkedList l2 = new LinkedList();
l2.Add(new Node("10"));
l2.Add(new Node("30"));
l2.Add(new Node("34"));
LinkedList list = new LinkedList();
list.MergeSortedList(l1.Head, l2.Head);
list.PrintNodes();
Console.ReadLine();
}
}
}
In Main you call list.PrintNodes() but your LinkedList class has no such method defined, hence the exception, exactly as it says so:
LinkedList.LinkedList doesn't contain a definition for PrintNodes

reverse a linked list in a recursive function c#

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;
}

Is there an C# attribute that forces an operation to occur?

For example, both of these methods need to update the count variable:
public void AddFront(T data) {
Node<T> newNode = new Node<T>(data, null, null);
if (count == 0) {
head = tail = newNode;
}
else {
newNode.Next = head;
head.Previous = newNode;
head = newNode;
}
// don't forget
count++;
}
public void AddBack(T data) {
Node<T> newNode = new Node<T>(data, null, null);
if (count == 0) {
head = tail = newNode;
}
else {
newNode.Previous = tail;
tail.Next = newNode;
tail = newNode;
}
// don't forget
count++;
}
I wonder is there an attribute that can force an operation like this to occur?, otherwise it will trigger a compile-time error message.
An attribute, no. (Though I will read up on Code Contracts suggested by #Michael)
You can however refactor your code. There is quite a bit of commonality. Perhaps create a single method that accepts as an additional parameter whether to add to the head or to the tail. Something like (untested):
private void Add(T data, bool front) {
Node<T> newNode = new Node<T>(data, null, null);
if (count == 0) {
head = tail = newNode;
}
else if (front) {
newNode.Next = head;
head.Previous = newNode;
head = newNode;
else {
newNode.Previous = tail;
tail.Next = newNode;
tail = newNode;
}
// don't forget
count++;
}
public void AddFront(T data) {
Add(data, true);
}
public void AddBack(T data) {
Add(data, false);
}

Categories