Finding an Element in a LinkedList - C++ - c++

I am trying to write a function find(Node* node, int valueInput) that starts at the given node and returns the index of the node with the value valueInput, and return -1 if valueInput does not exist.
Here is the code
#include <iostream>
class Node {
public:
int value;
Node* next = NULL;
};
int find(Node* node, int valueInput)
{
Node* tempNode = node;
int count = 0;
while (tempNode != NULL)
{
if (tempNode->value == 0)
{
break;
}
++count;
tempNode = tempNode->next;
}
return -1;
}
int main()
{
int valueInput, currentValue;
int listValues;
char arrow;
Node* node1, * previous, * head;
std::cin >> valueInput;
std::cin >> currentValue;
node1 = new Node();
node1->value = currentValue;
node1->next = NULL;
previous = node1;
head = node1;
while (std::cin)
{
std::cin >> arrow;
std::cin >> arrow;
std::cin >> currentValue;
node1 = new Node();
node1->value = currentValue;
previous->next = node1;
previous = node1;
}
std::cout << find(head, valueInput);
}
Currently, my program returns -1 always
Sample input and outputs:
Sample Input:
5
1->2->5
Sample Output:
2

That's because your code only has a return -1 statement. You should return count instead of break. Also, you are always comparing against 0 instead of the valueInput
int find(Node* node, int valueInput)
{
Node* tempNode = node;
int count = 0;
while (tempNode != nullptr)
{
if (tempNode->value == valueInput)
{
return count;
}
++count;
tempNode = tempNode->next;
}
return -1;
}
You should also be using nullptr instead of NULL

Related

Cloning a linked list where each node has a random pointer to any other node in linked list

