Inserting into sorted linked list? - c#

I'm very new to coding and I couldn't understand the error in my code, I'd be very grateful for any help.
So the code works fine except for the last element because the element after that is null and I couldn't handle it (I'm very new).
The problem is with the last part.
public static void InsertingIntoSortedLinkedList(int value, int key)
{
Node m = new Node();
m.value=value;
m.key=key;
if (root==null)
{
m.Next = null;
root = m;
}
else
{
if (key<root.key)
{
m.Next = root;
root = m;
}
else
{
Node temp1 = root;
Node temp2 = null;
while ((temp1!=null)&&(temp1.key<key))
{
temp2 = temp1;
temp1 = temp1.Next;
}
if (temp1==null)
{
m.Next = null;
temp2.Next=m;
}
else
{
m.Next = temp1;
if (temp2!=null)//I either put this here and the last element is lost or I got a NullReferenceException. What should I change?
{
temp2.Next = m;
}
}
}
}
}
Thank you for your help.

One situation where you may find a problem is when you insert a value equal to the root value - those values will be skipped because you are trying to insert BEFORE the matching item and not updating the root reference.
The solution is to either insert after the matching value - this can be done by changing the line
while ((temp1!=null)&&(temp1.key<key))
to
while ((temp1 != null) && (temp1.key <= key))
OR by inserting at the root element by changing the line
if (key<root.key)
to
if (key <= root.key)
OR by updating the root value when inserting before
if (temp2!=null)
{
temp2.Next = m;
}
else
root = m;
Any one of the changes should fix the problem

You have two typos:
if (key<root.key)
while ((temp1!=null)&&(temp1.key<key))
missing > at the end of <key

Related

How to add new node when building Binary Tree

I'm working with an alternate version of the BinaryTree class called RedBlackTree. I'm trying to build the tree with this add method.
public void Add(T val)
{
RedBlackNode<T> newNode = _rootNode;
while(newNode != null)
{
if(val.CompareTo(newNode.Data) < 0)
{
newNode = newNode.LeftChild;
}
else if(val.CompareTo(newNode.Data) >= 0)
{
newNode = newNode.RightChild;
}
}
newNode.Data = val; //nullReferenceException thrown here <---
newNode.IsBlack = false;
FixColors(newNode);
}
_rootNode is a private field giving the root of the tree. It is initialized to null as given by specific instructions. This Add method is being called from within another class from a method that is reading in file info. On the first iteration, a nullReferenceException is thrown, I assume because the node I am trying to change is null. I don't know how else I am supposed to change the data value of these nodes. I will post the code to the rest of the program if necessary.
Well, the while loop isn't going to exit while newNode isn't null. That implies newNode is going to be null once the loop exits. I think what you want is to create a new node if the RightChild or LeftChild nodes is null, and set newNode to that.
In addition, as Partha's answer points out, you need to initialize the _rootNode value if it isn't already set.
I don't really know how the parent property of the node is set, so I'm going to assume the parent node is injected as a constructor argument of the child node:
public void Add(T val)
{
RedBlackNode<T> parent = _rootNode;
RedBlackNode<T> target = null;
while(target == null)
{
if(val.CompareTo(parent.Data) < 0)
{
if (parent.LeftChild == null)
target = parent.LeftChild = new RedBlackNode<T>(parent);
else
parent = parent.LeftChild;
}
else if(val.CompareTo(newNode.Data) >= 0)
{
if (parent.RightChild == null)
target = parent.RightChild = new RedBlackNode<T>(parent);
else
parent = parent.RightChild;
}
}
target.Data = val;
target.IsBlack = false;
FixColors(newNode);
}
You need to create the node before you access the other fields. So if _rootNode is empty you create using new keyword.
public void Add(T val)
{
if(_rootNode == null)
{
RedBlackNode<T> newNode = new RedBlackNode<T>();
newNode.Data = val;
newNode.IsBlack = false;
_rootNode = newNode;
return;
}
//Followed by your logic
}

Deleting a node from an xmlNodeList

