Merging List Alternatively - c++

In the following code i am trying to merge 2 list alternatively and than printing them in reverse order. But my code is not giving correct output it is just merging the last element of the second list.
input:
1
3
1 3 5
3
2 4 6
Actual Output:
5 6 3 1
Expected Output:
5 6 3 4 1 2
Can someone please tell me whats the problem in my code....
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int data;
struct Node *next;
};
void push(struct Node ** head_ref, int new_data)
{
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList(struct Node *head)
{
struct Node *temp = head;
while (temp != NULL)
{
cout<<temp->data<<' ';
temp = temp->next;
}
cout<<' ';
}
void mergeList(struct Node **head1, struct Node **head2);
int main()
{
int T;
cin>>T;
while(T--){
int n1, n2, tmp;
struct Node *a = NULL;
struct Node *b = NULL;
cin>>n1;
while(n1--){
cin>>tmp;
push(&a, tmp);
}
cin>>n2;
while(n2--){
cin>>tmp;
push(&b, tmp);
}
mergeList(&a, &b);
printList(a);
printList(b);
}
return 0;
}
void mergeList(struct Node **p, struct Node **q)
{
struct Node*temp1=*p,*temp2=*q,*t1,*t2;
while(temp1!=NULL)
{
if(temp2==NULL)
break;
t1=temp1->next;
t2=temp2;
temp1->next=t2;
t2->next=t1;
temp1=t1;
*q=temp2->next;
temp2=*q;
}
}

To be honest, I'm really not sure what exactly you are doing in the mergeList function. The code is pretty cancerous so I did not take the liberty of verifying the correctness. I have renamed a few variables and re-written the code, so you can take this as a reference point and see what's wrong with your code.
void mergeList(struct Node **p, struct Node **q)
{
struct Node *a = *p, *b = *q, *next_a, *next_b;
while(a != NULL)
{
if(b == NULL)
break;
next_a = a->next;
a->next = b;
next_b = b->next;
b->next = next_a;
a = next_a;
b = next_b;
}
}
Hope this helps. Cheers.

Related

I am not getting how to concatenate two Linked List

I am not getting how to run the concatenate function using both Node and LinkedList as classes. If anyone knows how to do it, please let me know.
Here I have created two classes one for linked list and the former one for Node creation.
Using create function and passing array as Linked list input. Also, I am getting the headref using getHead() and getHead2() functions which give the starting pointer of first and second Linked List respectively.
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node* next;
Node(){
data=0;
next=NULL;
}
Node(int data){
this->data=data;
this->next=NULL;
}
};
class LL{
Node* first, *second;
public:
LL(){
first=second=NULL;
}
void create(int arr[], int n){
Node* t, *last;
first=new Node();
first->data= arr[0];
first->next=NULL;
last=first;
for(int i=1;i<n;i++){
t=new Node();
t->data=arr[i];
t->next=NULL;
last->next=t;
last=t;
}
}
void create2(int arr[], int n){
Node* t, *last;
second=new Node();
second->data= arr[0];
second->next=NULL;
last=second;
for(int i=1;i<n;i++){
t=new Node();
t->data=arr[i];
t->next=NULL;
last->next=t;
last=t;
}
}
Node* getHead(){
return first;
}
Node* getHead2(){
return second;
}
void display(Node* p){
while(p){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void concatLL(){
Node* p=first;
while(p->next){
p=p->next;
}
p->next=second;
second=NULL;
}
};
int main()
{
LL l,l2;
int arr[]={1,2,3,4,5,6,7};
int arr2[]={2,5,7,8,9};
int n=sizeof(arr)/sizeof(arr[0]);
int n2=sizeof(arr2)/sizeof(arr2[0]);
l.create(arr,n);
l2.create2(arr2,n2);
cout<<"Displaying first LL"<<endl;
l.display(l.getHead());
cout<<"Displaying second LL"<<endl;
l2.display(l2.getHead2());
cout<<"Displaying Linked list after concatination"<<endl;
l.concatLL();
l.display(l.getHead());
return 0;
}
p is equal to NULL when executing p->next=second; in concatLL() causing undefined behaviour since the while loop runs until p == NULL. You should use while(p->next) instead of while(p) and check that first is not a null pointer before.
A linked list is still a Node, and as others said, at the end of your while loop p is pointed to NULL. You can't NULL->second=second neither NULL=second, so change your while loop stop condition:
void concatLL(){
Node* p=first;
while(p->next){
p=p->next;
}
p->next=second;
second=NULL;
}
};
Here is my solution:
#include <iostream>
using namespace std;
struct Node {
Node* next;
int value;
Node(int value) {
this->value = value;
this->next = NULL;
}
Node(int n, int a[]) {
value = a[0];
next = NULL;
Node* p = this;
for (int i = 1; i < n; i++) {
p->next = new Node(a[i]);
p = p->next;
}
}
void concat(Node* head) {
Node* p = this;
while (p->next != NULL) {
p = p->next;
}
p->next = head;
}
void display() {
Node* current = this;
while (current != nullptr) {
cout << current->value << " ";
current = current->next;
}
cout << endl;
}
};
int main() {
int a[] = { 1, 2, 3, 4, 5 };
int b[] = { 6, 7, 8, 9, 10 };
Node* list1 = new Node(5, a);
Node* list2 = new Node(5, b);
list1->display();
list2->display();
list1->concat(list2);
list1->display();
return 0;
}

how to remove duplicate elements from the linked list

I have to make a program to count the number of occurrences of a given key in a singly linked
list and then delete all the occurrences. For example, if given linked list is 1->2->1->2->1->3->1 and given key is 1, then output should be 4. After deletion of all the
occurrences of 1, the linked list is 2->2->3.
I tried making a program that removes duplicate elements from a linked list and count the number of occurrence of the duplicate element
output for my program is
Your linked list is 1 2 1 2 1 3 1
Enter a number: 1
Number of occurance is: 4
After deleting repeated elements:
Your linked list is 2 2 1 3 1
I am going to add third case to remove element from the end soon but I need help in this function . Here I am only able to remove one '1' why is this happening please help
struct Node* ptr2= head;
struct Node* ptr3= head->next;
while(ptr3!=NULL)
{
if(ptr3->data==x)
{
ptr2->next=ptr3->next;
}
ptr2=ptr2->next;
ptr3=ptr3->next;
}
cout<<"Number of occurance is: "<<count<<endl;
return head;
whole program is :-
#include<iostream>
using namespace std;
struct Node
{
int data;
struct Node* next;
};
void traversal(struct Node* head)
{
cout<<"Your linked list is ";
struct Node* ptr = head;
while(ptr!=NULL)
{
cout<<ptr->data<<" ";
ptr=ptr->next;
}
}
struct Node* deleterepeated(struct Node* head, int x)
{
int s=0;//number of elements in linked list
struct Node* p = head;
while(p!=NULL)
{
p=p->next;
s++;
}
struct Node* ptr = head;
int count=0;
while(ptr!=NULL)
{
if(ptr->data == x)
{
if(count==0)
{
head=ptr->next;
}
count++;
}
ptr=ptr->next;
}
struct Node* ptr2= head;
struct Node* ptr3= head->next;
while(ptr3!=NULL)
{
if(ptr3->data==x)
{
ptr2->next=ptr3->next;
}
ptr2=ptr2->next;
ptr3=ptr3->next;
}
cout<<"Number of occurance is: "<<count<<endl;
return head;
}
int main()
{
struct Node* head;
struct Node* val1;
struct Node* val2;
struct Node* val3;
struct Node* val4;
struct Node* val5;
struct Node* val6;
head= (struct Node*)malloc(sizeof(struct Node));
val1= (struct Node*)malloc(sizeof(struct Node));
val2= (struct Node*)malloc(sizeof(struct Node));
val3= (struct Node*)malloc(sizeof(struct Node));
val4= (struct Node*)malloc(sizeof(struct Node));
val5= (struct Node*)malloc(sizeof(struct Node));
val6= (struct Node*)malloc(sizeof(struct Node));
head->data=1;
val1->data=2;
val2->data=1;
val3->data=2;
val4->data=1;
val5->data=3;
val6->data=1;
head->next=val1;
val1->next=val2;
val2->next=val3;
val3->next=val4;
val4->next=val5;
val5->next=val6;
val6->next=NULL;
traversal(head);
cout<<endl;
cout<<"Enter a number: ";
int x;
cin>>x;
head=deleterepeated(head,x);
cout<<"After deleting repeated elements: "<<endl;
traversal(head);
return 0;
}
It is very easy to do if you use the standard linked list implementation:
#include <iostream>
#include <list>
int main() {
std::list<int> list{1, 2, 1, 2, 1, 3, 1};
int nOnes = 0;
for (auto it = list.begin(), end = list.end(); it != end; /*no op*/) {
if (*it == 1) {
++nOnes;
it = list.erase(it); // remove element idiom
} else {
++it;
}
}
std::cout << "Removed " << nOnes << " item(s)\n"
<< "Remains: \n";
for (auto const e : list) {
std::cout << e << '\n';
}
}
As a side-note, it is even nicer with a vector:
#include <algorithm>
#include <vector>
int main() {
std::vector<int> vec{1, 2, 1, 2, 1, 3, 1};
auto const nOnes = vec.end() - std::remove(vec.begin(), vec.end(), 1);
vec.resize(vec.size() - nOnes);
}
so , you have a little tiny mistakes in your code , I edited it out , all of the edits are in the function named deleterepeated and here is my solution , not the best but it will work for your case :
EDIT: I removed unnecessary things in the code to be only one big loop , also I found a bug in my previous code and edit it out here in the new version , this is only the deleterepeated function
struct Node* deleterepeated(struct Node* head, int x)
{
int count = 0;
struct Node* ptr2 = head;
struct Node* ptr3 = ptr2->next;
struct Node* temp;
while (ptr3 != NULL)
{
if (head && head->data == x) // here is the part of deleting the head if it matches
{
temp = head;
head = head->next;
free(temp);
ptr2 = head;
ptr3 = head->next;
}
else if (ptr3 && ptr3->data == x)
{
temp = ptr3;
ptr2->next = ptr3->next;
free(temp); // you have to free memory to avoid memory leak
ptr3 = ptr2->next;
count++;
}
else
{
ptr2 = ptr2->next;
ptr3 = ptr3->next;
}
}
cout << "Number of occurance is: " << count << endl;
return head;
}
picture of the results:

Declaration of Head/First node in a Linked list

Hi all I'm having an issues in a linked list problem. Given two piece of code I've to find why one of them is not working
Code 1 is
struct node {
int data;
struct node *link;
};
void insert(struct node *head) {
struct node *last, *temp;
head = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &head->data);
head->link = NULL;
last = head;
{
int n = 3;
while(n>0){
temp = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &temp->data);
temp->link = NULL;
last->link = temp;
last = temp;
n--;
}
}
return;
}
void display(struct node *p) {
while(p) {
printf("%d ",p->data);
p = p->link;
}
return;
}
int main() {
struct node *head;
insert(head);
display(head);
return 0;
}
and second code is
struct node {
int data;
struct node *link;
}*head;
void insert() {
struct node *last, *temp;
head = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &head->data);
head->link = NULL;
last = head;
{
int n = 3;
while(n>0){
temp = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &temp->data);
temp->link = NULL;
last->link = temp;
last = temp;
n--;
}
}
return;
}
void display(struct node *p) {
while(p) {
printf("%d ",p->data);
p = p->link;
}
return;
}
int main() {
insert();
display(head);
return 0;
}
Now my question is why declaring head in main in the first is not giving o/p for display function wheres declaring it globally in second code is working? Asking this as I'm wondering that in first case head is declared in main and passed as an address so after coming back from insert function it should get the effect of that insert function operation but it's not working like the way and not giving ant o/p for display function
The issue is that, in the first code, insert receives a copy of the main's head pointer and modifies that copy by making it point to some newly allocated memory. That modification never propagates back to main.
To make it propagate, use a pointer to pointer:
void insert(struct node **head) {
struct node *last, *temp;
*head = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &(*head)->data);
(*head)->link = NULL;
last = *head;
{
int n = 3;
while(n>0){
temp = (struct node *)malloc(sizeof(struct node));
printf("Input an integer: ");
scanf("%d", &temp->data);
temp->link = NULL;
last->link = temp;
last = temp;
n--;
}
}
return;
}
and then, in main, call it like so:
insert(&head);
Alternatively, you could make insert take a pointer but also return a pointer (i.e. the new head):
struct node* insert(struct node *head) { ... }
One issue what that API is that it's rather error-prone: it's very easy to call insert() and forget to deal with its return value.