Please help me find what is wrong with my code
(1).
You are given a Singly Linked List with N nodes where each node next pointing to its next node. You are also given M random pointers , where you will be given M number of pairs denoting two nodes a and b i.e. a->arb = b.
The task is to complete the function copyList() which takes one argument the head of the linked list to be cloned and should return the head of the cloned linked list.
NOTE : If their is any node whose arbitrary pointer is not given then its by default null.
I tried to write code for the above problem..but it is not working
// { Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *next;
Node *arb;
Node(int x) {
data = x;
next = NULL;
arb = NULL;
}
};
void print(Node *root) {
Node *temp = root;
while (temp != NULL) {
int k;
if (temp->arb == NULL)
k = -1;
else
k = temp->arb->data;
cout << temp->data << " " << k << " ";
temp = temp->next;
}
}
Node *copyList(Node *head);
void append(Node **head_ref, Node **tail_ref, int new_data) {
Node *new_node = new Node(new_data);
if (*head_ref == NULL) {
*head_ref = new_node;
} else
(*tail_ref)->next = new_node;
*tail_ref = new_node;
}
bool validation(Node *head, Node *res, Node *cloned_addr,
Node *generated_addr) {
if (generated_addr == cloned_addr) return false;
Node *temp1 = head;
Node *temp2 = res;
int len1 = 0, len2 = 0;
while (temp1 != NULL) {
len1++;
temp1 = temp1->next;
}
while (temp2 != NULL) {
len2++;
temp2 = temp2->next;
}
/*if lengths not equal */
if (len1 != len2) return false;
temp1 = head;
temp2 = res;
while (temp1 != NULL) {
if (temp1->data != temp2->data) return false;
if (temp1->arb != NULL and temp2->arb != NULL) {
if (temp1->arb->data != temp2->arb->data) return false;
} else if (temp1->arb != NULL and temp2->arb == NULL)
return false;
else if (temp1->arb == NULL and temp2->arb != NULL)
return false;
temp1 = temp1->next;
temp2 = temp2->next;
}
return true;
}
/* Driver program to test above function*/
int main() {
int T, i, n, l, k;
Node *generated_addr = NULL;
/*reading input stuff*/
cin >> T;
while (T--) {
generated_addr = NULL;
struct Node *head = NULL, *tail = NULL;
cin >> n >> k;
for (i = 1; i <= n; i++) {
cin >> l;
append(&head, &tail, l);
}
for (int i = 0; i < k; i++) {
int a, b;
cin >> a >> b;
Node *tempA = head;
int count = -1;
while (tempA != NULL) {
count++;
if (count == a - 1) break;
tempA = tempA->next;
}
Node *tempB = head;
count = -1;
while (tempB != NULL) {
count++;
if (count == b - 1) break;
tempB = tempB->next;
}
// when both a is greater than N
if (a <= n) tempA->arb = tempB;
}
/*read finished*/
generated_addr = head;
Node *res = copyList(head);
Node *cloned_addr = res;
cout << validation(head, res, cloned_addr, generated_addr) << endl;
}
return 0;
}
// } Driver Code Ends
/* the node structure is as follows
struct Node {
int data;
Node *next;
Node *arb;
Node(int x) {
data = x;
next = NULL;
arb = NULL;
}
};
*/
// Should return the head of the copied linked list the
// output will be 1 if successfully copied
Node *copyList(Node *head) {
if(!head)
return nullptr;
Node*q=head;
Node*clone=new Node(q->data);
clone->next=0;
clone->arb=q->arb;
Node*p=clone;
Node*r=q;
q=q->next;
while(q)
{
r->next=p;
p->next=new Node(q->data);
p=p->next;
p->next=0;
p->arb=q->arb;
r=q;
q=q->next;
}
r->next=p;
p=clone;
while(p)
{
if(p->arb)
p->arb=p->arb->next;
p=p->next;
}
return clone;
}
The pointers inside the list cannot be assigned until you have constructed the cloned list itself, because until then the nodes to point will not exist.
Therefore, you need two iterations: the first one to clone the list and make a dictionary that associates the original node with the clone, and the second one to update the pointers. The code would look like this:
Node *copyList(Node *head) {
if(!head)
return nullptr;
Node* it1 = head;
Node* clone = new Node;
Node* it2 = clone;
std::map<Node*, Node*> nodeDict;
nodeDict[nullptr] = nullptr;
// first iteration: create the list and the values
while(it1){
it2->data = it1->data;
nodeDict[it1] = it2;
it1 = it1->next;
it2->next = it1 ? new Node: nullptr;
it2 = it2->next;
}
// second iteration: connect the nodes
it1 = head;
it2 = clone;
while(it1){
it2->arb = nodeDict[it1->arb];
it1 = it1->next;
it2 = it2->next;
}
return clone;
}

I'm trying to code a binary search tree using c++ but the program takes only 2 inputs and stops

