Search function - Linked List [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am working on a search function to search a linked list for a specific value. When it finds that value I want to output its position. I cannot seem to get past the first node without getting an error. I think something is wrong with the loops but I'm not sure what.
int NumberList::search(double num)
{
ListNode *nodePtr;
nodePtr=head;
int i=0;
while (nodePtr->value!= NULL)
{
i=i+1;
if (nodePtr->value==num)
return i;
else
nodePtr=nodePtr->next;
}
return 0;
}

Your while loop is incorect. You should be testing that nodePtr is not NULL
while (nodePtr != NULL)
{
i = i + 1;
if (nodePtr->value == num)
return i;
else
nodePtr = nodePtr->next;
}
Also this is a perfect reason to use nullptr instead of NULL when dealing with pointers. If you had use nullptr then
while (nodePtr->value!= nullptr)
Would give you a compiler error as you cannot compare a double to nullptr

I do not know how the corresponding class is defined but I think in any case the function should look the following way
int NumberList::search(double num)
{
ListNode *nodePtr = head;
int i = 0;
while ( nodePtr != NULL && nodePtr->value != num )
{
++i;
nodePtr = nodePtr->next
}
return nodePtr != NULL ? ++i : 0;
}
It is difficult to compare exactly two floating numbers. You should use a method of comparison that for example takes into account an epsilon.
Take also into account that other functions as for example the function that adds nodes to the list can also be wrong.:)

Your while loop condition should be:
while (nodePtr != NULL)
Because of this error you are likely visiting a node who's pointer is NULL And by dereferencing this you are causing undefined behavior.

You don't show the ListNode type but I'm guessing the value is a double.
while (nodePtr->value != NULL)
Here you're checking if the double is not NULL (NULL is essentially 0). But you need to test nodePtr against NULL.
Note: Consider using nullptr instead of NULL, nullptr is the type safe value for a null pointer and would have produced a compilation error.
error: invalid operands of types 'double' and 'std::nullptr_t' to binary 'operator=='

Related

