How to solve Josephus Elimination using Circular linked list - c#

class Node
{
public int Data { get; set; }
public Node Next { get; set; }
public int Counter { get; set; }
public Node(int element,int counter)
{
Data = element;
Counter = counter;
Next=null;
}
}
I use counter as a TAG on person, or in other words the position from which elimination starts.
class CircularLinkedList
{
Node first;
Node last;
public CircularLinkedList()
{
first = last = null;
}
protected void Insert(int element,int counter)
{
if (IsEmpty())
{
first = last = new Node(element,counter);
}
else
{
last.Next = last = new Node(element,counter);
last.Next = first;
}
}
public int RemoveAt(int index)
{
int value = 0;
Node current = first;
do
{
if (current.Counter == index)
{
value = current.Data;
}
current = current.Next;
} while (current != first);
return value;
}
public void AddMen(int n)
{
for (int i = 1; i <= n; i++)
{
Insert(i*2,i);
}
}
public int Eliminate(int m)
{
int value = 0;
Node current = first;
do
{
value = RemoveAt(m);
current = current.Next;
} while (current != first);
return value;
}
public bool IsEmpty()
{
return first == null;
}
public void Display()
{
Node current = first;
do
{
Console.WriteLine(current.Counter+" "+current.Data+" ");
current = current.Next;
} while (current!=first);
}
}
I am having problem with elimination method, I want it must be constantly called until the list is empty,

I would do:
public int Eliminate(int m)
{
int value = 0;
Node current = first;
Node nextNode;
do
{
nextNode = current.next;
value = RemoveAt(m);
current = nextNode;
} while (current != first);
return value;
}

Related

How to modify my CustLinkedList to implement insert more efficiently

I created a custom linked list on a whiteboard, for learning purposes.
CustDoublyLinkedList class with the nested Node class, but when it is time to insert, at the specified index method must loop through until it get to an index to insert. I want to insert directly without using loop as my Add or PushFront methods work.
I also added some more method like IndexOf and Contain methods for the list
CustDoublyLinkedList<int> myList = new();
myList.Add(12);
myList.Add(13);
myList.Add(14);
myList.Add(45);
myList.Add(28);
myList.Add(120);
myList.PushFront(32);
myList.Insert(3,1500);
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i]);
}
class CustDoublyLinkedList<T>
{
private class Node
{
public T Element { get; set; }
public Node NextNode { get; set; }
public Node PrevNode { get; set; }
public Node(T data)
{
this.Element = data;
this.PrevNode = null;
this.NextNode = null;
}
public Node(T data, Node prevNode): this(data)
{
prevNode.NextNode = this;
}
public Node(T data, Node prevNode, Node nextNode) : this(data, prevNode)
{
nextNode.PrevNode = this;
}
}
private Node head;
private Node tail;
private int counter;
public CustDoublyLinkedList()
{
this.head = null;
this.tail = null;
this.counter = 0;
}
public void Insert(int index, T item)
{
if (index == 0)
{
throw new ArgumentOutOfRangeException("You Can Push with PushFront Method at Index: " + index);
}
if (index < 0 || index >= this.counter)
{
throw new ArgumentOutOfRangeException("invalid Index: " + index);
}
Node newNode = new(item);
Node currentNode = this.head;
for (int i = 0; i < index - 1; i++)
{
currentNode = currentNode.NextNode;
}
newNode.NextNode = currentNode.NextNode;
newNode.PrevNode = currentNode.PrevNode;
currentNode.NextNode = newNode;
this.counter++;
}
public void Add(T item)
{
if (this.head == null)
{
this.head = new(item);
this.tail = this.head;
}
else
{
Node newNode = new(item, this.tail);
this.tail = newNode;
}
this.counter++;
}
public void PushFront(T item)
{
Node newNode = new(item);
newNode.NextNode = this.head;
newNode.PrevNode = null;
if(this.head != null)
{
this.head.PrevNode = newNode;
}
this.head = newNode;
this.counter++;
}
public bool Contain(T item)
{
int index = IndexOf(item);
if (index != -1)
{
return true;
}
return false;
}
public int IndexOf(T item)
{
Node currentNode = this.head;
int index = 0;
while(currentNode != null)
{
if (object.Equals(currentNode.Element, item))
{
return index;
}
currentNode = currentNode.NextNode;
index++;
}
return -1;
}
public int Count
{
get { return this.counter; }
}
public T this[int index]
{
get
{
if (index < 0 || index >= this.counter)
{
throw new IndexOutOfRangeException("Invalid Index: " + index);
}
Node currentNode = this.head;
for (int i = 0; i < index; i++)
{
currentNode = currentNode.NextNode;
}
return currentNode.Element;
}
set
{
if (index < 0 || index >= this.counter)
{
throw new IndexOutOfRangeException("Invalid Index: " + index);
}
Node currentNode = this.head;
for (int i = 0; i < index; i++)
{
currentNode = currentNode.NextNode;
}
currentNode.Element = value;
}
}
}
You are looking for a Skip List
With this you can drive your insert requirement to O(log N) on average while still maintaining a linked list structure

