Hi I have difficulty on understanding how ListNode && dummy node works.
Suppose we are given the head of the list. When we declare ListNode dummy = head, and we are not touching dummy node in the rest of code, but only changeing the node head, I'm wondering that why dummy node still has the reference to the modified node head? Suppose the code is:
ReverseList(ListNode head){
ListNode dummy = head;
while(head != null){
...
//we are not doing anything with dummy here
...
}
return dummy.next;
}
//if we change head, the dummy will also change(why?)
I really appreciate any explanation!
Related
//Deletes data given from the linked list
public void deleteByValue(T data) {
//if empty then simply return
if (isEmpty())
return;
//Start from head node
Node currentNode = this.headNode;
Node prevNode = null; //previous node starts from null
if(currentNode.data.equals(data)) {
//data is at head so delete from head
deleteAtHead();
return;
}
//traverse the list searching for the data to delete
while (currentNode != null) {
//node to delete is found
if (data.equals(currentNode.data)){
prevNode.nextNode = currentNode.nextNode;
return;
}
prevNode = currentNode;
currentNode = currentNode.nextNode;
}
}
}
Hi all, I am quite new to data structure and I am confused when I learned how to delete one specific value in the single linked list.
So when we traverse the LinkedList, we have a line like this
prevNode.nextNode = currentNode.nextNode;
I think this already means that we have connected "the previous node before the target node" and "the next node before the current node". Why do we still have these two lines after the traversing of the linked list?
prevNode = currentNode;
currentNode = currentNode.nextNode;
Are these two lines mean we are connecting the original previous node with the original next node? I always got lost when the code referred to the "currentNode".How can we tell which is the current "currentNode"?
Could someone help me with this? Visualized answer is appreciated. Thanks so much!
Why do we still have these two lines after the traversing of the linked list?
These are not after traversing; these are the traversing itself.
Some things to note:
An assignment to an attribute will mutate the list, like prevNode.nextNode = currentNode.nextNode does.
An assignment to a variable will not mutate the list, but can make a reference to a different node, like currentNode = currentNode.nextNode does. This really is the core of traversing: it makes the variable currentNode hop from one node to the next -- without changing anything to the list it is traversing.
In this specific algorithm, when the mutation with prevNode.nextNode = currentNode.nextNode is performed, the next thing that happens is a return -- so there is no further traversal happening.
I'm looking at the following code from Programming Interviews Exposed, and I can't seem to understand how exactly it works. Won't this method always return null?
// Overload it to handle nodes as well
Node findLowestCommonAncestor( Node root, Node child1,
Node child2 ){
if( root == null || child1 == null || child2 == null ){
return null;
}
return findLowestCommonAncestor( root, child1.getValue(),
child2.getValue() );
}
From the code snippet, we don't really know what getValue returns. So if there are other overloaded versions of findLowestCommonAncestor, and getValue returns something other than Node, then the call to findLowestCommonAncestor in your snippet is not recursively calling itself.
I have a RadTreeView C# component. The tree is nested, so some Nodes have their sub-trees, stored in Nodes property of upper-level Nodes.
Now I need to find a node by value. Node is hidden somewhere in subtrees. If I use call
RadTreeNode rtn= PagesTreeView.Nodes.FindNodeByValue(i.ToString());
where PagesTreeView is my tree, then it searches only across top-level nodes.
How I can Find Node by Value using not only Nodes from the current level of tree, but also dive into subtrees? Do I need to write such recursive search myself or there is a straightforward solution?
Recursively searching the RadComboBox
There isn't a built in function to recursively search, however you can roll your own pretty easiliy. This should work for you (not tested):
RadTreeNode FindNodeRecursive(RadTreeNodeCollection nodes, string value)
{
foreach (RadTreeNode node in nodes)
{
if(node.Value == value)
return node;
if (node.Nodes.Count > 0)
{
FindNodeRecursive(node.Nodes, value);
}
return null;
}
}
And then call it like this:
var node = FindNodeRecursive(PagesTreeView.Nodes, i.ToString());
Yes, you would need to write your own recursive function to do the search. Another option if you are using the ASP.NET AJAX version of the control is the GetAllNodes() method. It returns all nodes in the tree hierarchy (I'm guessing it uses recursion under the hood). Once you have the entire list you would search it for the node you care about. The big drawback with that approach is if you have a lot of nodes the search could be slow and consume a lot of memory. Doing your own recursive search is the best approach.
See this article for more info.
Old question but I faced this same problem in my application, how to search through the hierarchical tree nodes.
I would like to share one correction to previous solutions proposal. When calling FindNodeRecursive() recursively the return value of your recursive call is never being evaluated or assigned to a variable. So, you will always end up with going through the foreach loop and return value is null.
Corrected and tested function code (WPF C#):
RadTreeNode FindNodeRecursive(RadTreeNodeCollection nodes, string value)
{
RadTreeNode ret = null;
foreach (RadTreeNode node in nodes)
{
if(node.Value == value)
return node;
if (node.Nodes.Count > 0)
{
ret = FindNodeRecursive(node.Nodes, value);
}
return ret;
}
}
Function use:
var node = FindNodeRecursive(PagesTreeView.Nodes, i.ToString());
if (node != null) // found
{
;
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Deleting a middle node from a single linked list when pointer to the previous node is not available
Signature of delete node is given as void delete(struct node *nodeToBeDeleted);
head of the linklist is not provided. Is there any way to delete nodeToBeDeleted node?
Copy data of the next node to current node.
Now next node containing current node's data becomes the node to be deleted.
Set next of current node to next of next node.
Code Snippet
void delete(struct node *nodeToBeDeleted)
{
struct node *nextNode;
if(nodeToBeDeleted == NULL)
{
return;
}
nextNode = nodeToBeDeleted ->next;
nodeToBeDeleted ->data = nextNode->data;
nodeToBeDeleted->next = nextNode->next;
delete nextNode;
return;
}
You must print a simply linked list backwards:
Without recursion
With constant extra memory
In linear time
Leaving the list intact
Added Later Two passes at most
Invert the list, print it forwards, invert again. Each step can be done without violating restrictions except the last one.
EDIT: As cube notes in the comments the second and the third stages can be combined into one pass. This gives two passes – first reverse, then print while reversing again.
Building on sharptooth's reply, you can combine the printing and second inversion in the same pass.
Edit: The "list is left intact" from a single-threaded view because the post-condition equals the pre-condition.
Edit 2: Not sure how I got the answer, but I'll take it since I've hit the rep cap for the day. I gave sharptooth a +1 too.
Here's a C# implementation that holds for all the current rules. It mutates the list during the execution, but the list is restored before returning.
using System;
using System.Diagnostics;
namespace SO1135917.Classes
{
public class ReverseListPrinter
{
public static void Execute(Node firstNode, Action<Node> action)
{
Reverse(Reverse(firstNode, null), action);
}
private static Node Reverse(Node firstNode, Action<Node> action)
{
Node node = firstNode;
Debug.Assert(node != null);
Node nextNode = node.Next;
node.Next = null;
while (node != null)
{
if (action != null)
action(node);
if (nextNode == null)
break;
Node nextNode2 = nextNode.Next;
nextNode.Next = node;
node = nextNode;
nextNode = nextNode2;
}
return node;
}
}
}
There is one problem, however, and that is that the state of the list is undefined if an exception should occur in the above methods. Probably not impossible to handle though.
A subversion repository of the above code, with unit tests, for Visual Studio 2008 is available here, username and password is both 'guest' without the quotes.
You can first check the length of the list. Then create a print-buffer, which you fill in backwards as you traverse the list once again for the information.
Or
You can create another linked list where you add all the printing data in the front when you traverse the first list, and then print the second list from front to back.
Either way makes only two passes at most. The first idea could be done in one pass if you have a header struct that keeps track of the amount of elements in the list.
Edit: I just realised that these ideas does not use constant memory.
The only way to do this sensibly seems to be Sharptooths reply, but that requires three passes.
a function like the following might solver your issue:
void invert_print(PtNo l){
PtNo ptaux = l;
PtNo last;
PtNo before;
while(ptaux != NULL){
last = ptaux;
ptaux = ptaux->next;
}
while(ptaux != last){
printf("%s\n", last->info.title);
ptaux = l;
before = last;
while(ptaux != before){
last = ptaux;
ptaux = ptaux->next;
}
}
}
you will need a structure like the following:
typedef struct InfoNo{
char title20];
}InfoNo;
typedef struct aPtNo{
struct InfoNo info;
struct aPtNo* nextx;
}*PtNo;
Objective-C Link class with reverse method:
Link.h
#import <Foundation/Foundation.h>
#interface Link : NSObject
#property(nonatomic) int value;
#property(nonatomic) Link *next;
- (Link*)reversedList;
#end
Link.m
#import "Link.h"
#implementation Link
- (Link*)reversedList {
Link* head;
Link *link = self;
while (link) {
// save reference to next link
Link *next = link.next;
// "insert" link at the head of the list
link.next = head;
head = link;
// continue processing the rest of the list
link = next;
}
return head;
}
#end