Linked List in C++ using Struct - c++

I am not getting the else part in create_node() function..
As you can see in the else part ,memory block is allocated for r and coeff and power are assigned...but when did they assign r node to the last of linkedlist.. when did they traverse to end of linked list
I mean how is it getting assigned at the last of linked list.
#include <bits/stdc++.h>
using namespace std;
struct Node {
int coeff;
int pow;
struct Node* next;
};
// Function to create new node
void create_node(int x, int y, struct Node** temp)
{
struct Node *r, *z;
z = *temp;
if (z == NULL) {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
*temp = r;
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
}
else {
r->coeff = x;
r->pow = y;
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
}
}
// Display Linked list
void show(struct Node* node)
{
while (node->next != NULL) {
printf("%dx^%d", node->coeff, node->pow);
node = node->next;
if (node->coeff >= 0) {
if (node->next != NULL)
printf("+");
}
}
}
// Driver code
int main()
{
struct Node *poly1 = NULL, *poly2 = NULL, *poly = NULL;
// Create first list of 5x^2 + 4x^1 + 2x^0
create_node(5, 2, &poly1);
create_node(4, 1, &poly1);
create_node(2, 0, &poly1);
// Create second list of -5x^1 - 5x^0
create_node(-5, 2, &poly2);
create_node(-5, 0, &poly2);
printf("1st Number: ");
show(poly1);
printf("\n2nd Number: ");
show(poly2);
return 0;
}
Am I the only one who thinks that create_node() function should be more like this than the above code?
void create_node(int x, int y, struct Node** temp)
{
struct Node *r, *z;
z = *temp;
if (z == NULL) {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
r->next=NULL;
*temp = r;
}
else {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
r->next=NULL;
while(z->next!=NULL)
{
z=z->next;
}
z->next=r;
}
}
I really want to know how is it producing the right output, even without assigning newnode to last of linked list

