How add node before doubly linked list c++ - c++

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

Related

Inserting at the end in doubly linked list

**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;
}

inserting node at ith position in linked list recursively

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.

What is the best way to reject duplicates in a sorted doubly linked list

I am trying to make a sorted doubly linked list that doesn't insert duplicates, but I am having trouble finding a way to do this. I looked at posts on how to remove duplicates, but no posts on preventing duplicate insertions.
Here is the code I have to insert and sort without rejecting duplicates. The parameter, dataIn takes values from a predefined Student object list in main (Student s = {{gpa, name}, ..., {gpa, name}}:
void StudentList::insertNode(Student dataIn)
{
ListNode *newNode; // A new node pointer
ListNode *pCur; // To traverse the list
// Allocate a new node and store num there.
newNode = new ListNode;
newNode->stu = dataIn;
newNode->forw = NULL;
newNode->back = NULL;
//Check if there is node in list
if(head ->forw == NULL && head->back == NULL){
head->forw = newNode;
newNode->back = head;
newNode->forw = head;
head->back = newNode;
}
else{
// Initialize pointers
pCur = head->forw;
// Find location: skip all nodes whose name is less than dataIn's name
while (pCur != head && pCur->stu.name < dataIn.name)
{
pCur = pCur->forw;
}
// Insert the new node between pPre and pCur
ListNode *pPre = pCur->back; // The previous node
newNode->back = pPre;
newNode->forw = pCur;
pCur->back = newNode;
pPre->forw = newNode;
}
// Update the counter
count++;
}
Does anyone know a way for rejecting duplicates without deleting? Thanks everyone!
What is the best way to reject duplicates in a sorted doubly linked list?
I suggest delaying the creation of the new ListNode until you know that the new node isn't a duplicate.
Assuming that the ListNode looks like this
struct ListNode {
Student stu;
ListNode *back;
ListNode *forw;
};
and that you have a head and tail ListNode* that is set to nullptr when the StudentList is empty, then the insertNode function could look like this:
bool StudentList::insertNode(const Student& dataIn) { // return true if node is inserted
ListNode* prev = nullptr;
ListNode* pCur = head;
// search for a good insertion spot
for(; pCur; prev = pCur, pCur = pCur->forw) {
if(dataIn.name == pCur->stu.name) return false; // equal, reject
if(dataIn.name < pCur->stu.name) break; // found a good spot before pCur
}
// delayed creation until here:
ListNode* newNode = new ListNode{dataIn, prev, pCur};
// linking
if(prev) prev->forw = newNode;
else head = newNode;
if(pCur) pCur->back = newNode;
else tail = newNode; // comment this line out if you don't have a "tail"
++count;
return true; // node inserted
}

Linked list issue with multiple parameters

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.

Error inserting word into Linked List

So I have my Linked List struct here
struct ListNode
{
string item;
ListNode *next;
};
ListNode *head;
ListNode *cur;
ListNode *prev;
ListNode *search();
And my method to add nodes into Linked List
inline void List::guessedWords( string guess )
{
cur = head;
while ( cur != NULL )
{
ListNode *newNode = new ListNode;
newNode->item = guess;
if ( head == NULL )
{
newNode->next = NULL;
head = newNode;
}
else
{
prev = search();
newNode->next = cur;
prev->next = newNode;
}
cur = newNode;
}
}
Anyone can point to my what's my mistakes? I couldn't get to add the first node.
Search function is to traverse to the end of node. What I'm trying to do is to keep on adding words into the back of he node.
The while loop looks a bit strange, you don't need a loop to insert a single element given the search() function (which an be replaced with a pointer called tail) Also,
cur = head;
while ( cur != NULL )
{ /* .... */
if ( head == NULL )
the above head == NULL can never evaluate to true because the while condition already filters out that possibility.
head = tail = NULL;
inline void List::guessedWords( string guess )
{
ListNode *newNode = new ListNode;
newNode->item = guess;
newNode->next = NULL;
if ( head == NULL )
{
head = newNode;
tail = newNode;
}
else
{
tail->next = newNode;
}
}
I guess you are missing,
tail = tail->next; just after
tail->next = newNode;
it would ensure that tail is updated to the last node.