here is my code
public bool limitOutput()
{
double lowerLeftPointX = m_mapControl.CurrentExtent.LowerLeftPoint.X;
double lowerLeftPointY = m_mapControl.CurrentExtent.LowerLeftPoint.Y;
double upperRightPointX = m_mapControl.CurrentExtent.UpperRightPoint.X;
double upperRightPointY = m_mapControl.CurrentExtent.UpperRightPoint.Y;
for(int i = locationElements.Count - 1; i >= 0; i--)
{
if (Double.Parse(locationElements[i]["GEOMETRY_X"].InnerText) < lowerLeftPointX || Double.Parse(locationElements[i]["GEOMETRY_X"].InnerText) > upperRightPointX || Double.Parse(locationElements[i]["GEOMETRY_Y"].InnerText) < lowerLeftPointY || Double.Parse(locationElements[i]["GEOMETRY_Y"].InnerText) > upperRightPointY)
{
locationElements[i].ParentNode.RemoveChild(locationElements[i]);
}
}
if (locationElements.Count == 0)
{
PearMessageBox.Show(PearMessageBox.mBoxType.simpleNotification, "No results found in specified area");
return false;
}
return true;
}
I am trying to delete all the nodes which are not within the boundary I have set. The delete line is executed but does not actually delete as when I count locationElements it is still the same value before the method is executed.
Any ideas what is wrong with the code
The problem is due to the fact that RemoveChild() removed the element from the source XmlDocument, but not from the pre-populated XmlNodeList. So you need to execute again the code that was used to pre-populate locationElements variable, something like this :
//assume that GetLocationElements() is a method...
//...containing the same logic you used to populate locationElements variable
var updatedLocationElements = GetLocationElements();
if (updatedLocationElements.Count == 0)
{
PearMessageBox.Show(PearMessageBox.mBoxType.simpleNotification, "No results found in specified area");
return false;
}
return true;

Adding Nodes To TreeView In For/ForEach Loop

I've been trying to figure out but it is so complex, so I wanted to ask since I could not get an answer
CheckForIllegalCrossThreadCalls = false;
FolderBrowserDialog fbd = new FolderBrowserDialog();
if(fbd.ShowDialog() == DialogResult.OK)
{
Thread t = new Thread(() => StartListing(fbd.SelectedPath));
SplittedPath = fbd.SelectedPath.Split(Path.DirectorySeparatorChar);
t.Start();
foreach(string s in SplittedPath)
{
if(treeView1.Nodes.Count > 0)
{
treeView1.Nodes[i].Nodes.Add(s);
i++;
treeView1.Nodes[i].ImageIndex = 0;
}
else
{
treeView1.Nodes.Add(s);
treeView1.Nodes[0].ImageIndex = 0;
}
}
}
Here is my code.SplittedPath string is normally seems good.It has all splitted stuff but in ForEach loop, it seems like there are only 2 string.When I delete
if(treeView1.Nodes.Count > 0)
{
treeView1.Nodes[i].Nodes.Add(s);
i++;
treeView1.Nodes[i].ImageIndex = 0;
}
else
{
treeView1.Nodes.Add(s);
treeView1.Nodes[0].ImageIndex = 0;
}
This codes, it just works fine.When I add these to ForEach loop, it just does not add all SplittedPath strings.Any solution?
You don't deal with the tree structure in your code, that's why it doesn't work. You only have 2 levels here.
If you want a tree presentation of your path you should do the following:
TreeNode n = null;
TreeNode parent = null;
foreach(string s in SplittedString)
{
if (parent == null)
{
parent = new TreeNode(s);
treeview1.Nodes.Add(parent);
continue;
}
n = new TreeNode(s);
parent.Nodes.Add(n);
parent = n;
}
I don't say it's the best way to do it, but you have the general idea of an iterative solution.
You get a reference to the parent node, and as you go through your path, the parent changes to be the last node added. That way every string s will be at a different level of your tree structure.

How to store child to child nodes and remove the immediate parent?