If you are going to write a C++ program then use the operator new to allocate memory instead of calling the C function malloc.
If you want to append a node to the list to its tail then it is better to use a two-sided singly-linked list.
The first function create_node does not make a sense due to appending a dummy node with uninitialized data members except the data member next.
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
The function show can invoke undefined behavior because it does not check whether the passed pointer is equal to nullptr.
// Display Linked list
void show(struct Node* node)
{
while (node->next != NULL) {
//...
The functions as C++ functions can be declared and defined the following way without using a duplicated code.
void create_node( Node **head, int x, int y )
{
Node *new_node = new Node { x, y, nullptr };
while ( *head ) head = &( *head )->next;
*head = new_node;
}
std::ostream & show( const Node *head, std::ostream &os = std::cout )
{
for ( ; head != nullptr; head = head->next )
{
os << head->coeff << '^' << head->pow;
if ( head->next != nullptr ) os << " + ";
}
return os;
}

I am not getting the else part in create_node() function.. As you can
see in the else part ,memory block is allocated for r and coeff and
power are assigned...but when did they assign r node to the last of
linkedlist.. when did they traverse to end of linked list I mean
how is it getting assigned at the last of linked list.
It is not. When you pass a null Node*, z will be null, and your else code is dereferencing r which hasn't even been initialized.
// Function to create new node
void create_node(int x, int y, struct Node** temp)
{
struct Node *r, *z;
z = *temp;
if (z == NULL) {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
*temp = r;
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
}
else {
r->coeff = x;
r->pow = y;
r->next = (struct Node*)malloc(sizeof(struct Node));
r = r->next;
r->next = NULL;
}
}
Am I the only one who thinks that create_node() function should be
more like this than the above code?
This seems to solve above's code issues. Here you are creating a Node and assigning it to r, then appending it at the end of z (input Node*). Notice though that you are duplicating the code for creating r in both blocks of code. You could take at least that part out of the if-else.
void create_node(int x, int y, struct Node** temp)
{
struct Node *r, *z;
z = *temp;
if (z == NULL) {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
r->next=NULL;
*temp = r;
}
else {
r = (struct Node*)malloc(sizeof(struct Node));
r->coeff = x;
r->pow = y;
r->next=NULL;
while(z->next!=NULL)
{
z=z->next;
}
z->next=r;
}
}

Related

Linked List delete operation not working in visual studio using C

when I tried to implement a linked list in visual studio 2019 using c it produces heap error.
It was due to the free function.
However, the code works fine on online compilers which use the GCC compiler. https://www.jdoodle.com/c-online-compiler/
I can't able to figure it out..........................
here is the code:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node* head = NULL;
void append(int data)
{
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node*));
(*newNode).data = data;
(*newNode).next = NULL;
if (head == NULL)
{
head = newNode;
return;
}
struct Node* temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = newNode;
}
void insertAt(int position, int data)
{
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node*));
newNode->data = data;
newNode->next = NULL;
if (position == 1)
{
newNode->next = head;
head = newNode;
return;
}
struct Node* temp = head;
for (int i = 1; i < position - 1; i++)
{
temp = temp->next;
}
newNode->next = temp->next;
temp->next = newNode;
}
void deleteAt(int position)
{
struct Node* temp = NULL;
if (position == 1)
{
temp = head;
head = temp->next;
free(temp);
return;
}
struct Node* tempHead = head;
for (int i = 1; i < position - 1; i++)
{
tempHead = tempHead->next;
}
temp = tempHead->next;
tempHead->next = temp->next;
free(temp);
}
void print()
{
struct Node* temp = head;
while (temp != NULL)
{
printf("%d\n", temp->data);
temp = temp->next;
}
}
void main()
{
append(3);
append(4);
append(5);
append(6);
insertAt(3, 20);
insertAt(4, 50);
insertAt(2, 70);
deleteAt(4);
deleteAt(3);
print();
}
The sizes you're passing to malloc are wrong. You should pass sizeof(struct Node).
If you're compiling this as C++ you shouldn't be using malloc at all.
As #1201ProgramAlarm answered, the allocation size is wrong. sizeof(struct Node*) is the size of a pointer, not the size of the struct.
Instead of trying to match the type, use the size of the referenced data. Easy to code right, review and maintian.
Cast not needed in C.
// struct Node* newNode = (struct Node*)malloc(sizeof(struct Node*));
// instead...
// ptr = malloc(sizeof *ptr * N);
struct Node* newNode = malloc(sizeof *newNode);
Just try this code once down there .This code is written by me according to my understanding and still if u have any issue with the code you can further ask me .You can try this code out or just cross check it with your's.
Code:
Linked List:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
}*first=NULL;
void create(int A[],int n)
{
int i;
struct Node *t,*last;
first=(struct Node *)malloc(sizeof(struct Node));
first->data=A[0];
first->next=NULL;
last=first;
for(i=1;i<n;i++)
{
t=(struct Node*)malloc(sizeof(struct Node));
t->data=A[i];
t->next=NULL;
last->next=t;
last=t;
}
}
void Display(struct Node *p)
{
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
}
void RDisplay(struct Node *p)
{
if(p!=NULL)
{
RDisplay(p->next);
printf("%d ",p->data);
}
}
int Delete(struct Node *p,int index)
{
struct Node *q=NULL;
int x=-1,i;
if(index < 1 || index > count(p))
return -1;
if(index==1)
{
q=first;
x=first->data;
first=first->next;
free(q);
return x;
}
else
{
for(i=0;i<index-1;i++)
{
q=p;
p=p->next;
}
q->next=p->next;
x=p->data;
free(p);
return x;
}
}
int main()
{
int A[]={10,20,30,40,50};
create(A,5);
printf(“%d\n",Delete(first),2);
Display(first);
return 0;
}
In main function you can pass the function created int the program and also pass the argument according to you.

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.

Pairwise Swap of nodes without swapping data in LinkedList

I have been trying to do pairwise swap of linkedlist elements. In place of swapping the elements by data, I am swapping them by swapping the links:
input 1: 1->2->3->4->5
output 1: 2->1->4->3->5
input 2: 1->2->3->4->5->6
output 2: 2->1->4->3->6->5
#include <iostream>
using namespace std;
struct node{
int data;
struct node *next;
};
struct node* func(struct node *f, struct node *s){
if(s==NULL){
return f;
}
struct node *rest1;
rest1 = s->next;
s->next = f;
if(rest1){
f->next = func(rest1,rest1->next);
}
return s;
}
void show(struct node *head){
while(head!=NULL){
cout<<" "<<head->data;
head = head->next;
}
}
int main() {
//code
struct node *head =(struct node*)malloc(sizeof(struct node));
head->data=1;
head->next = (struct node*)malloc(sizeof(struct node));
head->next->data = 2;
head->next->next = (struct node*)malloc(sizeof(struct node));
head->next->next->data = 3;
head->next->next->next = (struct node*)malloc(sizeof(struct node));
head->next->next->next->data = 4;
//head->next->next->next->next=(struct node*)malloc(sizeof(struct node));
//head->next->next->next->next->data=5;
head = func(head,head->next);
show(head);
return 0;
}
This code works fine for odd length list but does not work for even length.
I think the problem is in:
if(s==NULL){
return f;
}
statement which I am using to make previous f->next=NULL (in case of even length).
Since you tagged this as C++, I'd recommend STL's <list>. You can accomplish what you want with its splice method which allows you to manipulate the list. One possible implementation would look something like:
void alternate(list<int>& l)
{
if (l.empty())
return;
auto from_itr = cbegin(l);
auto to_itr = from_itr;
for (; ++to_itr != cend(l) && ++to_itr != cend(l);) {
l.splice(to_itr, l, from_itr);
++from_itr;
}
}
NOTE: The from_itr in the loop is incremented only once because it has been moved in the list to precede the next node of interest.
Consider the case of Even length list say 1->2->3->4->5->6 when f points to 5, s points to 6 & rest1 points to null.
s->next = f makes node 6->5 but still node 5 will point to 6. Thus a loop will be formed where 6->5->6->5..............so on.
Thus to make this code work add an else statement here
if(rest1){
f->next = func(rest1,rest1->next);
}
else f->next = NULL;
This will make 5->NULL preventing an infinite loop.Thus your function will look like this
struct node* func(struct node *f, struct node *s){
if(s==NULL){
return f;
}
struct node *rest1;
rest1 = s->next;
s->next = f;
if(rest1){
f->next = func(rest1,rest1->next);
}
else f->next = NULL;
return s;
}

why after the first push head is still null?

I am trying to create singly-linked list. After the first push, head is still null. Why is the head not updated after the first push?
using namespace std;
typedef struct node {
int data; // will store information
node *next; // the reference to the next node
};
void push(node*,int);
void print(node*);
int main()
{
node* head = NULL; //empty linked list
push(head, 2);
if (head == NULL) {
cout << "vrvrvr";
}
push(head, 3);
push(head, 5);
push(head, 2);
//print(head);
getchar();
return 0;
}
void push(node* x, int y){
node *temp = new node();
if (x == NULL) { // check linked list is empty
temp->next = x;
temp->data = y;
x = temp;
}
else {
node *temp1 = new node();
temp1 = x;
while (temp1->next != NULL) { // go to the last node
temp1 = temp1->next;
}
temp1->next = temp;
temp->data = y;
temp->next = NULL;
delete temp1; // 'temp' node will be the last node
}
}
void print(node* x){
node *temp1 = new node();
temp1 = x;
while (temp1->next != NULL) {
cout << temp1->data << endl;
temp1 = temp1->next;
}
}
The main problem with push is that the changes made to x in the function are local to the function. It does not change the value of head in main.
You can fix that by changing the argument type to node*&.
void push(node*& x, int y) {
...
}
The other problems I see are in the block:
else {
node *temp1 = new node();
temp1 = x;
// Problem 1:
// After this, the memory returned by the previous line is lost.
// It is a memory leak.
while (temp1->next != NULL) { // go to the last node
temp1 = temp1->next;
}
temp1->next = temp;
temp->data = y;
temp->next = NULL;
delete temp1; // 'temp' node will be the last node
// Problem 2:
// You are deleting a node from the linked list.
// The linked list now has a dangling pointer.
}
You can correct those problems by using:
node *temp1 = x;
while (temp1->next != NULL) { // go to the last node
temp1 = temp1->next;
}
temp1->next = temp;
temp->data = y;
temp->next = NULL;
}
Suggested improvements
Remove typedef from definition of node. It is a dangling typedef in your posted code. Also, you can use node without a typedef in C++.
struct node {
int data;
node *next;
};
Add a constructor to node.
struct node {
node(int d) : data(d), next(nullptr) {}
int data;
node *next;
};
That will simplify your code in push.
void push(node*& x, int y){
node *temp = new node(y);
if (x == NULL) { // check linked list is empty
x = temp;
}
else {
node *temp1 = x;
while (temp1->next != NULL) { // go to the last node
temp1 = temp1->next;
}
temp1->next = temp;
}
}

