I'm having a problem when using linked list to build a queue program. Here's the full code.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define ERROR_VALUE -300000
typedef struct LinkedNode {
int data;
struct LinkdedNode* link;
}Node;
Node* front;
Node* rear;
void init_queue() { front = rear = NULL; }
int is_empty() { return (front = NULL && rear == NULL); }
int size() {
Node* p;
int count = 0;
if (is_empty())
return 0;
for (p = front; p != rear; p = p->link) {
count++;
return count + 1;
}
}
void enqueue(int e) {
Node* p = (Node*)malloc(sizeof(Node));
p->data = e;
p->link = NULL;
if (is_empty())
front = rear = p;
else {
rear->link = p;
rear = p;
}
}
int dequeue() {
Node* p = front;
int e;
if (is_empty()) {
printf("Queue Empty Error!\n");
return ERROR_VALUE;
}
else if (size() == 1) {
front = rear = NULL;
}
else
front = p->link;
e = p->data;
free(p);
return e;
}
int peek() {
if (is_empty()) {
printf("Queue Empty Error!\n");
return ERROR_VALUE;
}
return front->data;
}
void print_queue() {
Node* p;
printf("QUEUE STATUS: size=%d\n", size());
if (is_empty())
return;
for (p = front; p != NULL; p = p->link)
printf("[%2d] ", p->data);
printf("\n");
}
int main(void) {
int val, sel;
init_queue();
while (1) {
do {
printf("1.ENQUEUE 2.DEQUEUE 3.PEEK 4.STATUS 0.EXIT :");
scanf("%d", &sel);
} while (sel < 0 || sel > 4);
if (sel == 1) {
printf("1.ENQUEUE VALUE ? ");
scanf("%d", &val);
enqueue(val);
}
else if (sel == 2) {
val = dequeue();
if (val != ERROR_VALUE)
printf("2.DEQUEUE VALUE = %d\n", val);
}
else if (sel == 3) {
val = peek();
if (val != ERROR_VALUE)
printf("3.PEEK VALUE = %d\n", val);
}
else if (sel == 4)
print_queue();
else if (sel == 0) break;
}
return 0;
}
I didn't made is_full() function because linked list is "dynamic". When debugging, the program stops when I try enqueuing value. My guess is that there is something wrong in enqueue function, but cannot find what.
This is wrong:
int is_empty() { return (front = NULL && rear == NULL); }
Note the front = NULL. That means every time you call is_empty(), front gets set to NULL, which then causes is_empty() to return 0 because front = NULL evaluates to NULL.
You need to change is_empty() to
int is_empty() { return (front == NULL && rear == NULL); }
And this is exactly why many programmers use "Yoda conditions" like NULL == front - they prevent this type of bug because if you write = instead of == the code will fail to compile.
And, as you've noticed, such bugs are very hard to spot in your own code.
Related
I got problem with Singly Linked List problem.
When i inserted something in front of head. head is always have 0 of data.
I think init_list() function is something wrong. I think head of 0 is from randomly initialized data.
anything is fine without head 0 problem.
I'm sure that initializing method is wrong. But I don't know how to solve it..
Here is my I/0 and Desired Output
Input
2
insert 0 1
size
Output I got
1->0->NULL
2
1->0->NULL
Desired Output
1->NULL
1
1->NULL
Here is My Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int Element;
typedef struct LinkedNode {
Element data;
struct LinkedNode* link;
} Node;
Node* head;
void init_list() {
head = (Node*)malloc(sizeof(Node));
head->link = NULL;
}
int is_empty() {
if (head == NULL) return 1;
else return 0;
}
Node* get_entry(int pos)
{
Node* p = head;
int i;
for (i = 0; i < pos; i++, p=p->link){
if (p == NULL) return NULL;
}
return p;
}
int size()
{
Node* p;
int count = 0;
for (p = head; p != NULL; p = p->link)
count++;
return count;
}
void replace(int pos, Element val)
{
Node* node = get_entry(pos);
if (node != NULL)
node->data = val; // replace
}
Node* search_list(Element val)
{
Node* p;
for (p = head; p != NULL; p = p->link)
if (p->data == val) return p;
return NULL;
}
void insert_next(Node * before, Node * node)
{
if (node != NULL) {
node->link = before->link;
before->link = node;
}
}
void insert(int pos, Element val)
{
Node* new_node, * prev;
new_node = (Node*)malloc(sizeof(Node));
new_node->data = val;
if (pos == 0) {
new_node->link = head;
head = new_node;
}
else {
prev = get_entry(pos-1);
if (prev != NULL)
insert_next(prev, new_node);
else free(new_node);
}
}
Node * remove_next(Node * prev)
{
Node* removed = prev->link;
if (removed != NULL) {
prev->link = removed->link;
}
return removed;
}
void delete(int pos)
{
Node* prev, * removed;
if (pos == 0 && is_empty() == 0) {
removed = get_entry(pos);
head = head->link;
free(removed);
}
else {
prev = get_entry(pos-1);
if (prev != NULL) {
remove_next(prev);
free(removed);
}
}
}
void clear_list()
{
while (is_empty() == 0)
delete(0);
}
void print_list()
{
Node* p;
for (p = head; p != NULL; p = p->link)
printf("%d->", p->data);
printf("NULL\n");
}
Node * concat_list(Node * new_node)
{
if(is_empty()) return new_node;
else if(new_node == NULL) return new_node;
else{
Node* p;
p = head;
while (p->link != NULL) {
p = p->link;
}
p->link = new_node;
return head;
}
}
int main(void)
{
Element num;
int pos;
int n, i, j, len;
char c[15];
Node* tmp_head= NULL;
Node* new_head= NULL;
init_list();
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%s", c);
if (strcmp(c, "insert") == 0) { scanf("%d %d\n",&pos, &num); insert(pos,num); print_list();}
else if (strcmp(c, "delete") == 0) { scanf("%d\n", &pos); delete(pos); print_list();}
else if (strcmp(c, "size") == 0) {printf("%d\n", size()); print_list();}
else if (strcmp(c, "empty") == 0) {printf("%d\n", is_empty()); print_list();}
else if (strcmp(c, "getEntry") == 0) { scanf("%d\n", &pos); printf("%d\n", get_entry(pos)->data); print_list();}
else if (strcmp(c, "search_list") == 0) { scanf("%d\n", &num); printf("%d\n", search_list(num)->data); print_list();}
else if (strcmp(c, "replace") == 0) { scanf("%d %d\n", &pos, &num); replace(pos,num); print_list();}
else if (strcmp(c, "concat_list") == 0) {
tmp_head = head;
init_list();
scanf("%d", &len);
for (j = 0; j < len; j++)
{
scanf("%d %d\n",&pos, &num); insert(pos,num);
}
printf("new_node: ");
print_list();
new_head = head;
head = tmp_head;
head = concat_list(new_head);
print_list();
}
else printf("error\n");
}
return 0;
}
The basic problem is that within init_list, the code only initializes link but not data. I'd suggest instead that you initialize head to NULL and simply use insert to create nodes.
I am working on building circular doubly linked list code.
In my code, there are four function- add node, delete node, print clockwise, print counterclockwise. All my code works fine, besides the delete function. The if(recycle->name == x) line seems not working properly, and free(recycle) also doesn't successfully free the recycle node.
My original code are. as follows
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define nameLen 20
struct Node
{
char name[nameLen];
struct Node *left; //next
struct Node *right; //previous
};
struct Node* current;
struct Node* head;
int count = 0;
struct Node* GetNewNode(char *x)
{
struct Node* newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
strncpy(newNode->name, x, nameLen);
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
void add_name(char *x)
{
struct Node* temp = current;
struct Node* newNode = GetNewNode(x);
count++;
if(current == NULL)
{
current = newNode;
head = current;
}
else
{
current->left = newNode;
newNode->right = temp;
current = newNode;
current->left = head;
head->right = current;
}
printf("Add %s into database.\n\n", current->name);
}
void delete_name(char *x)
{
int i, j;
struct Node* recycle = current;
if(current == NULL)
{
printf("No data input.");
}
else
{
for (i = 0; i < count; i++)
{
if(recycle->name == x)
{
free(recycle);
j++;
printf("Delete %s from database.\n", x);
}
recycle = recycle->left;
}
if(j == 0)
{
printf("There is no %s in data", x);
}
current = recycle;
}
}
void print_clock(int number)
{
int i;
struct Node* temp = current;
if(temp == NULL)
{
printf("No data input.");
}
else
{
printf("Clockwise: \n");
for(i = 0; i < number; i++)
{
printf("%s ",temp->name);
temp = temp->left;
}
}
printf("\n\n");
}
void print_counter(int number)
{
int i;
struct Node* temp = current;
if(temp == NULL)
{
printf("No data input.");
}
else
{
printf("Counterclockwise: \n");
for(i = 0; i < number; i++)
{
printf("%s ",temp->name);
temp = temp->right;
}
}
printf("\n\n");
}
int main()
{
char s1;
char s2[nameLen];
char name[nameLen];
int number;
while(1)
{
printf("Enter the instruction: ");
scanf("%s %s", &s1, s2);
if (s1 == '+' && sscanf(s2, "%d", &number) == 1)
{
printf("Print out %d name(s) clockwise.\n", number);
print_clock(number);
}
else if (s1 == '-' && sscanf(s2, "%d", &number) == 1)
{
printf("Print out %d name(s) counterclockwise.\n", number);
print_counter(number);
}
else if (s1 == '+' && sscanf(s2, "%s", name) == 1)
{
add_name(s2);
}
else if (s1 == '-' && sscanf(s2, "%s", name) == 1)
{
delete_name(s2);
}
else if (s1 == 'e')
{
printf("Bye.\n");
break;
}
else // No match.
printf("Wrong Input. %s %s\n", &s1, s2);
}
system("pause");
return 0;
}
Statement recycle->name == x checks if two pointers point to the same object in memory. It does not check if two (different) objects in memory have equal content.
Use
if (strcmp(recycle->name, x) == 0) { ...
to check for equal string contents.
I'm studying about circular queue in data structure . As you can see from the code below, I try to delete a specific data and insert data on Circular queue. However, when I try to run it there's a problem when deleting data and insert a new one. I had no clue about it. I was trying to solve this for many hours but I can't find anything. Any help would be appreciated.
#include <stdio.h>
#define SIZE 3
typedef struct queue{
int val[SIZE]={NULL};
int front;
int rear;
}queue;
void display(struct queue *q);
void enqueue(struct queue *q){
int ins,i=1;
if((q->rear == SIZE-1 && q->front == 0) || (q->rear == q->front-1)){
printf("Queue is full!\n");
}
else if (q->front == -1)
{
printf("Enqueue data : ");
scanf("%d",&ins);
q->front = q->rear = 0;
q->val[q->rear] = ins;
}
else if (q->rear == SIZE-1)
{
printf("Enqueue data : ");
scanf("%d",&ins);
q->rear = 0;
q->val[q->rear] = ins;
}
else
{
printf("Enqueue data : ");
scanf("%d",&ins);
q->rear++;
q->val[q->rear] = ins;
}
display(q);
};
void dequeue(struct queue *q);
int main(){
queue *q= new queue;
q->front = -1;
q->rear = -1;
char select;
flag1:
printf("\n------- Please Select Operations ---------\n");
printf("Press e: Enqueue\n");
printf("Press d: Dequeue\n");
printf("Press x: Exit Program\n");
printf("------------------------------------------\n");
printf("Select Menu : ");
scanf(" %c",&select);
switch(select){
case 'e' : enqueue(q); goto flag1;
case 'd' : dequeue(q); goto flag1;
case 'x' : break;
}
return 0;
}
void dequeue(struct queue *q){
int deq,hold;
if (q->front == -1)
{
printf("Queue is Empty");
}
else
{
printf("Dequeue data : ");
scanf("%d",&deq);
for(int i=0;i<SIZE;i++){
if(deq==q->val[i]){
if(i==q->front){
q->val[q->front]=NULL;
q->front = i;
q->rear=q->rear+1;
if(q->rear=SIZE-1){
q->rear=0;
}
}
else
q->val[q->front]=NULL;
}
}
display(q);
}
};
void display(struct queue *q){
int i;
printf("Queue : |");
for (i= 0; i<SIZE; i++){
if(q->val[i]==NULL){
printf(" |");
}
else
printf("%d|", q->val[i]);
}
};
GIGO!
Your code is overly complex.
Complex code requires complex testing and debugging.
Try the following code:
void enqueue( struct queue *q, int v) {
int r = (q.rear + 1) % SIZE
if(( r == q.front) {
printf( "Queue is full!\n");
} else {
q.val[ q.rear] = v;
q.rear = r;
}
};
int dequeue( struct queue *q) {
if( q.front == q.rear) {
printf( "Queue is Empty");
v = NULL; # or whatever (required as a return value)
} else {
v = q.val[ q.front];
q.front = ( q.front + 1) % SIZE;
}
return v;
};
int main() {
queue *q = new queue;
q->front = q->rear = 0;
...
};
To summarize:
rear is index of the youngest element
front is the index of the oldest element
% (the modulus operator) take care of the index overwrapping.
(front == rear) means empty buffer
((rear +1) % SIZE == front) means full buffer.
Please note that this simple algorithm always leave an unused element in the buffer. This is required to distinguish "full" from "empty".
Circular Queue in Java
public class CircularQueue<T> {
private Object[] arr;
private int front = -1, rear = -1;
public CircularQueue(int initialCapacity) {
this.arr = new Object[initialCapacity];
}
public void add(T val) throws Exception {
if (isEmpty()) {
rear++;
front++;
} else if (isFull()) {
throw new Exception("Queue is full");
}
arr[rear] = val;
rear = (rear + 1) % arr.length;
}
public T delete() throws Exception {
if (isEmpty()) {
throw new Exception("No elements in Queue");
}
T temp = (T) arr[front];
front = (front + 1) % arr.length;
return temp;
}
public boolean isEmpty() {
return (front == -1 && rear == -1);
}
public boolean isFull() {
return (front == rear);
}
#Override
public String toString() {
String ret = "[ ";
int temp = front;
do {
ret += arr[temp] + " ";
temp = (temp + 1) % arr.length;
} while (temp != rear);
ret += "]";
return ret;
}
}
Your code is overly and dumbly complex. I think you don't understand circular-queues well.
Here's my simplified code. You can check it out and learn something.
#include<stdio.h>
#include<stdlib.h>
typedef struct _node {
int size,front,rear,*q;
} node;
node *pu;
void initialize() {
if(pu!=NULL)
free(pu);
pu = (node *)malloc(sizeof(node));
printf("\nEnter the size of the queue :- ");
scanf(" %d",&pu->size);
pu->q = (int *)malloc(sizeof(int) * pu->size +1);
pu->front = pu->rear = 0;
}
int isempty() {
return (pu->front == pu->rear);
}
int isfull() {
return ((pu->rear + 1) % pu->size == pu->front);
}
void enqueue(int x) {
if(isfull())
return;
else {
pu->q[pu->rear=(pu->rear +1) % pu->size] = x;
}
}
int dequeue() {
if(isempty())
return '$';
else {
return pu->q[ pu->front = (pu->front + 1) % pu->size];
}
}
void display() {
if(isempty())
return;
else {
for( int i = pu->front + 1; i != (pu->rear +1)%pu->size ; i = ( i +1) % pu->size)
printf("\n %d",pu->q[i]);
}
}
int main() {
// do something in here with the functions.
return 0;
}
I'm writing a function to search an element in linked list in c, it works if the element exist, but I don't know how to write the code so that it returns "not found" if the element doesn't exist.
Here is the search function
void search(Node *head, int c)
{
int count = 0;
Node *temp3 = head;
while (temp3 != NULL) {
if (temp3->data != c) {
count++;
temp3 = temp3->next;
printf("Element found at: %d \n", count);
} else
printf("Element not found");
}
}
You should just loop through the list and set a flag or count the occurrences when you find the element (in addition to printing its node number). Then you can just test the flag to print "Element not found" if that's the case:
void search(Node *head, int c) {
int count = 0, found = 0;
for (Node *temp3 = head; temp3 != NULL; temp3 = temp3->next) {
count++;
if (temp3->data == c) {
found++;
printf("Element found at: %d\n", count);
}
}
if (!found) {
printf("Element not found\n");
}
}
In case your list can only contain one occurrence of the element, it would probably be more helpful to return it:
Node *search(Node *head, int c)
{
Node *n;
for (n = head; n != NULL; n = n->next) {
if(n->data == c)
break;
}
return n;
}
// Somewhere else
Node *res = search(head, 123);
if (res != NULL) {
// Do something
} else {
puts("Element not found.");
}
Possible solution could be like this (-1 is interpreted as not found):
int search(Node* head, int c)
{
int count = 0;
Node* temp3 = head;
while(temp3 != NULL )
{
if(temp3 -> data == c) {
return count;
} else(temp3 -> data != c) {
++count;
temp3 = temp3 -> next;
}
}
return -1;
}
void search(Node* head, int c)
{
int count = 0;
Node* temp3 = head;
while(temp3 != NULL )
{
if(temp3 -> data != c) {
count ++;
temp3 = temp3 -> next;
printf("Element found at: %d \n", count);
break;
}
}
if(temp3 == NULL)
printf("Element not found");
}
here you go
#include <stdio.h>
#include <malloc.h>
struct el {
int info;
struct el* next;
};
struct el* create_el(struct el* Li)
{
int num;
printf("\n\nInsert number:\n\n");
scanf("%d", &num);
Li = (struct el*)malloc(sizeof(struct el));
if (Li != NULL) {
Li->info = num;
Li->next = NULL;
}
return (Li);
}
struct el* push(struct el* L, struct el* e)
{ //inserts the elements from the head of the list
if (L == NULL)
return (e);
else {
e->next = L;
L = e;
return (L);
}
}
void visualize(struct el* primo)
{
printf("\n\nList-->");
while (primo->next != NULL) {
printf("%d", primo->info);
printf("-->");
primo = primo->next;
}
if (primo->next == NULL)
printf("%d-->NULL", primo->info);
}
struct el* cancel(struct el** P, int val)
{ //delete element
struct el* prec = NULL;
struct el* curr = (*P);
if (P == NULL) //case empty list
return NULL;
else if (prec == NULL) {
if (curr->info == val) { //case 2 : if the element is the head
(*P)->next = curr->next;
free(curr);
curr = NULL;
}
}
else {
while ((curr != NULL) && (curr->info != val)) {
prec = curr;
curr = curr->next;
}
if (curr->next == NULL && curr->info == val) { // case 3: the elemnt is the last one
prec->next = NULL;
free(curr);
curr = NULL;
return (prec);
}
else {
if (curr->info == val) { //other cases
prec->next = curr->next;
free(curr);
curr = NULL;
return (prec);
}
}
}
}
int main()
{
struct el* head = NULL;
struct el* element;
struct el* list = NULL;
int i, n;
int elem;
printf("Insert the number of elements for the list:\n\n");
scanf("%d", &n);
for (i = 0; i <= n; i++) {
element = create_el(head);
if (element != NULL) {
list = push(list, element);
}
}
visualize(list);
printf("\n\nInsert the element that you want to cancel:");
elem = scanf("%d", &elem);
cancel(&list, elem);
visualize(list);
}
All I've wanted to do was delete an element from a listr, but after all the procediment the list is printed without any modification.
Can anyone see whats wrong in the function cancel(which is meant to delete an element by including any possible position of it)?
In your function cancel, P is definitely not NULL (assuming OS has assigned it an address initially).
prec is NULL the before execution enters if loop.
So, execution executes the line
if(curr->info==val)
Now, if the value, val, you have provided doesn't match curr->info then execution exits the function without deleting any node.