I have created function to modify a node in Linkedlist in C++ but its not working: [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
This Function is Created in LinkedList to modify a node at a given position. But, this function is not working properly and it is giving some random values.
void update_data(int old, int new_data) {//Function toupdate node
Node *curr=header;//Data members
int pos = 0;
while(curr->next!=NULL) {
if(curr->isbn == old)
{
curr->isbn = new_data;
cout<<old<<" Found at position "<<pos<<" Replaced with "<<new_data<<endl;;
}
curr = curr->next;
pos++;
}
}
For starters the variable pos is not used within the function.
Secondly the condition of the while loop
while(curr->next!=NULL) {
is incorrect and in general can invoke undefined behavior because the pointer header can be equal to nullptr. And moreover if the list contains only one node pointed to by the pointer header and its data member isbn is equal to the value of the variable old it will not be changed.
The function should not output any message.
The function can look the following way
void update_data( int old, int new_data )
{//Function toupdate node
for ( Node *curr = header; curr != nullptr; curr = curr->next )
{
if ( curr->isbn == old )
{
curr->isbn = new_data;
}
}
}

Insert in Binary Serach Tree Unhandled exception thrown [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a function to insert nodes in a binary search tree. I get a crash when I try to insert a node. I use the debugger from VS and it tells me Unhandled exception thrown: write access violation.
m_father was nullptr.
Here is my function to insert:
NOD *INSERT(NOD k)
{
NOD *temp = new NOD(k);
NOD *m_father = NULL;
NOD *x = root;
while (x != NULL)
{
m_father = x;
if (m_father->m_key > x->m_key)
{
x = x->m_right_child;
}
x = x->m_left_child;
}
if (root == NULL)
root = temp;
else if (temp->m_right_child->m_key > m_father->m_key)
{
m_father->m_right_child = temp;
}
m_father->m_left_child = temp;
temp->m_father = m_father;
return 0;
}
And here is how i try to insert a node:
int temp_nod;
cin >> temp_nod;
binary_tree.INSERT(temp_nod);
else if (temp->m_right_child->m_key > m_father->m_key)
temp is copy-constructed here (is it the expected behaviour?). If it's created from a new node, m_right_child might not be assigned yet, so you try to dereference a nullptr.
I'm not sure, but you did you want to check temp key here? I don't see much reason to check child key when choosing the correct place in BST.
Also, as noted in the comments, you assign m_father->left_child always, without a condition. This happens even in an empty list, so again we try to dereference a nullptr. I suppose it should look more like this:
if (root == NULL)
root = temp;
else if (temp->m_right_child->m_key > m_father->m_key)
{
m_father->m_right_child = temp;
temp->m_father = m_father;
}
else
{
m_father->m_left_child = temp;
temp->m_father = m_father;
}
As a side note, if your function does not return anything useful, just make it void.
If root == NULL the only assignment to m_father would be NOD *m_father = NULL;, before the statement m_father->m_left_child = temp;.
EDIT: (Because if root == NULL, then x would also be NULL, so the while loop would not be executed)
EDIT2: else if (temp->m_right_child->m_key > m_father->m_key) => m_father->m_left_child = temp; - the former will not be evaluated if root == NULL, since it is an else if to an if that was true.

Union of two linked lists [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am trying to develop a friend function for the union of two link lists. Compiler keeps giving me an error saying that Node was not declared in this scope, as well as p,q not declared in this scope. So I added List::Node, but it is not performing the union still
const List getunion(const List&a, const List&b) {
List::Node * p=a.list;
List::Node* q=b.list;
List result;
while (q!=NULL && p!=NULL) {
if(q->value==p->value) {
result.insert(q->value);
q=q->next;
p=p->next;
}
q=q->next;
p=p->next;
}
return result;
}
void insert(int x) {
Node* tmp=new Node;
tmp->value=x;
if(list==NULL || list->value >x){
tmp->next=list;
list=tmp;
}
else {
Node *curr=list;
while (curr->next !=NULL && curr->next->value < x) {
curr=curr->next;
}
tmp->next=curr->next;
curr->next=tmp;
}
Note my insert function adds Nodes in ascending order, and I have tried it out and it does work on test cases, it's when i implement the union function that things go astray...
I take it that you fixed the compile error and now you are wondering why it doesn't work.
You're not merging these two lists correctly. The issues are:
You only insert an item if it's in both lists - that's intersection, not union.
You are advancing both pointers simultaneously.
You need to merge one or the other:
while ( q && p ) {
if( q->value < p->value ) {
result.insert(q->value);
q = q->next;
} else if( q->value > p->value ) {
result.insert(p->value);
p = p->next;
} else {
result.insert(q->value);
q = q->next;
p = p->next;
}
}
Now, once either of those list pointers reaches the end, you still need to add the remaining elements from the other. This will do the trick:
for(; q; q = q->next) result.insert(q->value);
for(; p; p = p->next) result.insert(p->value);
Make sure, also, that you have defined a copy constructor for List. It looks like you're doing your own memory allocation in there, so you must follow the Rule of Three.
Firstly, I am not sure what you code is intended to be doing.
It seems you expect the input to be 2 lists, which you step thru in parallel, constructing a third list if the corresponding values are matching.
This is more like an intersection than a union, tho its harsher than that, since it cares about position.
The insert seems to be a sorted insert.
Anyway, this part is certainly wrong:
if(q->value==p->value) {
result.insert(q->value);
q=q->next;
p=p->next;
}
Remove these q=q->next and p=p->next.
These are causing a double step, since its done inside the if statement, and outside.
Double stepping is bad, since it can take you past the end of a list, causing crashes.

inserting integer into linked list in ascending order [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm trying to insert a new element into a linked list in ascending order, my code for inputting 3,1,9,7,5 outputs 1,1,1,1,1,1 however the output I want is 1,3,5,7,9
head is actually in a private instance variable for the class List and this is a member function
It is called as:
List a;
a.insertInOrder(3); a.insertInOrder(1); a.insertInOrder(9); a.insertInOrder(7); insertInOrder(5);
the output is 1,1,1,1,1
void List::insertInOrder( int data) {
Node *newNode = new Node;
newNode->data=data;
if(head == null || head->data > data) {
newNode->next = head;
head = newNode;
}
else{
Node *cur = head;
while(cur->next != null && current->next->data < data)
cur = cur->next;
newNode->next = cur->next;
cur->next = newNode;
}
}
Seems mostly valid, but:
while(cur->next != null && current->next->data < data)
Here you refer to "cur" in one clause, and "current" in the other clause.
"current' does no appear to exist, but perhaps you have globals?
But, even that would just screw up the ordering, so I suspect the error is in your output code, rather than your sort code.
You aren't incrementing nextC, so your while loop is comparing data to just one number. cur does nothing since you aren't using it in the conditional like you are with nextC.
while(cur->next != null && nextC->data < data) //nextC->data is set only once
cur = cur->next; //cur incremented, but for what?

LinkedList used in an interview's test

[EDIT]Fixed my code. Is while(temp != NULL), not while(temp->next != NULL). Sorry to insert wrong code.
Today I've participated an online programming test. The interviewer used Codility to evaluate my code and the other interviewees.
At some moment a question about Linked list was made. It's about to count how many items a linked list has.
I did the only possible approach to do this, AFAIK:
//This is struct declaration
struct SomeStruct
{
int value;
SomeStruct* next;
}
int elementCount(SomeStruct* list)
{
int count = 0;
if(list != NULL)
{
SomeStruct* temp = list;
while(temp != NULL)
{
count++;
temp = temp->next;
}
}
return count;
}
I remember when I send this code as answer for this question, Codility points me out that this solution is wrong because its consume too much time to execute the task.
In my head and in this thread on SO there's no other way to get size of linked list without traversing it, not in a simple way.
Is there a problem with Codility when it says this solution is wrong? Or there are another approaches?
PS: the test allowed using of STL
Your solution is incorrect, since it returns 1 less than the actual count. Just try applying it to a list with 1 element.
Why did you come up with this strange two-tiered structure with an if and and a cycle that checks temp->next? Why not just
unsigned elementCount(const SomeStruct *list)
{
unsigned count = 0;
for (const SomeStruct *temp = list; temp != NULL; temp = temp->next)
++count;
return count;
}
I suspect that you decided to treat the element pointed by the list as the unused and reserved "header" element. Indeed, sometimes it might make sense to do implement lists that way. But I see nothing like that stated in your post. Did they tell you to treat it that way specifically?
well you don't have to evaluate the indirection temp->next twice for each iteration.
you can simply do
int count( SomeStruct const* pNode )
{
int result = 0;
while( pNode != 0 )
{
++result;
pNode = pNode->next;
}
return result;
}
Also, as WhozCraig notes, your code was logically wrong (yielding an off by one result), not just potentially inefficient.
Codility may be using a circularly linked list to check, in this case, your code will never end.
Using STL trivilailzes this though, as it has a List<> with a size method.