Notice the //, the program stops taking input and that is the main problem.
root->cand = data;
Here is the full code:
#include <bits/stdc++.h>
using namespace std;
struct node
{
int cand;
node *left;
node *right;
};
class candies
{
node *root;
public:
candies();
int add(int);
int check();
};
candies::candies()
{
root = NULL;
}
int candies::add(int data)
{
if (root == NULL)
{
root->cand = data; //code stops here
root->left = NULL;
root->right = NULL;
}
else
{
node *temp = root;
while (temp != NULL)
{
if (data < temp->cand)
{
temp = temp->left;
}
else
{
temp = temp->right;
}
}
temp = new node;
temp->cand = data;
temp->left = temp->right = NULL;
}
return 1;
}
int candies::check()
{
node *temp;
temp = root;
int data;
cin >> data;
while (temp != NULL)
{
if (temp->cand == data)
{
cout << "YES\n";
return 1;
}
else if (data < temp->cand)
temp = temp->left;
else if (data > temp->cand)
temp = temp->right;
}
cout << "NO\n";
return 0;
}
int main()
{
candies c;
int n;
cin >> n;
while (n--)
{
int data;
cin >> data;
c.add(data);
}
c.check();
}
The member function add is invalid and moreover has undefined behavior.
In this if statement
if (root == NULL)
{
root->cand = data; //code stops here
root->left = NULL;
root->right = NULL;
}
there is used a null-pointer to access memory.
In this else statement
else
{
node *temp = root;
while (temp != NULL)
{
if (data < temp->cand)
{
temp = temp->left;
}
else
{
temp = temp->right;
}
}
temp = new node;
temp->cand = data;
temp->left = temp->right = NULL;
}
the created node temp is not added to the tree. So the program has a memory leak.
The function can be written the following way. It is better to make its return type void. Otherwise the returned value 1 as in your function implementation does not make sense.
class candies
{
node *root;
public:
candies();
void add(int);
int check();
};
//...
void candies::add( int data )
{
node **current = &root;
while ( *current != nullptr )
{
if ( data < ( *current )->cand )
{
current = &( *current )->left;
}
else
{
current = &( *current )->right;
}
}
*current = new node { data, nullptr, nullptr };
}
You are first checking that root is NULL. If it is, you are changing its data. This is not good at all, and will cause a crash.
if (root == NULL)
{
root->cand = data; //code stops here
If root is NULL, you must create a root node first.
if ( root == nullptr ) {
root = new node;
root->cand = data;

Swap the first and last nodes in C++

I'm trying to swap the location of the first and the last node using dev c++, it's an assignment for my grades.
And the following is what I've done so far. I haven't started on the swapping function because I have no idea how.
#include <iostream>
#include <cstdlib>
using namespace std;
// Node class
class Node {
int data;
public:
Node* next;
Node(int d=0){
data = d;
next=NULL;
}
int getData() const{
return data;
}
}; //class Node
void display(Node *start, Node *end)
{
// Temp pointer
Node *tmp = start;
// One node in the list
while (tmp)
{
cout << tmp->getData() << "\t";
tmp=tmp->next;
}
} //display
Node* node;
int main()
{
Node *start, *end, *head, *last, *newNode;
start = end = new Node(5);
for (int n=10; n<=35; n=n+5) {
end->next=new Node(n);
end=end->next;
}
display(start,end);
cin.get();
//delete the first node
head=start;
start = start->next;
delete(head);
display(start,end);
cin.get();
//delete the last node
last = start;
end = start->next;
while(end->next != NULL){
last = end;
end = end->next;
}
last->next = NULL;
delete(end);
display(start,end);
cin.get();
//insert value 3 in front of the node
newNode = new Node(3);
newNode->next = NULL;
newNode->next = start;
start = newNode;
display(start,end);
cin.get();
//insert value 23 in between 20 and 25
int pos = 5;
newNode = new Node(23);
Node *temp;
end = start;
for(int i=1; i<pos-1; i++){
end = end->next;
}
temp = end->next;
end->next = newNode;
newNode->next = temp;
display(start,end);
cin.get();
//here is where the swap function must be performed.
display(start,end); //to display the result
cin.get();
} //main
Find the first, second, last and second last nodes.
first->link = null;
last->link=second;
second_last->link=first;
return last
In case of 2 nodes
first->link=null;
second->link=first;
return second;
You have created a list of nodes. Starting from first.
if( first == NULL)
return ;
else if( first ->next ==NULL)
return first;
else
{
second = first -> next;
if(second ->next == NULL)
{
first->next = NULL;
second->next = first;
return second;
}
else
{
//declare firstcopy,last,second_last
firstcopy = first;
while( firstcopy->next != NULL)
{
second_last = firstcopy;
firstcopy = firstcopy ->next;
last = firstcopy;
}
first->next = null;
last->next=second;
second_last->next=first;
return last;//or you may print the linked list starting from last.
}
}
Code
#include <iostream>
#include <cstdlib>
using namespace std;
// Node class
class Node {
private:
int data;
public:
Node* next;
Node(int d=0):data(d),next(NULL)
{
}
int getData() const{
return data;
}
Node operator=(const Node& b) {
Node box(b.getData());
box.next=b.next;
return box;
}
}; //class Node
void display(Node *start)
{
while(start!=NULL )
{
cout<<start->getData()<<" ";
start=start->next;
}
cout<<endl;
} //display
Node* swap(Node *first){
if( first == NULL)
return first;
else if( first ->next ==NULL)
return first;
else
{
Node *second = first -> next;
if(second ->next == NULL)
{
first->next = NULL;
second->next = first;
return second;
}
else
{
Node* firstcopy,*last,*second_last;
firstcopy=first;
while( firstcopy->next != NULL)
{
second_last = firstcopy;
firstcopy = firstcopy ->next;
last = firstcopy;
}
first->next = NULL;
last->next=second;
second_last->next=first;
return last;//or you may print the linked list starting from last.
}
}
}
Node* node;
int main()
{
Node *start, *end;
start = end = new Node(5);
for (int n=10; n<=35; n=n+5) {
end->next=new Node(n);
end=end->next;
}
display(start);
cin.get();
start = swap(start);
display(start);
cin.get();
} //main
#include <iostream>
#include <cstdlib>
using namespace std;
// Node class
class Node {
int data;
public:
Node* next;
Node(int d=0){
data = d;
next=NULL;
}
int getData() const{
return data;
}
}; //class Node
void display(Node *start, Node *end)
{
// Temp pointer
Node *tmp = start;
// One node in the list
while (tmp)
{
cout << tmp->getData() << "\t";
tmp=tmp->next;
}
} //display
void swap(Node *first, *second, *second_last, *firstcopy){
first->next = NULL;
last->next=second;
second_last->next=first;
return last;
if( first == NULL)
return ;
else if( first ->next ==NULL)
return first;
else{
second = first -> next;
if(second ->next == NULL)
{
first->next = NULL;
second->next = first;
return second;
}
else
{
//declare firstcopy,last,second_last
firstcopy = first;
while( firstcopy->next != NULL)
{
second_last = firstcopy;
firstcopy = firstcopy ->next;
last = firstcopy;
}
first->next = NULL;
last->next=second;
second_last->next=first;
return last;//or you may print the linked list starting from last.
}
}
}
Node* node;
int main()
{
Node *start, *end, *head, *last, *newNode;
start = end = new Node(5);
for (int n=10; n<=35; n=n+5) {
end->next=new Node(n);
end=end->next;
}
display(start,end);
cin.get();
//delete the first node
head=start;
start = start->next;
delete(head);
display(start,end);
cin.get();
//delete the last node
last = start;
end = start->next;
while(end->next != NULL){
last = end;
end = end->next;
}
last->next = NULL;
delete(end);
display(start,end);
cin.get();
//insert value 3 in front of the node
newNode = new Node(3);
newNode->next = NULL;
newNode->next = start;
start = newNode;
display(start,end);
cin.get();
//insert value 23 in between 20 and 25
int pos = 5;
newNode = new Node(23);
Node *temp;
end = start;
for(int i=1; i<pos-1; i++){
end = end->next;
}
temp = end->next;
end->next = newNode;
newNode->next = temp;
display(start,end);
cin.get();
//swap the position of the first and the last node
swap(&first, &second, &second_last, &firstcopy);
display(start,end);
cin.get();
} //main

Access violation reading location 0xCCCCCCCC error in linklist

Why does the above error occur when calling showNode()?
#include<iostream>
#define NULL 0
using namespace std;
class myNode{
private:
int data;
myNode* link;
myNode* first;
public:
myNode(){
data=0;
link=NULL;
first=NULL;
}
void insertNode(int value, int iposition){
myNode n;
if (iposition==1)
{
first=&n;
cout<<first<<endl;
n.data=value;
n.link=NULL;
}
if (iposition>1)
{
int nodeCounter=1;
myNode* temp=first;
while (temp->link != NULL)
{
nodeCounter++;
}// this while counts the number of inserted nodes.
if (iposition>nodeCounter)//if the position of the new node is greater than number of inserted node,
//it will be inserted at the end.
{
cout<<"Node will be inserted at end."<<endl;
myNode* ieTemp=first;
while (ieTemp->link != NULL)
{
ieTemp=ieTemp->link;
cout<<ieTemp->data<<endl;
}
ieTemp->link=&n;
n.data=value;
n.link=NULL;
cout<<&n<<" ";
}
else
{
myNode* imTemp=first;
while (iposition-1)
{
imTemp=imTemp->link;
iposition--;
}
n.link=imTemp->link;
n.data=value;
imTemp->link=&n;
}
}
}//end insertNode
void showNode(){
myNode* sTemp=first;
while (sTemp != NULL)
{
cout<<sTemp->data<<" ";
sTemp=sTemp->link;
}
}//end showNode
};
int main(){
myNode a;
a.insertNode(10,1);
a.insertNode(20,2);
a.insertNode(25,3);
a.insertNode(30,4);
a.insertNode(40,5);
a.showNode();
system("pause");
}
First you must declare myNode *n = new myNode(); because you use it outside of insertNode function. Second you may want to check if first node exist to avoid error on inserting first node on any other position than 1 (in your case if your first insert will be like inserNode(x, y != 1) will throw an error because you try to access first node (here: while (temp->link != NULL))) but this node don't exist.
This is what I think you want:
void insertNode(int value, int iposition){
myNode *n = new myNode();
myNode *cur = first;
//insert first node or on first position
if (cur == NULL || iposition <= 1) {
n->data = value;
if (cur == NULL) { //first node
n->link = NULL;
}
else { //first position
n->link = first;
}
first = n;
return;
}
for (int i = 1; i < iposition - 1; i++) { //find given position
if (cur->link == NULL) { //if end
n->data = value;
n->link = NULL;
cur->link = n;
return;
}
cur = cur->link;
}
//here we are on position = iposition-1
n->data = value;
n->link = cur->link;
cur->link = n;
}//end insertNode

After exiting from function, nodes aren't saved

My program should create a linked list and show it. My problem is when the addelemnt_end function ends, it doesn't update head and last.
I tried with debug and when my function is done, the info and next part from head and last are "unable to read memory".
struct node{
int info;
node *next;
};
node *head, *last;
void addelement_end(node *head, node *last, int element)
{if (head == NULL)
{ node *temp = new node;
temp->info = element;
temp->next = NULL;
last = temp;
head = temp;
}
else {node*temp = new node;
last->next = temp;
temp->info = element;
temp->next = NULL;
last = temp;
}
}
void show(node* head, node *last)
{
if (head==NULL)
cout << "Empty list";
else
while (head != NULL)
{
cout << head->info << " ";
head = head->next;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int x, n, i;
cout << "how many numbers";
cin >> n;
head = last = NULL;
for (i =1; i <= n; i++)
{
cin >> x;
addelement_end(head, last, x);
}
show(head, last);
return 0;
}
It's a very common error. Here is a similar illustration of the problem:
int change_a(int a) {
a = 42;
}
int main() {
int a = 10;
change_a(a);
printf("%d\n", a);
return 0;
}
This will print 10 because in the function change_a you are only modifying a copy of the value contained in the variable a.
The correct solution is passing a pointer (or using a reference since you are using C++).
int change_a(int *a) {
*a = 42;
}
int main() {
int a = 10;
change_a(&a);
printf("%d\n", a);
return 0;
}
But maybe you're going to tell me: "I'm already using a pointer!". Yes, but a pointer is just a variable. If you want to change where the pointer points, you need to pass a pointer to that pointer.
So, try this:
void addelement_end(node **head, node **last, int element)
{
if (*head == NULL)
{ node *temp = new node;
temp->info = element;
temp->next = NULL;
*last = temp;
*head = temp;
}
else {
node *temp = new node;
(*last)->next = temp;
temp->info = element;
temp->next = NULL;
*last = temp;
}
}