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:
Related
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.
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
void add(struct Node *head, int n) {
Node *newNode = new Node;
newNode->data = n;
newNode->next = NULL;
Node *cur = head;
while(cur) {
if(cur->next == NULL) {
cur->next = newNode;
return;
}
cur = cur->next;
}
}
void display(struct Node *head) {
Node *list = head;
while(list) {
cout << list->data << " ";
list = list->next;
}
cout << endl;
cout << endl;
}
int main()
{
struct Node *newHead;
struct Node *head = new Node;
int ar[]={2,5,46,7,55};
for(int i=0; i<5;i++){
add(head,ar[i]);
}
display(head);
}
OUTPUT:
0 2 5 46 7 55
What's the reason of the linked list has a zero of the beginning?
And how can I fix it? I do not want to print zero.
If you see some mistakes in my code, please tell me. I am new at coding.
In main, you allocate an uninitialized instance of Node and store the pointer in head. You never assign the head->data of that node, so that value is indeterminate. Same holds for head->next. When those values are read in add and display, the behaviour of the program is undefined.
And how can I fix it?
Firstly, initialize head in main to avoid undefined behaviour:
Node *head = new Node();
// ^^ these are important
Then you could do one of these things:
a) Skip the first node using display(head->next); instead of display(head);
b) Initialize the head to the first value that you want
head->data = ar[0];
for(int i=1; i<5;i++)
// ...
c) Redesign your API to not require the user to allocate the first node separately. More details about this in Remy's answer.
There are several problems with your code:
When you allocate the head node, you are not assigning any value to its data member, so it holds a random value that happens to be 0 in your case. And you are not initializing its next member either, which means add() and display() will not work correctly.
in add(), if head is NULL, no node is added to the list (you don't update the caller's Node* variable to point at the new node), and you leak the allocated newNode.
you are leaking all of the allocated nodes when exiting from main().
Try this instead:
#include <iostream>
struct Node {
int data;
Node* next;
Node(int value) : data(value), next(0) {}
};
void add(Node* &head, int n) {
Node **newNode = &head;
while (*newNode) {
newNode = &((*newNode)->next);
}
*newNode = new Node(n);
}
void display(Node *head) {
Node *cur = head;
while (cur) {
std::cout << cur->data << " ";
cur = cur->next;
}
std::cout << std::endl;
std::cout << std::endl;
}
void clear(Node* &head) {
Node *cur = head;
head = NULL;
while (cur) {
Node *next = cur->next;
delete cur;
cur = next;
}
}
int main()
{
Node *head = NULL;
int ar[] = {2, 5, 46, 7, 55};
for(int i = 0; i < 5; ++i){
add(head, ar[i]);
}
display(head);
clear(head);
return 0;
}
And then, when you get that working, throw it all away and use the STL's std::list container instead:
#include <iostream>
#include <list>
void display(const std::list<int> &mylist) {
for(std::list<int>::const_iterator iter = mylist.begin(); iter != mylist.end(); ++iter) {
std::cout << *iter << " ";
}
std::cout << std::endl;
std::cout << std::endl;
}
int main()
{
std::list<int> mylist;
int ar[] = {2, 5, 46, 7, 55};
for(int i = 0; i < 5; ++i){
mylist.push_back(ar[i]);
}
/* or:
int ar[] = {2, 5, 46, 7, 55};
std::list<int> mylist(ar, ar+5);
*/
display(mylist);
return 0;
}
I am stuck on this simple question for hours...can someone plz help...where i am going wrong?
Question : Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,
return 1->4->3->2->5->NULL.
Note: 1 ≤ m ≤ n ≤ length of list
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *next;
};
typedef struct node ListNode;
node *newNode(int key)
{
node *temp = new node;
temp->data = key;
temp->next = NULL;
return temp;
}
ListNode* reverseUpto(ListNode *head, int size)
{
if(size<=1)
return head;
ListNode *cur=head,*newhead=NULL,*temp;
for(int i=0;i<size;i++)
{
temp=cur;
cur=cur->next;
temp->next=newhead;
newhead=temp;
}
head->next=cur;
return newhead;
}
ListNode* reverseBetween(ListNode* A, int m, int n)
{
ListNode *head=A;
if(m==n)
return A;
ListNode *dummyhead=newNode(0);
dummyhead->next=head;
ListNode *prev=dummyhead;
ListNode *cur=head;
int counter=1;
while(counter<m)
{
printf("counter= %d prev=%d cur=%d\n",counter,prev->data,cur->data);
counter++;
prev=cur;
cur=cur->next;
}
prev->next=NULL;
ListNode * retPtr=reverseUpto(cur,m-n+1);
prev->next=retPtr;
return A;
}
void printlist(node *head)
{
while(head != NULL)
{
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
int main()
{
node *head1 = newNode(1);
head1->next = newNode(2);
head1->next->next = newNode(3);
head1->next->next->next = newNode(4);
head1->next->next->next->next = newNode(5);
head1->next->next->next->next->next = newNode(6);
head1->next->next->next->next->next->next = newNode(7);
head1->next->next->next->next->next->next->next = newNode(8);
cout << "Given linked list\n";
printlist(head1);
head1=reverseBetween(head1,3,5);
cout << "\nReversed linked list\n";
printlist(head1);
return 0;
}
I am getting same output as my input!!....where is the pitfall?
ListNode * retPtr=reverseUpto(cur,m-n+1);
modify to
ListNode * retPtr=reverseUpto(cur,n-m+1);
Can Someone please explain the difference in Behaviour ?
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
// only for the 1st Node
void initNode(Node *head,int n){
head->data = n;
head->next =NULL;
}
void insertFront(Node *head, int n) {
Node *newNode = new Node;
newNode->data = n;
newNode->next = head;
head = newNode;
}
void display(Node *head) {
Node *list = head;
while(list) {
cout << list->data << " ";
list = list->next;
}
cout << endl;
cout << endl;
}
int main()
{
Node *l1 = new Node;
initNode(l1,10);
display(l1);
insertFront(l1,5);
display(l1);
insertFront(l1,6);
display(l1);
insertFront(l1,7);
display(l1);
return 0;
}
Some how the nodes are not linking. The output is :
10
10
10
10
If The program is coded using pointer to a pointer as below then it works fine. what am is missing ?
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
// only for the 1st Node
void initNode(Node *head,int n){
head->data = n;
head->next =NULL;
}
void insertFront(Node **head, int n) {
Node *newNode = new Node;
newNode->data = n;
newNode->next = *head;
*head = newNode;
}
void display(Node *head) {
Node *list = head;
while(list) {
cout << list->data << " ";
list = list->next;
}
cout << endl;
cout << endl;
}
int main()
{
Node *l1 = new Node;
initNode(l1,10);
display(l1);
insertFront(&l1,5);
display(l1);
insertFront(&l1,6);
display(l1);
insertFront(&l1,7);
display(l1);
return 0;
}
Output correct as expected :
10
5 10
6 5 10
7 6 5 10
In the first case, in function
void insertFront(Node *head, int n) {
Node *newNode = new Node;
newNode->data = n;
newNode->next = head;
head = newNode;
}
head is a copy of the pointer l1 used in the scope of main(). When head is modified, l1 is left unchanged. This is the reason why a pointer to l1 (&l1) is passed to the function in the second case void insertFront(Node **head, int n). Then *head is l1, not just a copy of l1.
First case is an example of passing argument by value, and the second case is passing an argument by reference What's the difference between passing by reference vs. passing by value?
For instance, the following function is basically useless :
void useless(int a){
a=42;
}
If int b=2;useless(b);cout<<b<<endl; is called it will print 2, not 42.
The following function is the right way to go :
void rightwaytogo(int*a){
*a=42;
}
Don't forget to write a function to delete the nodes of your linked list.
I got a problem with my doubly linked list. How can i make the input unique ( i don`t want it to be repeated )
for example i can input 1 and then again 1 i will have a list of 1 and 1. I need to forbid this somehow :) so the list can contain only not repeating numbers.
#include <cstdlib>
#include <iostream>
using namespace std;
struct node
{
int data;
node* next;
node* prev;
};
class Node
{
public:
Node();
~Node();
void setKopa();
void printForward();
private:
node* head;
node* tail;
node* n;
};
Node::Node()
{
setKopa();
}
Node::~Node()
{
delete n;
}
void Node::setKopa()
{
int lenght;
do
{
cout << "Input list lenght (how many elements): ";
cin >> lenght;
if(lenght<2)
cout << "Error list has to have atleast 2 elements!" <<endl;
}
while(lenght<2);
int fill;
cout << "Input "<< lenght <<" elements: "<<endl;
for (int i=0; i<lenght; i++)
{
cin>>fill;
n = new node;
n->data = fill;
if (i==0)
{
n->prev = NULL;
head = n;
tail = n;
}
else if (i+1==lenght)
{
n->prev = tail;
tail->next = n;
tail = n;
tail->next = NULL;
}
else
{
n->prev = tail;
tail->next = n;
tail = n;
}
}
}
void Node::printForward()
{
node* temp = head;
while(temp != NULL)
{
cout << temp->data << " ";
temp = temp-> next;
}
cout << endl;
}
int main()
{
Node a;
a.printForward();
system("pause");
return 0;
}
When you read input, go through the list to see if the input is already there.
With that (simple) answer out of the way, I would like to address some other things regarding your code. The first is that you have a memory leak in that you never delete the list. The second is that you don't need the class member variable n, it might as well be a local variable inside the setKopa loop.
Your way of adding new nodes is also, well, weird. It should, in my opinion, be more general instead of using the loop counter to check what to do. What I suggest is that you make a member function to add new nodes, taking the integer data as argument. This way you can call this function to add nodes anywhere, and not just in the setKopa function. In fact, I think the list should not handle that input at all, instead it should be a free-standing function called from main and which calls the addNode function.
Also the node structure doesn't need to be in the global namespace, it could be a private structure in the Node class. And speaking of the Node class, shouldn't it really be called List instead?
So if I may suggest, you might want to do something like this:
#include <iostream>
class List
{
public:
List()
: head(nullptr), tail(nullptr)
{}
~List();
void addNode(const int data);
void printAll() const;
private:
struct node
{
node()
: next(nullptr), prev(nullptr)
{}
node* next;
node* prev;
int data;
};
node* head;
node* tail;
};
List::~List()
{
for (node* next, *cur = head; cur; cur = next)
{
next = cur->next;
delete cur;
}
}
void List::addNode(const int data)
{
node* n = new node;
n->data = data;
if (tail == nullptr)
{
// First node in list
head = tail = n;
}
else
{
n->prev = tail;
tail->next = n;
tail = n;
}
}
void List::printAll() const
{
std::cout << "{ ";
for (node* cur = head; cur != nullptr; cur = cur->next)
std::cout << cur->data << ' ';
std::cout << "}\n";
}
int main()
{
List list;
for (int i = 0; i < 10; ++i)
list.addNode(i);
list.printAll();
}
The above code should print
{ 0 1 2 3 4 5 6 7 8 9 }
Replace the node-adding loop with your own.