here is my code for deque implementation using doubly linked list. It is not working..can u get me some pointers on where i am going wrong. The pointers are not initialised and the code is getting stuck in the addqatend function.
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <string.h>
#include<time.h>
#include<math.h>
#include<ctype.h>
#include <malloc.h>
#include <Windows.h>
struct node
{
struct node *prev;
int data;
struct node *next;
};
struct queue
{
struct node *front;
struct node *rear;
};
void initqueue(struct queue *);
void addqatbeg(struct queue *,int);
void addqatend(struct queue *, int);
int delqatbeg(struct queue *);
int delqatend(struct queue *);
void delqueue(struct queue *);
int main()
{
struct queue a;
int i;
system("cls");
initqueue(&a);
addqatbeg(&a,11);
addqatbeg(&a,23);
addqatbeg(&a,-5);
addqatbeg(&a,45);
addqatend(&a,34);
addqatend(&a,78);
i = delqatbeg(&a);
if(i!=NULL)
printf("item deleted from front:%d",i);
i = delqatbeg(&a);
if(i!=NULL)
printf("item deleted from front:%d",i);
i = delqatend(&a);
if(i!=NULL)
printf("item deleted from end:%d",i);
i = delqatend(&a);
if(i!=NULL)
printf("item deleted from end:%d",i);
delqueue(&a);
system("pause");
return 0;
}
//initialise the queue
void initqueue(struct queue *q)
{
q->front = q->rear = NULL;
}
//add at the beginning of the queue
void addqatbeg(struct queue *q,int item)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
if(temp == NULL)
printf("queue is full\n");
//temp->data = item;
//temp->link = NULL;
if(q->front == NULL)
{
q->rear = q->front = temp;
q->front->prev = NULL;
q->front->next = NULL;
q->rear->next = NULL;
q->rear->prev = NULL;
return;
}
q->front->data = item;
q->front->next = temp;
q->front = temp;
q->front->prev = q->front;
//q->rear->next = q->front->next;
//q->front->prev = q->rear;
}
//add at the end of the queue
void addqatend(struct queue *q, int item)
{
struct node *temp;
temp = (struct node*)malloc(sizeof(struct node));
if(temp == NULL)
printf("queue is full\n");
if(q->front == NULL)
{
q->rear = q->front = temp;
q->front->prev = NULL;
q->front->next = NULL;
return;
}
while(q->front->next!=NULL)
q->rear = q->front->next;
q->rear->data = item;
q->rear->next =temp;
q->rear = q->rear->next;
q->rear->prev = q->rear;
}
//delete at the beginning of the queue
int delqatbeg(struct queue *q)
{
struct node *temp;
int item;
if(q->front ==NULL)
{
printf("queue is empty:\n");
return NULL;
}
item = q->front->data;
temp = q->front;
q->front = q->front->next;
free(temp);
return item;
}
//delete at the end of the queue
int delqatend(struct queue *q)
{
struct node *temp;
int item;
if(q->rear == NULL)
{
printf("queue is empty\n");
return NULL;
}
item = q->rear->data;
temp = q->rear;
q->rear = q->rear->prev;
free(temp);
return item;
}
//free the nodes
void delqueue(struct queue *q)
{
struct node *temp;
if(q->front == NULL)
return;
while(q->front!=NULL)
{
temp = q->front;
q->front = q->front->next;
free(temp);
}
}
There are various issues here.
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <string.h>
#include<time.h>
#include<math.h>
#include<ctype.h>
#include <malloc.h>
#include <Windows.h>
Ugh, that's a whole slew of includes. What language are you using? Make up your mind. <iostream> is a C++ header, the rest are C headers. What is <malloc.c>? Usually, malloc should be in <stdlib.h> or <windows.h>. For this example, you just need <stdlib.h> and <stdio.h>.
If I switch on compiler warnings, I get the warnings about comparing and assignig integers to pointers. In delqatend you should return plain 0 as error code, not NULL. likewise here:
i = delqatbeg(&a);
if (i != NULL)
printf("item deleted from front:%d", i);
The NULLshould be 0. (0 is a language representation of the null pointer as well as of null integers, but the macro NULL casts it to (void *), making it a pointer. here' i is an integer.) Also, please print a newline at the end of the string.
temp = (struct node *) malloc(sizeof(struct node));
if (temp == NULL)
printf("queue is full\n");
I like how the queue is full if your job is out of memory, but you shouldn't just print that but do domething else like aborting the process or returning an error code, otherwise you'll do something bad later on in the function to a NULL pointer.
Okay, now to your main problem. Let's look at your function addqatbeg. In the case where the queue is empty you insert the node correctly, although you essentially do the same assignment twice, because q->front and q->end are equal. But you don't assign the data to the new node.
The other case, where there is already a node in the queue, is a mess. You don't isert nodes by jiggling around their data, but by reornagising the queue structure through the pointers. Here's a better addqatbeg:
//add at the beginning of the queue
void addqatbeg(struct queue *q, int item)
{
struct node *temp;
// Create node and check for NULL
temp = (struct node *) malloc(sizeof(struct node));
if (temp == NULL) {
printf("queue is full\n");
return;
}
// Assign data
temp->data = item;
temp->prev = temp->next = NULL;
// Insert node
if (q->front == NULL) {
q->rear = q->front = temp;
} else {
temp->next = q->front;
q->front->prev = temp;
q->front = temp;
}
}
It should be easy to implement addqatend now. The functions addqatend and addqatbeg are totally analogous in your case, bacause you maintain forward and backward pointers. The while loop in your addqatend is superflous and introduces an endless loop: You check q->front, but never update it in your loop.
Look if these functions work for you. Repeating patterns suggest some refactoring in common functions, but try this out.
Addqatbeg:
//add at the beginning of the queue
void addqatbeg(struct queue *q,int item)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
if(temp == NULL)
printf("queue is full\n");
if(q->front == NULL)
{
q->rear = q->front = temp;
q->front->data = item;
return;
}
q->front->next = temp;
q->front = q->front->next;
q->front->data = item;
}
Addqatend:
//add at the end of the queue
void addqatend(struct queue *q, int item)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
if(temp == NULL)
printf("queue is full\n");
if(q->rear == NULL)
{
q->rear = q->front = temp;
q->rear->data = item;
return;
}
q->rear->prev = temp;
q->rear = q->rear->prev;
q->rear->data = item;
}
Delqatbeg:
//delete at the beginning of the queue
int delqatbeg(struct queue *q)
{
struct node *temp;
int item;
if(q->front == NULL)
{
printf("queue is empty:\n");
return NULL;
}
item = q->front->data;
temp = q->front;
q->front = q->front->prev;
free(temp);
}
return item;
}
Delqatend:
//delete at the beginning of the queue
int delqatend(struct queue *q)
{
struct node *temp;
int item;
if(q->rear == NULL)
{
printf("queue is empty:\n");
return NULL;
}
item = q->rear->data;
temp = q->rear;
q->rear = q->rear->next;
free(temp);
return item;
}
Related
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.
I am trying to implement Linked List. In this sample program, user inputs an integer value (the number of strings to store in the list) and then strings one by one... But after several inputs (may be 4 or 5) the program crashes like the image here...
Even, I can't call any function more than 3 times at once which contains malloc() inside them..
I don't know why the problem is occurring. Help me fixing the issue....
#include <bits/stdc++.h>
using namespace std;
typedef struct Linked_List NODE;
struct Linked_List
{
string data;
NODE* next;
};
//Function prototypes
NODE *traverse(NODE *temp);
NODE* createNode(string data);
void preAppend(NODE* ln_list, string x);
NODE* find_data(NODE* ln_list, string data);
int main()
{
NODE* x=createNode("");
int t;
cin >>t;
string z;
while(t--)
{
cin >> z;
preAppend(x, z);
}
traverse(x);
return 0;
}
NODE *traverse(NODE *temp)
{
cout << temp->data << endl;
if(temp->next==NULL) return temp;
traverse(temp->next);
}
NODE* createNode(string data)
{
NODE* node = (NODE*)malloc(sizeof(NODE));
if(node==NULL)
{
printf("Error creating node (Error! Allocating Memory)\n");
exit(1);
}
node->data = data;
node->next = NULL;
}
void preAppend(NODE* ln_list, string x)
{
NODE* new_node = (NODE*)malloc(sizeof(NODE));
if(new_node==NULL)
{
printf("Error! Appending (Error Allocating Memory)\n");
exit(1);
}
new_node->data = x;
new_node->next = ln_list->next;
ln_list->next = new_node;
}
NODE* find_data(NODE* ln_list, string data)
{
NODE* current_node;
current_node = ln_list;
while(current_node->next!=NULL)
{
if(current_node->data == data)
{
return current_node;
}
current_node = current_node -> next ;
}
return NULL;
}
There are several problems in your code:
Usage of malloc instead of new
Using malloc for objects containing c++ objects (like stringin your case) won't call the constructors and therefore any operation upon the non constructed objects will fail.
If your program works without the return statements, it's because of undefined behaviour
Solution:
Replace
NODE* new_node = (NODE*)malloc(sizeof(NODE));
with
NODE* new_node = new NODE;
No return statements in non void functions
NODE *traverse(NODE *temp)
{
cout << temp->data << endl;
if (temp->next == NULL) return temp;
return traverse(temp->next); // return statement is needed here
}
NODE* createNode(string data)
{
NODE* node = new NODE;
if (node == NULL)
{
printf("Error creating node (Error! Allocating Memory)\n");
exit(1);
}
node->data = data;
node->next = NULL;
return node; // return statement needed here
}
Abuse of recursion
Using recursion in traverse may result in a stack overflow for long lists.
You should use a iterative approach. But you've found out that one already.
I uploaded the whole code at once. This method should work without any interruption
although if you want a complete understanding of each part i will recommend you to go over this article that i wrote on my website.
https://www.thebytewise.com/post/data-structure-and-algorithm-using-c-linear-linked-list-thebytewise
#include<stdio.h>
#include<stdlib.h>
void createList();
void traverseList();
struct node{
int data;
struct node *next;
}*header;
int main(){
int n;
printf("Enter the number of elements: ");
scanf("%d", &n);
createList(n);
printf("\nData in the list:\n");
traverseList(n);
return 0;
}
void createList(int n){
struct node *newNode, *temp;
int data, i;
newNode = (struct node *) malloc(sizeof(struct node));
if(newNode == NULL){
printf("ERROR: Memory Overflow");
}
else{
printf("Enter element 1: ");
scanf("%d", &data);
newNode->data = data;
newNode->next = NULL;
header = newNode;
temp = newNode;
for(i=2;i<=n;++i){
newNode = (struct node *) malloc(sizeof(struct node));
if(newNode == NULL){
printf("ERROR: Memory Overflow");
}
else{
printf("Enter element %d: ",i);
scanf("%d",&data);
newNode->data = data;
newNode->next = NULL;
temp->next = newNode;
temp = temp->next;
}
}
}
}
void traverseList(int n){
struct node *temp;
int i;
if(header == NULL){
printf("ERROR: Memory Underflow");
}
else{
temp = header;
for(i=0;i<n;++i){
printf("\ndata %d= %d",i+1, temp->data);
temp = temp->next;
}
}
}
In this queue is implemented using Linked List, So the display function is showing the correct result but the SizeOf() is also implemented by the same logic and if called not showing the proper answer.
Why is this happening?
// A C program to demonstrate linked list based implementation of queue
#include <stdlib.h>
#include <stdio.h>
#include<bits/stdc++.h>
using namespace std;
// A linked list (LL) node to store a queue entry
struct QNode
{
int key;
struct QNode *next;
};
// The queue, front stores the front node of LL and rear stores the last node of LL
struct Queue
{
struct QNode *front, *rear;
};
// A utility function to create a new linked list node.
struct QNode* newNode(int k)
{
struct QNode *temp = (struct QNode*)malloc(sizeof(struct QNode));
temp->key = k;
temp->next = NULL;
return temp;
}
// A utility function to create an empty queue
struct Queue *createQueue()
{
struct Queue *q = (struct Queue*)malloc(sizeof(struct Queue));
q->front = q->rear = NULL;
return q;
}
// The function to add a key k to q
void enQueue(struct Queue *q, int k)
{
// Create a new LL node
struct QNode *temp = newNode(k);
// If queue is empty, then new node is front and rear both
if (q->rear == NULL)
{
q->front = q->rear = temp;
return;
}
// Add the new node at the end of queue and change rear
q->rear->next = temp;
q->rear = temp;
}
// Function to remove a key from given queue q
struct QNode *deQueue(struct Queue *q)
{
// If queue is empty, return NULL.
if (q->front == NULL)
return NULL;
// Store previous front and move front one node ahead
struct QNode *temp = q->front;
q->front = q->front->next;
// If front becomes NULL, then change rear also as NULL
if (q->front == NULL)
q->rear = NULL;
return temp;
}
void Display(struct Queue *q)
{
if(q==NULL)
{
cout<<"No elements"<<endl;
return;
}
else{
while(q->front->next!=NULL)
{
cout<<q->front->key<<" ";
q->front=q->front->next;
}
cout<<q->front->key<<" ";
}
}
int SizeOf(struct Queue *q)
{
int count=0;
if(q==NULL)
{
cout<<"No elements"<<endl;
return 0;
}
else{
while(q->front->next!=NULL)
{
count++;
q->front=q->front->next;
}
count++;
}
return count;
}
// Driver Program to test anove functions
int main()
{
struct Queue *q = createQueue();
enQueue(q, 10);
enQueue(q, 20);
deQueue(q);
deQueue(q);
enQueue(q, 30);
enQueue(q, 40);
enQueue(q, 50);
enQueue(q, 40);
enQueue(q, 50);
struct QNode *n = deQueue(q);
if (n != NULL)
printf("Dequeued item is %d\n", n->key);
cout<<"The Queue is Displayed as follows:"<<endl;
Display(q);
cout<<"The Queue Size is as follows:"<<endl;
int no=SizeOf(q);
cout<<no<<endl;`enter code here`
return 0;
}
Output of Display() is 40 50 40 50 but output of SizeOf() is 1. What is the problem with that?
I am trying to impliment Queue using linked list but it goes stops unexpectidly.
could not find why?
#include <iostream>
#include <string>
using namespace std;
Class Node for creating a node.
class Node
{
public:
int data;
Node *next;
};
Queue Class containing operations for Queue.
class Queue{
private:
Node* front = NULL;
Node* rear = NULL;
public:
void enQueue(int x){
Node* temp = NULL;
temp->data = x;
temp->next = NULL;
if(front == NULL && rear == NULL){
front = rear = NULL;
return;
}
rear->next = temp;
rear = temp;
}
void dequeue()
{
Node* temp = front;
if(front == NULL)
{
cout << "No list found." << endl;
return;
}
if(front == rear){
front = rear = NULL;
}
else{
front = front->next;
}
delete temp;
}
};
main function goes here
int main(){
Queue a;
a.enQueue(45);
a.dequeue();
a.dequeue();
}
void enQueue(int x){
Node* temp = NULL; //Node* temp = new Node;
temp->data = x; //BOOM
temp->next = NULL;
if(front == NULL && rear == NULL){
front = rear = NULL; //What?
return;
}
rear->next = temp;
rear = temp;
}
You are assigning to an invalid address.
This will only stop the program from "stopping unexpectidly". There are still bugs though.
The first time you enqueue a node, you're dereferencing a null pointer
void enQueue(int x){
Node* temp = NULL;
temp->data = x; // Wrong
dereferencing a null pointer yields undefined behavior.
There is an error in your enqueue function. Make the following changes:
void enQueue(int x){
Node* temp = new Node();//you need to create this variable and not set it to NULL
temp->data = x;
temp->next = NULL;
if(front == NULL && rear == NULL){
front = rear = temp;
return;
}
rear->next = temp;
rear = temp;
}
Now your program will behave as expected
I'm trying to create a Queue program, but I keep getting errors that "front" and "rear" are not declared in this scope. Can anyone tell me what I'm doing wrong? Here is my code. I've comparing it to other code I've written, and I've declared them exactly the same way.
#include <iostream>
using namespace std;
class node{
public:
int data;
node *next;
node();
};
class que{
public:
node *front;
node *rear;
void enq(int a);
void deq();
void pq();
que();
};
que::que(){
front = NULL;
rear = NULL;
}
node::node(){
data = 0;
next = NULL;
}
void enq(int a){
node *temp;
temp = new node;
temp->data = a;
if(front == NULL && rear == NULL){
front = rear = temp;
}
else{
rear->next = temp;
rear = temp;
}
}
void deq(){
node *temp;
temp = front;
if(front == NULL)
return;
if(temp == rear)
front = rear = NULL;
else{
temp = temp->next;
}
delete temp;
}
void pq(){
node *curs;
curs = front;
if(front == NULL)
return;
while(1){
cout << curs->data;
if(curs->next == NULL)
break;
else
curs=curs->next;
}
}
int main(){
que *Q = new que;
return 0;
}
In your code, you start defining functions like:
void pq(){
But that's not part of the class, you have to say:
void deq::pq(){