Start pointer not updating while passing by reference [duplicate]

This question already has answers here:
When I change a parameter inside a function, does it change for the caller, too?
(4 answers)
Closed 6 years ago.
This is push function.
void push(struct node **head)
{
struct node *temp;
temp = new node;
cout<<"enter the value";
cin>>temp->data;
temp->link=NULL;
if(*head==NULL)
{
*head=new node;
*head=temp;
}
else{
temp->link=*head;
*head=temp;
}
}
this is how i am calling push.
struct node *start=NULL;
push(&start);
this is node
struct node{
int data;
struct node *link;
};
now the problem: i don't think the list is updating. The start always remains the null. Don't know why.
edit:
void display(struct node **head)
{
struct node *temp;
temp=*head;
if(*head==NULL){
cout<<"\nthe head is NULL\n";
}
while(temp!=NULL)
{
cout<<temp->data;
temp=temp->link;
}
}
int main() {
struct node *start=NULL;
push(&start);
push(&start);
push(&start);
push(&start);
push(&start);
display(&start);
return 0;
}
input:
1
2
3
4
5
now display out should have been 5 4 3 2 1 but there is some mistake.
The answer is mentioned by paxdiablo in the comments: C++ has pass by reference. Example:
#include <iostream>
struct node
{
int data;
struct node *link;
};
void push(node*& head)
{
struct node *temp = new node;
std::cout << "enter the value";
std::cin >> temp->data;
temp->link = head;
head = temp;
}
int main()
{
node *start = NULL;
push(start);
return 0;
}
Alternative implementation:
void push(struct node** head_reference, int new_data)
{
struct node* a_node = new node;
a_node->data = new_data;
a_node->link = (*head_reference);
(*head_reference) = a_node;
}
int main() {
struct node* head = NULL;
push(&head, 10);
// rest of your code here
return 0;
}

