public void Insert(int value)
{
if (value < Data)
{
if (LeftNode == null)
{
LeftNode = new TreeNode(value);
}
else
{
LeftNode.Insert(value);
}
}
else if (value > Data)
{
if (RightNode == null)
{
RightNode = new TreeNode(value);
}
else
{
RightNode.Insert(value);
}
}
}
I wrote method to add element in BST recursively, It checks for value to add less than or greater than and add it in its proper place, but I want to know how iterative method works? I need iterative add method for my BST.
Ok, here's an iterative version of your algorithm:
public void Insert(int value)
{
TreeNode current = this;
while (current != null)
{
if(current.Data < value)
if(current.LeftNode == null)
{ current.LeftNode = new TreeNode(value); break; }
else current = current.LeftNode;
else
if(current.RightNode == null)
{ current.RightNode = new TreeNode(value); break; }
else current = current.RightNode;
}
}
You can find a implementation in Java at wikipedia, what is very similar C# http://en.wikipedia.org/wiki/Binary_search_tree
We start at root:
Node root = m_root;
while (root != null) {
then look if the value is less os greater than root.
if (data < root.getData()) {
Now we know if we need to traverse at left or right. The logic at left and right are the same. We look if the slot is empty and if it is, we put the value at that slot.
if (root.getLeft() == null) {
root.setLeft(new TreeNode(data, null, null));
return;
}
If the slot contains a value, then we set that slot as root and continue the process.
} else {
root = root.getLeft();
}
An iterative method is one that will repeat.
Iterative method implies it will be called repeatedly.
Recursion implies the method will call itself n times, where n > 0.
Searching a binary search tree is done using a method which calls itself (recursive) until it finds the end of a branch.
To do an insert, a search is executed to find the correct place to place the node.
Related
I have multiple objects(nodes) and each node has a getter and setter for a list named Calea which contains other nodes, also each node has neighbours and they are also nodes . The problem is that list is stacking up and I can't figure out why , it's like a static variable and also I am not using that getter and setter anywhere else.
Here is my code :
private int cost = 10000;
private LinkedList<GraphNode<string>> calea=new LinkedList<GraphNode<string>>() ;
public int Cost
{
get
{
return cost;
}
set
{
cost = value;
}
}
public LinkedList<GraphNode<string>> Calea
{
get
{
if (calea == null) return new LinkedList<GraphNode<string>>();
return calea;
}
set
{
calea = value;
}
}
Code above shows the method for Cost and Calea , Cost works fine but Calea is stacking up.The code below is a sample of code of how I am setting the value Calea for each node:
if (curr.Neighbors.ElementAt(i).Cost > curr.Costs.ElementAt(i) + curr.Cost)
{
curr.Neighbors.ElementAt(i).Cost = curr.Costs.ElementAt(i) + curr.Cost;
curr.Neighbors.ElementAt(i).Calea = curr.Calea;
curr.Neighbors.ElementAt(i).Calea.AddLast((GraphNode<string>)curr.Neighbors.ElementAt(i));
index = i;
}
++i;
The sample code where I change the current node below:
pathNodesToVisit.Remove(curr);
if (pathNodesToVisit.Count == 0) break;
if (curr.Neighbors.Count > index)
{
for (int j = 0; j < pathNodesToVisit.Count; j++)
{
if (pathNodesToVisit.ElementAt(j).Value == curr.Neighbors.ElementAt(index).Value)
{
indexx = j;
//MessageBox.Show(pathNodesToVisit.ElementAt(j).Value);
}
}
curr = pathNodesToVisit.ElementAt(indexx);
}
else
{
curr = pathNodesToVisit.ElementAt(0);
}
A few words : pathNodesToVisit are all the nods which I want to visit(Dijkstra algorithm) , in the code above I remove the curr node from the list and the new curr node is a node which had the Costs and Calea changed.
I have no idea what you mean by "stacking up," but:
public LinkedList<GraphNode<string>> Calea
{
get
{
if (calea == null) return new LinkedList<GraphNode<string>>();
return calea;
}
... creates a new list every time the property is read, not just the first time. calea will always be null with this approach.
Try
get
{
if (null == calea)
calea = new LinkedList<GraphNode<string>>();
return calea;
}
Update
The line
curr.Neighbors.ElementAt(i).Calea = curr.Calea;
Does not make a copy of the list. It copies a reference to the list. Any changes made to any node's calea afterward will affect every node, not just the one you're after.
Try
curr.Neighbors.ElementAt(i).Calea = new LinkedList<GraphNode<string>>(curr.Calea);
Though, you should make sure .Neighbors actually has an element i before doing this, among other things.
Note: In the case of an uninitialized node, this will actually create two lists - once when Calea is read (LH of the expression, which calls your .get), and another on the right.
There are many ways to copy a collection. I suggest googling c# deep copy LinkedList<T>.
For a school lab I have to make a linked list of messages and then sort those messages by priority, with "High" priority being pulled out first, then medium, then low. I've been trying to figure this out for days and I can't wrap my mind around the sorting. I've been trying to get it to sort without adding anything other than a head and a size field in my ListofMessages class but all I seem to do is add garbage code. I wanted to figure this out myself but right now I'm stumped.
Here's what I have so far. Hopefully you can make sense of it:
class ListOfMessages
{
private int m_nSize;
public Message m_cListStart;
//public Message m_cNextItem;
public Message m_cLastItem;
public ListOfMessages()
{
m_nSize = 0;
m_cListStart = null;
//m_cNextItem = null;
}
public int Count
{
get { return m_nSize; }
}
public string Display(Message cMessage)
{
return "Message: " + cMessage.m_strMessage + "\nPriority: " + cMessage.m_strPriority;
}
//list additions
public int Add(Message newMessage)
{
Message nextMessage = new Message();
//inserts objects at the end of the list
if (m_nSize == 0)
{
m_cListStart = newMessage;
//m_cLastItem = newMessage;
}
else
{
Message CurrentMessage = m_cListStart;
if (newMessage.m_strPriority == "High")
{
if (m_cListStart.m_strPriority != "High")
{
//Make the object at the start of the list point to itself
CurrentMessage.m_cNext = m_cListStart;
//Replace the object at the start of the list with the new message
m_cListStart = newMessage;
}
else
{
Message LastMessage = null;
for (int iii = 0; iii < m_nSize; iii++)//(newmessage.m_strpriority == iii.m_strpriority)
//&& (iii.m_cnext == null);)
{
if (m_cListStart.m_strPriority != "High")
{
nextMessage = newMessage;
nextMessage.m_cNext =
CurrentMessage = nextMessage;
//LastMessage.m_cNext = CurrentMessage;
}
LastMessage = CurrentMessage;
if (m_cListStart.m_cNext != null)
m_cListStart = m_cListStart.m_cNext;
}
}
//iii = iii.m_cnext;
}
// for (int iii = m_cListStart; ; iii = iii.m_cNext)//(newMessage.m_strPriority == iii.m_strPriority)
// //&& (iii.m_cNext == null);)
//{
// //Message lastMessage = iii;
// if (iii.m_strPriority != iii.m_strPriority)
// {
// //iii.m_cNext = newMessage;
// newMessage.m_cNext = iii.m_cNext;
// iii.m_cNext = newMessage;
// }
//m_cLastItem.m_cNext = newMessage;
}
//m_cLastItem = newMessage;
return m_nSize++;
}
public Message Pop()
{
//Message Current = m_cListStart;
//if the object at the start of the list has another object after it, make that object the start of the list
//and decrease the size by 1 after popping an object off if there is more than 1 object after the start of the list
if (m_cListStart.m_cNext != null)
{
m_cListStart = m_cListStart.m_cNext;
}
if (m_nSize > 0)
m_nSize--;
else
m_cListStart = null;
return m_cListStart;
//if (m_cListStart.m_cNext != null)
// m_cListStart = m_cListStart.m_cNext;
//if (m_nSize > 1)
// m_nSize--;
//return m_cListStart;
}
My pop function to retrieve the messages might need some refining but most of the work right now lies in the Add function. I'm really just stumbling through the dark there.
Does anyone know of a simple way of doing what I'm asking?
Why dont you write a custom linked list as follows:
class Node<T> : IComparable<T>
{
public int Priority {set;get;}
public T Data {set;get;}
public Node<T> Next {set;get;}
public Node<T> Previous {set;get;}
// you need to implement IComparable here for sorting.
}
This is your node definitions. Now We need to implement a LinkedList Class.
Your linked list class can be doubly linked list, since you dont have any specs on it. and it would be easier with doubly linked list.
Here is the definition:
class LinkedList<T> : IEnumerable<T> where T: IComparable
{
public Node<T> Head {set;get;}
public Node<T> Tail {set;get;}
// set of constructors
//.....
public void Insert(Node<T> node)
{
// you can do recursive or iterative impl. very easy.
}
// other public methods such as remove, insertAfter, insert before, insert last etc.
public void Sort()
{
// easiest solution is to use insertion sort based on priority.
}
}
If you can get away by creating extra memory, ie: another linked list. insertion sort would be fine. For this purpose you need to implement insert after functionality as well.
I have a LinkedList implementation, you can check it out. You just need to implement sorting based on priority, you can use bubble sort, insertion sort, or merge sort.
Also, you might want to look at Heap which you can use to implement a priority Queue, it serves the purpose. I have a Heap Data Structure Implementation, you can check it out.
The easiest solution would be to have three singly-linked lists, one for each priority.
When you add, you add to the end of the correct list. When you remove, you first try to remove from the highest priority list. If that is empty, try the middle one. If even that is empty, use the lowest list.
If you have constant number of priorities, the time complexities are O(1) in both cases.
Im working with the code on this page Working with C# lists since 2 days, and I have a problem when I try to change the code to add items to the list after the previous item (instead before the previous item) .
//ListNode constructor params: name, code, nextNode
//Insert element after the first element
public void InsertelementAfterTheFirst(object name, object code)
{
if (IsEmpty())
FirstNode = LastNode = new ListNode(name, code, null);
else
{
FirstNode = new ListNode(name, code, FirstNode);
}
}
I know I can use the "List<>" collection in C#, but my intention is to learn how does the lists works.
Thanks for the help.
Here is the pseudo code...
if (firstNode is empty)
{
//new list...
firstNode = lastNode = new Node(name, code, null);
}
else
{
var node = new Node(name, code, firstNode.nextNode);
firstNode.nextNode = node;
}
Only thing is, this is only good for adding a node after the first Node. A better method might be to specify in the InsertAfter method which node you want to attach the new node to. Or if you are using an iterator-like pattern (your Linked List class has Current node), you can do similar thing.. just get the current node and the code in the else branch above should still work (but instead firstNode, it will be currentNode).
Something like:
public ListNode InsertAfterCurrent(object name, object code)
{
if (currentNode == null)
{
//assume new list
currentNode = firstNode = lastNode = new ListNode(name, code, null);
}
else
{
currentNode.NextNode = new ListNode(name, code, currentNode.NextNode);
}
}
public ListNode InsertAfter(ListNode anchor, object name, object code)
{
if (anchor != null && NodeIsPartOfList(anchor))
{
anchor.NextNode = new ListNode(name, code, anchor.NextNode);
}
}
public bool NodeIsPartOfList(ListNode node)
{
var current = firstNode;
while (current != null)
{
if (current == node)
return true;
current = current.NextNode;
}
return false;
}
Before I answer this I feel I should mention that posting code in Spanish on an English speaking forum is in bad taste. I spent more time trying to understand your basically gibberish naming than writing this post.
Also, List<>, despite its poor naming, isn't implemented as a list. It's a wrapper over an array, which is why .ToArray() is so efficient.
Now to your specific problem, you want to set your head link to the node you just created, and set its next link to the previous head link:
if (EsVacio())
primerNodo = ultimoNodo = new ListNode(nom, cod, null);
else
{
var node=new ListNode(nom, cod, primerNodo);
node.Siguiente=primerNodo;
primerNodo=node;
}
I have 2 millions items in a SortedDictionary<string, MyClass>
I've done the following and takes ages, any ideas?
for(int i = 0; i<dic.Count-1; i++)
{
Debug.WriteLine(dic.ElementAt(i).Value.ToString());
}
The SortedDictionary<TKey, TValue> class does not directly support (fast) retrieval by index; it is internally implemented as a binary search tree. Consequently, every call to the LINQ Enumerable.ElementAt method you've got there creates a new enumerator that iterates each value of the sequence represented by the key-value pairs in the collection (sorted by key) from the beginning until it reaches the desired index. This means that the loop is going to have to pull something like 1 + 2 + 3 + ... + Count (roughly 2 trillion) elements before it completes, making it (atleast) quadratic in its time-complexity.
Try this instead, which should run in roughly linear time:
foreach(var myClass in dic.Values)
Debug.WriteLine(myClass);
If you really do want fast access by index (from the provided code, there doesn't seem to be any reason to indicate this), consider using a SortedList<TKey, TValue> instead. There are downsides to this choice (slower non-appending inserts and deletes) that you should evaluate.
I also notice that the loop condition is i < dic.Count - 1 rather than the more common i < dic.Count. This is either an off-by-one bug, or perhaps you intend to not consider the last value in the dictionary. In the latter case, you could maintain a local variable serving as a counter, or with LINQ:
foreach(var myClass in dic.Values.Take(dic.Count - 1))
Debug.WriteLine(myClass);
foreach might be faster, since you don't use the indexer
foreach (var value in dic.Values)
Debug.Writeline(value)
Also, as far as speed is concerned, Debug.Writeline is probably not the best option (what are you going to do with 2 million debug trace entries anyway??). Consider writing to a file, a database, etc.
EDIT Looking at reflector, finding a value in a SortedDictionry boils down to a binary search:
internal virtual Node<T> FindNode(T item)
{
int num;
for (Node<T> node = this.root; node != null; node = (num < 0) ? node.Left : node.Right)
{
num = this.comparer.Compare(item, node.Item);
if (num == 0)
{
return node;
}
}
return null;
}
The implementation of SortedDictionary's iteration seems a bit more involved:
public bool MoveNext()
{
this.tree.VersionCheck();
if (this.version != this.tree.version)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}
if (this.stack.Count == 0)
{
this.current = null;
return false;
}
this.current = this.stack.Pop();
SortedSet<T>.Node item = this.reverse ? this.current.Left : this.current.Right;
SortedSet<T>.Node node2 = null;
SortedSet<T>.Node node3 = null;
while (item != null)
{
node2 = this.reverse ? item.Right : item.Left;
node3 = this.reverse ? item.Left : item.Right;
if (this.tree.IsWithinRange(item.Item))
{
this.stack.Push(item);
item = node2;
}
else
{
if ((node3 == null) || !this.tree.IsWithinRange(node3.Item))
{
item = node2;
continue;
}
item = node3;
}
}
return true;
}
It seems to maintain a stack whose top element is the smallest (or largest, depending on the direction) one, and thus always the one to be popped and returned during iteration. I haven't done any complexity analysis, but it's bound to be considerably more efficient than running a binary search each time.
Use foreach:
foreach (var pair in d)
Debug.WriteLine(pair.Value);
I bet that debug output takes more time than dictionary lookup though.
I saw the following post order traversal algorithm in some website... it seems to be correct. I just want to verify that this algorithm works correctly — is this algorithm correct for post order traversal without recursion?
void postOrderTraversal(Tree *root)
{
node * previous = null;
node * s = null;
push(root);
while( stack is not empty )
{
s = pop();
if(s->right == null and s->left == null)
{
previous = s;
process s;
}
else
{
if(s->right == previous or s->left == previous)
{
previous = s;
process s;
}
else
{
push( s );
if(s->right) { push(s->right); }
if(s->left) { push(s->left); }
}
}
}
}
Try to write iterative versions of pre-order, in-order, and post-order binary traversal methods. You will then see the pattern or methodology of converting their corresponding recursive versions into the iterative versions.
Key point is sticking to some basic rules:
- Use node selection (e.g., currentNode = currentNode->Left before reiterating the loop, etc.) for immediate node traversal.
- Use stack to remember nodes that need to be visited or revisited later.
- If a node need to be "REvisited," detecting / keeping the state so that you can indicate whether the next node needs to be "processed" in next iteration or one of more of the child nodes should be visited before the node can be processed.
If you stick to these rules, you can esily accomplish the tasks.
Here is an example of the iterative post-order traversal. Ignore BinarySearchTree - it works for any binary trees.
public static IEnumerator<BinarySearchTreeNode<T>> GetPostOrderTraverseEnumerator(BinarySearchTreeNode<T> root)
{
if (root == null)
{
throw new ArgumentNullException("root");
}
Stack<BinarySearchTreeNode<T>> stack = new Stack<BinarySearchTreeNode<T>>();
BinarySearchTreeNode<T> currentNode = root;
// If the following flag is false, we need to visit the child nodes first
// before we process the node.
bool processNode = false;
while (true)
{
// See if we need to visit child nodes first
if (processNode != true)
{
if (currentNode.Left != null)
{
// Remember to visit the current node later
stack.Push(currentNode);
if (currentNode.Right != null)
{
// Remember to visit the right child node later
stack.Push(currentNode.Right);
}
// Visit the left child
currentNode = currentNode.Left;
continue;
}
else if (currentNode.Right != null)
{
// Remember to visit the current node later
stack.Push(currentNode);
// Visit the right child
currentNode = currentNode.Right;
continue;
}
}
// Process current node
yield return currentNode;
// See if we are done.
if (stack.Count == 0)
{
break;
}
// Get next node to visit from the stack
BinarySearchTreeNode<T> previousNode = currentNode;
currentNode = stack.Pop();
// See if the next node should be processed or not
// This can be determined by the fact that either of the current node's child nodes
// has just been processed now.
processNode = (previousNode == currentNode.Left || previousNode == currentNode.Right);
}
}
no here prev should not start with null
eg:for bst having nodes 5 2 1 3 7 6 8 0
it will not consider zero because at 1 its right is null and this time previous will also be null hence it will not consider its left child i.e. 0
write previous=any value but not null
Here is the working code
Stack s=new Stack();
while(true){
if(root!=null){
s.push(root);
root=root.left;
}
else{
if(s.top().right==NULL){
root=s.top();
s.pop();
System.out.println(root.data);
if(root==s.top().right){
System.out.println(s.top().data);
s.pop();
}
}
if(!s.empty())
root=s.top().right;
else
root=NULL;
}
}