would help me to solve this problem
i am trying to insert the node at ith location in linked list using recursion
here is the code please help me to imporve the code
i ma specifically facing problem at the end when i have to return the head i am not getting how to return
Node* insertNodeRecursively(Node*head, int n, int data)
{
if(head == nullptr)
{
return head;
}
else if(n==0)
{
Node* newNode= new Node(data);
newNode->next = head->next;
head->next = newNode;
return head;
}
Node * x = insertNodeRecursively(head->next,n-1,data);
}
So I guess you want the function insertNodeRecursively to return the new head, right? Anything else would not work without considering the special case of inserting at position 0 in the caller function.
You could do the following:
if (n == 0) {
Node *newNode = new Node(data);
newNode->next = head;
return newNode;
}
if (head == nullptr) {
return nullptr;
}
Node *node = insertNodeRecursively(head->next, n - 1, data);
head->next = node;
return head;
The idea is that when this is not the position to insert to, we need to assume the next recursive call might give us a new head (from that position on), so we need that head->next = node; assignment. To call the node passed as first argument head might confuse as it is not always the head of the list (Only at the start of the recursion)! It is rather the node in front of which you want to insert in case n is 0. The problem with what you wrote in the n == 0 case is that you always return the old head, even though you should return newNode. The head node should be what follows after newNode.
Related
**following is my linked list code...
its not working for some reason. Can someone help me out here?
void insertAtTheEnd(node *&head, int data){
node *newNode= new node(data);
newNode->data=data;
node *temp=head;
while(temp!=NULL){
temp=temp->next;
}
temp->next=newNode;
newNode->next=NULL;
newNode->prev=temp->next;
}
As you have it coded, temp is guaranteed to be NULL when your while loop exits. Hence, temp->next=NULL will crash.
When you probe for a position in the list, you typically need to keep "previous" variable to point to the item before the one you are iterating with.
node* temp = head->next;
node* previous = head;
while (temp)
{
previous = temp;
temp = temp->next;
}
// when the while loop returns, `previous` is the last element in the list
previous->next = newNode;
newNode->prev = previous;
newNode->next = nullptr;
Another case you missing in your code. When head is NULL (empty list), you need to update head to be your newNode
// empty list - return the new node as head
if (head == nullptr)
{
newNode->next = nullptr;
newNode->prev = nullptr;
head = newNode;
return;
}
I am making a code for double linked list in C++. But, i have a problem, I dont know how add node before other node.
I have these.
template<class T>
void LinkedListD<T>::addNodeBeforeTo(Node<T> *before, T info) {
Node<T>* newNode = new Node<T>( info );
if ( isEmpty() ){
head = newNode;
last = newNode;
} else{
if ( before == head ){
newNode->next = head;
head = newNode;
} if ( before == last ){
newNode->previous = last;
last = newNode;
}
else{
Node<T>* act = head;
Node<T>* past = last;
while ( act->next != before && past->previous != before){
act = act->next;
past = past->previous;
}
newNode->previous = past->previous;
newNode->next = act->next;
act->next = newNode;
past->previous = newNode;
}
}
}
The example is 10, 15, 20, 12
Add node before to 20: 30
Finish Output 10, 15, 30, 20, 12
Thks
You have to realize how to approach the solution, methodically (n is the object you want to insert the new_item object before it):
if (head != nullptr) // i.e. if list is not empty
{
}
if (new_item.P == nullptr) // i.e. if new_item is first
head = new_item;
You don't need the while loop at all. Each node knows the nodes on both sides of it, that is all you need to update the list properly. Given the input node before, all you have to do is:
set newNode->previous to point at the before->previous node
set newNode->next to point at the before node
if before->previous is not null, set before->previous->next to point at the newNode node
set before->previous to point at the newNode node
if before is pointing at the head node, set head to point at the newNode node.
Done.
Also, you have some other logic errors in this code. When inserting before the head node, you are not updating head->previous to point at the newNode node before updating head itself. And since your function inserts before a given node, you should not be trying to insert after the last node at all, that job should be handled by a separate addNodeAfterTo() method instead.
Try something more like this:
template<class T>
Node<T>* LinkedListD<T>::addNodeBeforeTo(Node<T> *before, const T &info) {
if ( !before ) return nullptr;
Node<T>* newNode = new Node<T>( info );
newNode->previous = before->previous;
newNode->next = before;
if ( before->previous )
before->previous->next = newNode;
before->previous = newNode;
if ( before == head )
head = newNode;
return newNode;
}
Demo
So I am trying to sort nodes according to their location (an integer) and then by the date (year and month). When I use my overloaded operator to print my linked list, it shows that the list is only inserting one of the wanted nodes meaning that my insert function is not correct. It is not giving any errors, it is just not running as expected. My insert function is below. Does anyone have any ideas as to what is wrong?
void LinkedList::insert(int location, int year, int month, double temperature) {
// Implement this function
Node* newNode = new Node();
newNode->loc = location;
newNode->yr = year;
newNode->mo = month;
newNode->temp = temperature;
Node* tempNode = head;
Node* previousNode = nullptr;
if(tail == nullptr & head == nullptr){
head = newNode;
}
while(tempNode != nullptr){
if((tempNode->loc == newNode->loc) && (tempNode->yr == newNode->yr)){
if(tempNode->mo > newNode->mo){
newNode->next = tempNode->next;
tempNode->next = newNode;
}
if(tempNode->mo < newNode->mo){
newNode->next = tempNode;
}
}
if(tempNode->loc > newNode->loc){
newNode->next = tempNode->next;
tempNode->next = newNode;
}
if(tempNode->loc < newNode->loc){
newNode->next = tempNode->next;
tempNode->next = newNode;
}
tempNode = tempNode->next;
}
}
The reason you are not getting the linkedlist properly is because you are making a mistake in pointer manipulation. When you assign cur->next=data->next;
you are basically breaking the list since data->next doesnot point to next node in the list.
Also, note that since this is a single linked list [meaning it has only one pointer forward] you can only insert nodes ahead of the current node.
Try something like this:
if (cur->loc > data->loc) {
data->next = cur->next; // This will insert data in middle of
cur->next = data; // cur and cur->next
}
There are multiple checks you will need to do if you want to insert in a increasing or decreasing order.
Make different cases for when you insert the first element of the list, insert at head, insert at tail and insert in the middle of linkedlist.
Also, at tail node make sure that its next is always set to null.
I am a novice programmer and this is my second question on Stack Overflow.
I am trying to implement a pushback function for my Linked List by using a tail pointer. It seems straightforward enough, but I have a nagging feeling that I am forgetting something or that my logic is screwy. Linked Lists are hard!
Here is my code:
template <typename T>
void LinkedList<T>::push_back(const T n)
{
Node *newNode; // Points to a newly allocated node
// A new node is created and the value that was passed to the function is stored within.
newNode = new Node;
newNode->mData = n;
newNode->mNext = nullptr;
newNode->mPrev = nullptr;
//If the list is empty, set head to point to the new node.
if (head == nullptr)
{
head = newNode;
if (tail == nullptr)
{
tail = head;
}
}
else // Else set tail to point to the new node.
tail->mPrev = newNode;
}
Thank you for taking the time to read this.
Your pointing the wrong mPrev to the wrong node. And you never set mNext of the prior tail node if it was non-null to continue the forward chain of your list.
template <typename T>
void LinkedList<T>::push_back(const T n)
{
Node *newNode; // Points to a newly allocated node
// A new node is created and the value that was passed to the function is stored within.
newNode = new Node;
newNode->mData = n;
newNode->mNext = nullptr;
newNode->mPrev = tail; // may be null, but that's ok.
//If the list is empty, set head to point to the new node.
if (head == nullptr)
head = newNode;
else
tail->mNext = newNode; // if head is non-null, tail should be too
tail = newNode;
}
I have a singly linked list. If I want to delete an known element from this linked list, what can I do?
For example:
Node* head; (44)
Node* tail; (39)
linked list: 44 27 59 13 45 39
we want to delete 45 from it. and get: 44 27 59 13 39
I only figured out that delete first element from list(if element(need to be removed) is first element of the list).
I got: head = head-> next;
How to remove intermediate node from list?
13 will be pointing 45 as its next element, simple change its next element to 39. And free the 45 from memory, just to keep memory clean from trash.
This pseudo code might help you :-
void remove(int key) {
Node* p = head->next;
Node*prev = head;
while(p!=NULL) {
if(p->data==key) {
prev->next = p->next;
free(p);
break;
}
prev = p;
p = p->next;
}
}
Look at the value in the next node, if there is a value. If that is the value you're looking for, then the next node is the one to delete, so you make the current node's next element point to the next node's next element, after preserving a pointer to the next node so that you can delete it.
// Assuming head is a non-const reference variable (or a global variable)
if (head == NULL)
return;
if (head->value == wanted)
{
head = head->next;
return;
}
for (Node *curr = head; curr->next != NULL; curr = curr->next)
{
if (curr->next->value == wanted)
{
Node *old = curr->next;
curr->next = curr->next->next;
delete old;
return;
}
}
return; // Possibly after reporting that the value wanted was not found
First, find the element you want to delete. Don't forget to handle when the element doesn't exist:
Node* find(Node* head, int value) {
do {
if (head->value == value) return head;
head = head->next;
} while (head);
return nullptr;
}
Then, you want to connect the previous node's next ptr to the next node. In a singly-linked list, you can track the previous node using a local variable. Don't forget to handle if the node you want to delete is the head (i.e. no previous node), or if the node is the tail (i.e. no next node):
Node *previous = nullptr;
do {
if (head->value == value) {
if (previous != nullptr) {
previous->next = head->next;
}
if (head == tail) {
tail = previous;
}
return;
}
previous = head;
head = head->next;
} while (head);
Think through the problem.
You need a loop to traverse all the nodes till you find the one you are looking for. Say you have Node* curr, prev both pointing to head.
while(curr != null)
For each node you need to check if the value matches or not with the node that you are looking for.
if (curr->value == node_you_are_looking_for->value)
If this is the matching node, delete this node. You have two pointers to update the links.
prev->next = curr->next;
prev = curr;
curr = curr->next;
prev->next = null;
delete(prev);
Else keep on traversing the list.
prev = curr;
curr= curr->next;
Then you can assemble all these steps and write a working program.
You just have to analyse the problem first and know the changes required if we delete a particular node.
let us suppose that we have the address of the node which is supposed to be deleted
there can be 3 cases if the node is the 1st node or the last node or a middle node ie a minimum 2 nodes.
void deletenode(struct node **s,struct node *t){
struct node *temp;
if(*s==t)
{
*s=t->next;
free(t);
}
else{
temp=*s;
while(temp->next!=t)
{
temp=temp->next;
}
temp->next=t->next;
delete(t);
}
}