We are parsing an xml and after serializing them ,it will be stored in database.
Our XML is look like below.
<SampleTypeService>
<Name>sample1</Name>
<URL>sample1</URL>
<SampleTypeService_PK_ID>225d0266-e83a-44b8-88fc-700f6570d530</SampleTypeService_PK_ID>
<SampleTypes>
<SampleType_PK_ID>ef1d8c40-72ce-48d8-b252-9b521e96fa74</SampleType_PK_ID>
</SampleTypes>
</SampleTypeService>
<SampleTypeService>
<Name>sample2</Name>
<URL>sample2</URL>
<SampleTypeService_PK_ID>225reg66-e83a-44b8-88fc-700f6570d530</SampleTypeService_PK_ID>
<SampleTypes>
<SampleType_PK_ID>gh4d8c40-72ce-48d8-b252-9b521e96fa74</SampleType_PK_ID>
</SampleTypes>
</SampleTypeService>
We need to store the value in SampleType_PK_ID in a string and then remove both
SampleTypes and SampleType_PK_ID node.
I am trying to delete it like below.
foreach (XmlNode SampleNode in SampleList)
{
XmlNodeList ChildList = SampleNode.ChildNodes;
for (int j = 0; j < ChildList.Count; j++)
{
if (ChildList[j].LocalName == "SampleType_PK_ID>")
{
strSampleTypePKID = ChildList[j].InnerText;
if (strSampleTypePKID != null)
{
SampleNode.ParentNode.RemoveChild(ChildList[j]);
j--;
}
}
}
testString = SampleNode.OuterXml;
Console.WriteLine("1):" + strSampleTypePKID);
//Code to serialize and store in database is here.
}
But strSampleTypePKID is returning as empty string. What am I missing here. How to take the child to child node value and then delete it along with it's immediate parent?
You're looking for the inner child node "SampleType_PK_ID" at the wrong level.
If you put a breakpoint at the line strSampleTypePKID = ChildList[j].InnerText;, you can see that it's never been executed.
Try the following instead:
foreach (XmlNode SampleNode in doc.FirstChild.ChildNodes)
{
strSampleTypePKID = string.Empty;
var sampleTypesNode = SampleNode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "SampleTypes").FirstOrDefault();
if (sampleTypesNode != null)
{
var pkNode = sampleTypesNode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "SampleType_PK_ID").FirstOrDefault();
if (pkNode != null)
{
strSampleTypePKID = pkNode.InnerText;
SampleNode.RemoveChild(sampleTypesNode);
}
}
testString = SampleNode.OuterXml;
Console.WriteLine("1):" + strSampleTypePKID);
//Code to serialize and store in database is here.
}

Get next item in a tree

Having a tree (logical in DB) with items in the form
List item A
List item B
List item C
List item D
List Item E
List Item F
List Item G
and so on (nesting depth not limited), I want to get the next node down (or up), starting from an arbitrary node.
Let's say, List Item D is given I want to write a function GetNextNode() that would return List Item E.
My idea would be to do some recursion stuff, but maybe there is a more clever way to handle this?
My question:
How would you solve this?
EDIT 1:
The tree can be accessed with functions like:
GetParentNode()
GetChildrenNodes()
GetNextSiblingNode()
etc.
So it's similar to e.g. e Windows Forms TreeView.
I've had to do this several times. From memory:
public Node GetBelowNode()
{
if (GetChildrenNodes().count > 0)
return GetChildrenNodes()[0];
else
if (GetNextSiblingNode() != null)
return GetNextSiblingNode();
else
{
Node curr = this;
Node parent;
while (true)
{
parent = curr.GetParentNode();
if (parent == null)
return null;
else
{
if (parent.GetNextSiblingNode() != null)
return parent.GetNextSiblingNode();
else
curr = parent;
}
}
}
}
You can handle this via recursion or... worst xD
I think there are only 3 basic cases:
private string getNext(TreeNode node)
{
if (node.FirstNode != null)
{
return node.FirstNode.Name;
}
else
{
if (node.NextNode != null)
{
return node.NextNode.Name;
}
else if (node.Parent.NextNode != null)
{
return node.Parent.NextNode.Name;
}
}
return "";
}
This doesn't works for every scenario. You should search the parent's next node too. Thanks to Vincent Vancalbergh for the comment ;-)
public Party Next {
get {
if (this.children.Count > 0) return this.children[0];
Party target = this;
do {
if (target.NextSibling != null) return target.NextSibling;
} while ((target = target.Parent) != null);
return null;
}
}
public Party Previous {
get {
if (Parent != null && Parent.children.Count > 0 && this == Parent.children[0]) {
return Parent;
}
Party target = this;
do {
if (target.PreviousSibling != null) { target = target.PreviousSibling; break; }
} while ((target = target.Parent) != null);
if (target != null) {
while (target.children.Count > 0) {
target = target.children[target.children.Count - 1];
}
}
return target;
}
}
Since I got a great reply for the "down" part, I'll added my own "up" part. Maybe it is for some help of you; the up part is similar to:
Get the previous sibling.
If there is a previous sibling, get the deepest child node of this
sibling.
If there is no previous sibling, get the direct parent.
To get the deepest sibling (2.), I use the following code:
function getDeepestChild( page )
dim result
set result = nothing
dim childPages
set childPages = page.ChildPages
if childPages.Count>0 then
dim p
set p = childPages(childPages.Count-1)
' recurse.
set result = getDeepestChild( p )
else
set result = page
end if
set getDeepestChild = result
end function
(Yes, I do know that this is VBScript; I needed it in fact in this language)
Try this maybe:
TreeNode currentNode = treeView1.SelectedNode;
treeView1.selectedNode = currentNode.NextNode;

Categories