How to add an element at an index in singly linked list in C#

I am implementing linked-list data-structure in C#. I am facing below issue.
When I am try to add element at an index in singly linked list then it not working.
below is my code. Issue is in function AddToIndex. It is not working properly.
Node
public class DNode
{
public int data;
public DNode next;
public DNode(int d)
{
data = d;
}
}
LinkedList
public class DLinkedList
{
public int data;
public DNode Next { get; set; }
public DNode Head { get; private set; }
public DNode Tail { get; private set; }
public int Count { get; set; }
public void AddToHead(int element)
{
DNode temp = new DNode(element);
temp.next = Head;
Head = temp;
Count++;
if (Count == 1)
{
Tail = Head;
}
}
public void AddToIndex(int element, int index)
{
DNode temp = new DNode(element);
for (int i = 1; i < index - 1; i++)
{
Head = Head.next;
}
temp.next = Head;//in this case infinite link list
//temp.next = Head.next; in this case one element is removed.
Head.next = temp; // whole link list is not created, partial linked list created
}
public void Display()
{
DNode temp = Head;
while (temp != null)
{
System.Console.WriteLine(temp.data);
temp = temp.next;
}
}
}
To display result set
static class Program
{
static void Main(string[] args)
{
DLinkedList dLinked = new DLinkedList();
dLinked.AddToHead(5);
dLinked.AddToHead(7);
dLinked.AddToHead(10);
dLinked.AddToHead(11);
Console.WriteLine("---Add Head---");
dLinked.Display();
dLinked.AddToIndex(12, 4);
Console.WriteLine("---After AddToIndex function");
dLinked.Display();
}
}
Result on Console:
---Add Head---
11
10
7
5
---After AddToIndex function Called --
7
12
5
Note: I am just building this no test cases is run .
you are modifying the head of the linked list, which should not be done. try taking another temp variable and assign it to head. like the code below.
public void AddToIndex(int element, int index)
{
DNode temp = new DNode(element);
DNode temp1=Head;
for (int i = 1; i < index - 1; i++)
{
temp1 = temp1.next;
}
temp.next=temp1.next
temp1.next=temp
}

How to avoid out of memory using trie by C#

how to write billions of data into a trie with less memory
I want to extract some infomation from news like company names,so I write billions of company names into a trie,but it needs much memory and throw out of memory exception,I don't know how to solve it,so anyone can help,thanks in advance.
public class Node
{
public char Value { get; set; }
public List<Node> Children { get; set; }
public int Depth { get; set; }
public string Code { get; set; }
public bool Terminal { get; set; }
public Node(char value, int depth)
{
Value = value;
Depth = depth;
Children = new List<Node>();
}
public Node FindChildNode(char c)
{
foreach (var child in Children)
if (child.Value == c)
return child;
return null;
}
}
public class Trie
{
private Node _root;
public Trie()
{
_root = new Node('^',0);
}
public Node Prefix(string s)
{
var currentNode = _root;
var result = currentNode;
foreach (var c in s)
{
currentNode = currentNode.FindChildNode(c);
if (currentNode == null)
break;
result = currentNode;
}
return result;
}
public void Insert(string randomLength,string code)
{
var commonPrefix = Prefix(randomLength);
var current = commonPrefix;
for (var i = current.Depth; i < s.Length; i++)
{
var newNode = new Node(s[i], current.Depth + 1);
if (i+1==s.Length)
{
newNode.Terminal = true;
newNode.Code = code;
}
current.Children.Add(newNode);
current = newNode;
}
}
}
Trie t=new Trie();
t.Insert("C","ABCG00DFD");
The aboved statement run 1000000000 Loops and the "C" can be replaced with different string with different length,as the loops increasing,it throw out of memory exception,so how to avoid or change it?
Have a go at this Trie and see if you can get it to work for what you need:
public class Trie : Dictionary<char, Trie>
{
public void Add(string value)
{
var c = String.IsNullOrEmpty(value) ? '\0' : value[0];
if (!this.ContainsKey(c))
{
this[c] = new Trie();
}
if (c != '\0')
{
this[c].Add(value.Substring(1));
}
}
}