whats wrong with this linked list for counting

THs following code is crashing, and I'm unsure why. Trying to count the number of times an integer is found in the following linked list..However xcode keeps saying the int count=0 from the main is breaking a thread?
#include <iostream>
using namespace std;
struct Node {
int val;
Node *next;
};
int countNum (Node *head, int key);
Node* cons (int x, Node* p);
int main()
{
Node *head = (1,cons(2,cons(2,(cons(4,(cons(5,nullptr)))))));
int counts=0;
counts= countNum(head,2);
cout<< counts<< head;
return 0;
}
Node* cons (int x, Node* p){
Node *q=new Node;
q->val=x;
q->next=p;
return p;
}
int countNum (Node *head, int key) {
int count=0;
if (head==nullptr)
return 0;
Node *follow=head;
while (follow!=nullptr) {
if(follow->val==key)
count++;
follow=follow->next;
}
cout<<count;
return count;
}
use Node *head = cons(1,cons(2,cons(2,(cons(4,(cons(5,nullptr)))))));
I think you want to return a pointer to the current node instead of the next node. Also I don't think you can do:
Node *head = (1, ptrToNextNode);
Something like this might work:
struct Node *head = malloc(sizeof (struct Node));
head->value = 1;
head->next = cons(2,cons(2,(cons(4,(cons(5,nullptr))))));
...
Node* cons (int x, Node* p)
{
Node *q=new Node;
q->val=x;
q->next=p;
return q;
}