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.
Related
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
I am writing a program to check whether a singly linked list is a palindrome or not. For that, I want to reverse the list, and compare it to the original list.
But I am facing the following problem - when I reverse the list, the head pointer of the original list gets modified, and points to NULL.
So, when I have the following original list, following happens after reversing the original list:
Original list: 1->1->2->1->NULL
Reversed list: 1->2->1->1->NULL
But, after calling reverseList, the Original list becomes: 1->NULL
This is, because I have the following code to reverse the list:
ListNode* reverseList(ListNode* head)
{
ListNode* temp = head;
ListNode* temp1 = temp;
ListNode* current = NULL, * nextNode = NULL;
if (temp)
current = temp->next;
if (current)
nextNode = current->next;
while (current)
{
current->next = temp;
temp = current;
current = nextNode;
if (current)
nextNode = current->next;
}
temp1->next = NULL;
return temp;
}
As soon as I do temp1->next = NULL in the above reverseList function (the second last line in the function), the head of the original list is modified and the original list now points to 1->NULL, instead of 1->1->2->1->NULL.
Below if the full code, that calls the function reverseList:
struct ListNode
{
int val;
ListNode* next;
ListNode(int x):val(x),next(NULL){}
};
ListNode* reverseList(ListNode* head)
{
ListNode* temp = head;
ListNode* temp1 = temp;
ListNode* current = NULL, * nextNode = NULL;
if (temp)
current = temp->next;
if (current)
nextNode = current->next;
while (current)
{
current->next = temp;
temp = current;
current = nextNode;
if (current)
nextNode = current->next;
}
temp1->next = NULL;
return temp;
}
bool isPalindrome(ListNode* head) {
//reverse the Linked list and then compare the two lists.
if (head == NULL)
return true;
ListNode* head1 = head;
ListNode* head2 = reverseList(head);
while (head1 && head2)
{
if (head1->val != head2->val)
return false;
head1 = head1->next;
head2 = head2->next;
}
return true;
}
int main()
{
ListNode* head = new ListNode(1);
head->next = new ListNode(1);
head->next->next = new ListNode(2);
head->next->next->next = new ListNode(1);
head->next->next->next->next = NULL;
bool palindrome = isPalindrome(head);
cout << palindrome << endl;
return 0;
}
So, when the reverseList function returns, following happens in isPalindrome function:
head2 is set to: 1->2->1->1->NULL
head and head1 are set to 1->NULL
And I can no longer compare the two linked lists to check if they are palindromes of each other (since the comparison will give me wrong result).
This all is happening because I set temp1->next=NULL in the reverseList function.
Do you know how I should properly terminate the list in reverseList function, such that it does not effect the original list?
Thanks a lot!
Following is the corrected code, where I incorporated the Deep Copy of the original list (in isPalindrome function):
struct ListNode
{
int val;
ListNode* next;
ListNode(int x):val(x),next(NULL){}
};
ListNode* reverseList(ListNode* head)
{
ListNode* temp = head;
ListNode* temp1 = temp;
ListNode* current = NULL, * nextNode = NULL;
if (temp)
current = temp->next;
if (current)
nextNode = current->next;
while (current)
{
current->next = temp;
temp = current;
current = nextNode;
if (current)
nextNode = current->next;
}
temp1->next = NULL;
return temp;
}
bool isPalindrome(ListNode* head) {
//reverse the Linked list and then compare the two lists.
if (head == NULL)
return true;
ListNode* head1 = head;
ListNode* temp1 = NULL, *temp2=NULL;
bool firstEntry = true;
//Deep Copy
temp2 = temp1 = new ListNode(head1->val);
while (head1->next)
{
temp1->next = new ListNode(head1->next->val);
temp1 = temp1->next;
head1 = head1->next;
}
temp1->next = NULL;
ListNode* head2 = reverseList(head);
while (temp2 && head2)
{
if (temp2->val != head2->val)
return false;
temp2 = temp2->next;
head2 = head2->next;
}
return true;
}
int main()
{
ListNode* head = new ListNode(1);
head->next = new ListNode(1);
head->next->next = new ListNode(2);
head->next->next->next = new ListNode(1);
head->next->next->next->next = NULL;
bool palindrome = isPalindrome(head);
cout << palindrome << endl;
return 0;
}
I want to generate a random doubly linked list with a fixed length that is chosen by the user.
The list would insert the first value at the head and then all of the other values at the end of the list but it doesn't correctly adjust the pointers.
Head and tail nodes are both initialized in main to NULL.
Random values work, the problem is with the pointers since at the second iteration the tail stays the same as the head, meaning the list is not increasing.
void GenRandSeq(struct Node* &head, struct Node* &tail, int len){
int i = 0;
std::mt19937 rng;
std::uniform_int_distribution<uint32_t> uint_dist(0,10000);
while (i < len){
Node* newNode = new Node();
int new_el = uint_dist(rng);
newNode->key = new_el;
newNode->prev = NULL;
newNode->next = NULL;
if (head == NULL){
tail = newNode;
head = newNode;
}
else{
if (tail != NULL){
newNode->next = NULL;
newNode->prev = tail;
tail->next = newNode;
}
else
tail = newNode;
}
i++;
}
}
I don't see what I'm missing in the code.
You are not setting tail correctly.
When head and tail are both not null (which should always be true when the list is not empty), you are not updating the tail to point at the newly created node. The assignment of tail needs to be moved out of the else statement. You are appending new nodes to the end of the list, so the tail must be updated on every loop iteration.
Try something more like this instead:
void GenRandSeq(Node* &head, Node* &tail, int len){
std::mt19937 rng;
std::uniform_int_distribution<uint32_t> uint_dist(0,10000);
while (len > 0){
Node* newNode = new Node;
newNode->key = uint_dist(rng);
newNode->prev = tail;
newNode->next = nullptr;
if (!head){
head = newNode;
}
if (tail){
tail->next = newNode;
}
tail = newNode;
--len;
}
}
Which can then be streamlined a little bit further by eliminating the if statements inside the loop:
void GenRandSeq(Node* &head, Node* &tail, int len){
std::mt19937 rng;
std::uniform_int_distribution<uint32_t> uint_dist(0,10000);
Node **next = (tail) ? &(tail->next) : &head;
while (len > 0){
Node *newNode = new Node;
newNode->key = uint_dist(rng);
newNode->prev = tail;
newNode->next = nullptr;
*next = newNode;
tail = newNode;
next = &(newNode->next);
--len;
}
}
I don't yet understand fully how linked lists and nodes in C/C++ work, but this is the function I use to add nodes to a list.
void AddNode(Node* head, int new_data)
{
Node* new_node = new Node();
Node *last = head;
new_node->data = new_data;
new_node->next = NULL;
if (head == NULL)
{
head = new_node;
return;
}
while (last->next != NULL)
{
last = last->next;
}
last->next = new_node;
}
The first element in the list will always be 0, what am I doing wrong?
In c++ , you must update
Node *last = head;
to
Node *& last = head;
In C, you must update
Node *last = head;
to
Node ** last = head;
I used the function AddNode as bellow:
Node* head = new Node();
AddNode(head, 1);
And i get the same problem like you.Because the first element will never change.There are two modify
(1) return the head
Node* AddNode(int new_data)
{
Node* head = NULL;
Node* new_node = new Node();
Node *last = head;
new_node->data = new_data;
cout << "-->" << new_node->data << endl;
new_node->next = NULL;
if (head == NULL)
{
head = new_node;
return head;
}
while (last->next != NULL)
{
last = last->next;
}
last->next = new_node;
return head;
}
use like this:
Node* head = AddNode(1);
(2)pass the head address,because you want to change it
void AddNode(Node** head, int new_data)
{
Node* new_node = new Node();
Node *last = *head;
new_node->data = new_data;
cout << "-->" << new_node->data << endl;
new_node->next = NULL;
if (*head == NULL)
{
*head = new_node;
return;
}
while (last->next != NULL)
{
last = last->next;
}
last->next = new_node;
}
use lie this:
Node* head = NULL;
AddNode(&head, 1);
Hope it's useful for you.
I don't understand why the display() func show me only the first member of the list. I think I did a mess with pointers, but I can't understand where. I have compared this to other linked list source and it seem that the function is written in the-good-way.
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
struct Node
{
int Data;
Node * next;
};
void initNode(struct Node *head,int n);
void AddNode(int n,Node* head);
void display(Node* head);
int main()
{
Node * head = new Node;
initNode(head,5);
display(head);
AddNode(10,head);
display(head);
AddNode(15,head);
display(head);
cin.get();
return 0;
}
void AddNode(int n,Node * head)
{
Node * node = new Node;
node->Data = n;
node->next = NULL;
Node * nextNode = head;
while(nextNode)
{
if(nextNode->next == NULL)
{
nextNode->next = node;
}
nextNode = nextNode->next;
}
}
void display(Node * head)
{
while(head)
{
cout << head->Data << " "<<endl;
head = head->next;
}
}
void initNode(struct Node *head,int n)
{
head->Data = n;
head->next = NULL;
}
Your AddNode method is over-complicated. Do something like this to add to the front:
Node *AddNode(int n, Node *head)
{
Node *newNode = new Node;
newNode->Data = n;
newNode->next = head;
return newNode;
}
Or to add to the end:
Node *AddNode(int n, Node *head)
{
Node *newNode = new Node;
newNode->Data = n;
newNode->next = NULL;
if(head == NULL) return newNode;
Node *current = head;
while(current->Next != NULL)
{
current = current->Next;
}
current->Next = newNode;
return head;
}
Doing AddNode this way you will not need initNode. Now you can just day:
Node *head = NULL;
head = AddNode(5, head);
head = AddNode(10, head);
head = AddNode(15, head);
display(head);
Also, you don't need to say struct Node in C++, it is only required in C.
Function AddNode has an infinite loop.
void AddNode(int n,Node * head)
{
Node * node = new Node;
node->Data = n;
node->next = NULL;
Node * nextNode = head;
while(nextNode)
{
if(nextNode->next == NULL)
{
nextNode->next = node;
}
nextNode = nextNode->next;
}
}
Let assume that you have only one element that is the head (after a call of initNode). And as the result head->next = NULL. So inside the body of the loop you make assignment
nextNode->next = node;
Now head->next is not equal to NULL. So after statement
nextNode = nextNode->next;
nextNode caontains the new element. As it is not equal to NULL then iteration of the loop will be repeated. Again for the new node its data member next is equal to NULL. And you add it to it itself.
Now you have no any element in the list that would have data member next equal to NULL. So you are unable to add new elements. The last element contains reference to itself.
You could write the function the following way
void AddNode(int n,Node * head)
{
Node * node = new Node;
node->Data = n;
node->next = NULL;
Node * nextNode = head;
while( nextNode -> next ) nextNode = nextNode->next;
nextNode->next = node;
}
But take into account that it is assumed that head is not equal to NULL. otherwise the function will be incorrect. I think that you should redesign you list.
In your AddNode function add a break in the if block.
void AddNode(int n,Node * head)
{
Node * node = new Node;
node->Data = n;
node->next = NULL;
Node * nextNode = head;
while(nextNode)
{
if(nextNode->next == NULL)
{
nextNode->next = node;
break;
}
nextNode = nextNode->next;
}
}
Now it should add properly.
Node * nextNode = head;
while(nextNode)
{
if(nextNode->next == NULL)
{
nextNode->next = node;
}
nextNode = nextNode->next;
}
The problem is this block of code. When you find the end of the list (if nextNode->next == NULL) you need to break out of the loop. Try it with an example to convince yourself.
Each time you add a node you traverse from head to the end of the list
You can change it as follows
void AddNode(int n){
Node *node=new Node;
node->data=n;
node->next=NULL; //head is global
if(head==NULL){
t=head=n;
}
else{
t->next=n; //t is global
t=t->next;
}
}