Endless loop IntNode

before showing the issue, look at the IntNode class:
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 (this.next != null);
}
public override string ToString()
{
if (this.HasNext())
return this.value + " --> " + this.next;
else
return this.value + ". [end]";
}
}
I have the following function:
static IntNode Sort (IntNode head)
{
IntNode pos = head.next;
IntNode current = head;
IntNode prev = head;
bool changed = false;
while (current != null)
{
while (pos != null)
{
if (current.value > pos.value)
{
if (pos.HasNext()) current.next = pos.next;
else prev.next = pos;
pos.next = current;
changed = true;
if (current.next.HasNext())
pos = current.next.next;
break;
}
pos = pos.next;
}
if (!changed)
{
current.next = head;
head = current;
}
prev = current;
current = current.next;
changed = false;
}
return head;
}
But when I am launching the program (with given parameters) it is not responding (a "-" appears and disappears) I dont know why it is like that and I am sitting on this a hour...
The purpose of the program is to a list and sort it from smaller to bigger and than return the edited list (dont create another list).
For Example:
Given list:
6,-4,5,0
Output:
-4,0,5,6
Thanks!
I can see several issues with how your bubble sort is written. If you don't have a debugger it will be difficult to debug manually. Here is an insertion sort that may do the trick for you and be easier to trace mentally. It finds the lowest value and moves it to a different list.
static IntNode Sort (IntNode head)
{
IntNode resultTail = null;
IntNode resultHead = null;
IntNode current = head;
IntNode lowestPrev = null;
IntNode lowest = head;
while (head != null)
{
lowestPrev = null;
current = head;
while (current != null)
{
if (current.value < lowest.value)
{
lowest = current;
lowestPrev = prev;
}
prev = current
current = current.next;
}
if (resultHead = null)
{
resultHead = lowest;
resultTail = lowest;
}
else
resultTail.next = lowest;
if (lowest == head)
head = head.next;
else
lowestPrev.next = lowest.next;
}
return resultHead;
}

Doubly LinkedList traversing

I have write a C# code to insert data to a doubly linked list and to delete a node. It is working and I can traverse the list from last node to first. But I can not traverse the list from first node to the last. I can not find the mistake I have made. Following is my code.
class Node
{
public string data { get; set; }
public Node next { get; set; }
public Node previous { get; set; }
public Node(string data)//first node)
{
this.data = data;
this.next = null;
this.previous = null;
}
public Node(string data, Node next,Node previous)
{
this.data = data;
this.next = next;
this.previous = previous;
}
}
class doublyLinkedList
{
private Node first;
private Node last;
private int size;
public doublyLinkedList()
{
this.first = null;
this.last = null;
this.size = 0;
}
public bool isEmpty
{
get { return this.size == 0; }
}
public int count
{
get { return this.size; }
}
public void Add(string o)
{
Node current = this.last;
if (this.isEmpty)
{
this.first = new Node(o);
this.last = new Node(o);
}
else
{
current.next = new Node(o, current.next,current);
last = current.next;
Console.WriteLine("first " + first.data + "last " + last.data + "previous " + last.previous.data);
}size++;
}
public object getFirst()
{
return first.data;
}
public string remove()
{
Node current = this.last;
current.previous.next = null;
object removedElement = current.data;
string reEle = ((String)(removedElement).ToString());
current = current.previous;
size--;
return reEle;
}
public void TraverseFront()
{
Node current = this.first;
string str = current.data;
Console.WriteLine("first " + str);
Node current1 = first.next;
string str1 = first.next.data;
string question = str + str1;
Console.WriteLine(question)
}
}
Your problem is when you insert the first object. You need to set last to the same instance as first, as at the moment you are disconnecting the first object (this.first.next is always null), change it from:
this.last = new Node(o);
to:
this.last = this.first;

Categories