Cycle start node of Cycle linked list

I'm trying to implement a program for finding a starting node of circular linked list. My code is-
struct node
{
char data;
struct node *link;
} ;
char FindStartNode(struct node **q)
{
struct node *r,*t;
r = *q;
t = *q;
while(t->link != NULL)
{
r = r->link;
t = t->link->link;
if(r == t)
{
break;
}
}
if(t == NULL )
return NULL;
r = *q;
while(r != t)
{
t = t->link;
r = r->link;
}
return t->data;
}
int main()
{
struct node *p;
p = NULL;
char num;
Append(&p,'A');
Append(&p,'B');
Append(&p,'C');
Append(&p,'D');
Append(&p,'E');
Append(&p,'C');
Display(p);
num = FindStartNode(&p);
printf("\nStarting node of the cycle linked list is:- %c",num);
_getch();
return 0;
}
int Append(struct node **q, char data)
{
struct node *r,*t;
r = (struct node *)malloc(sizeof(struct node));
r->data = data;
r->link = NULL;
if(*q == NULL)
*q = r;
else
{
t = *q;
while(t->link != NULL)
{
t = t->link;
}
t->link = r;
}
return 0;
}
int Display(struct node *q)
{
while(q != NULL)
{
printf("%c\t",q->data);
q = q->link;
}
return 0;
}
ths is my code. I'm not getting any value in return t->data part or I'm unable to find the start node of cycle ink list.Any help?
t = t->link->link; // t->link can be null
//so t = t->link->link can be a crash or illegal reference
Change the loop to:
while(t != NULL)
{
r = r->link;
t = t->link;
if(t == NULL)
break; // or return no circle
else t = t->link;
if(r == t)
{
break;
}
}
I have gone through your code. Comparing with the algorithm discussion here it seems to be OK. But you are returning a char why dont you return a pointer so that you can check if it is NULL or not. In case it is not null then issue pt->tada. This makes more sense.
I checked you code it seems you are not implementing circular linked list correctly in Append(). I am providing you with a working implementation below. See how I modified Append()
#include <stdio.h>
#include <stdlib.h>
struct node
{
char data;
struct node *link;
} ;
char FindStartNode(struct node **q)
{
struct node *r,*t;
r = *q;
t = *q;
while(t->link != NULL)
{
r = r->link;
t = t->link->link;
if(r == t)
{
break;
}
}
if(t == NULL )
return NULL;
r = *q;
while(r != t)
{
t = t->link;
r = r->link;
}
return t->data;
}
int Append(struct node **q, char data);
int main()
{
struct node *p;
p = NULL;
char num;
Append(&p,'A');
Append(&p,'B');
Append(&p,'C');
Append(&p,'D');
Append(&p,'E');
Append(&p,'C');
//Display(p);
num = FindStartNode(&p);
printf("\nStarting node of the cycle linked list is:- %c\n",num);
//_getch();
return 0;
}
int Append(struct node **q, char data)
{
struct node *r,*t, *startOfcycle=NULL;
r = (struct node *)malloc(sizeof(struct node));
r->data = data;
r->link = NULL;
if(*q == NULL)
*q = r;
else
{
t = *q;
while(t->link != NULL)
{
if(t->data == data)
startOfcycle = t;
t = t->link;
}
if(startOfcycle == NULL)
t->link = r;
else {// there is a cycle point to the start of cycle
t->link = startOfcycle;
free(r);
}
}
return 0;
}
int Display(struct node *q)
{
while(q != NULL)
{
printf("%c\t",q->data);
q = q->link;
}
Please note that Display function is also wrong as runs an infinite loop of the linked list is circular. I have not modified it since it is not relevant to you question. Thanks.
...
p = NULL;
char num;
Append(&p,'A');
...
You are trying to assign to NULL, which Append handles, but you are doing it repeatedly, which means you won't make a list, just a bunch of dangling nodes.
You need to make one node to start, outside of append, as your seed node, and pass that in.