How can i solve the logical error in following code - c

I Have a Problem in following code
#include<stdio.h>
#include<stdlib.h>
struct linked
{
int val;
struct linked *before;
struct linked *next;
};
void get(struct linked *var);
void printforward(struct linked *var);
void printbackward(struct linked *var);
int main()
{
struct linked *ptr,*temp;
ptr=(struct linked*)malloc(sizeof(struct linked));
if(ptr==NULL)
{
printf("NOT ENOUGH MEMOREY");
exit(2);
}
ptr->before=NULL;
get(ptr);
printf("\nForward:\n");
printforward(ptr);
for(temp=ptr;temp->next;temp=temp->next)
{
temp->next->before=(struct linked*)temp;
}
printf("\nBackward:\n");
printbackward(temp->before);
}
void get(struct linked *var)
{
printf("Enter the number (-99) to quit:");
scanf("%d",&var->val);
if(var->val==-99)
{
var->next=NULL;
return;
}
else
{
var->next=(struct linked*)malloc(sizeof(struct linked));
if(var->next==NULL)
{
printf("NOT ENOUGH MEMOREY");
exit(2);
}
get(var->next);
}
}
void printforward(struct linked *var)
{
if(var->next==NULL)
{
return;
}
else
{
printf("\n%d",var->val);
printforward(var->next);
}
}
void printbackward(struct linked *var)
{
if(var->before==NULL)
{
printf("\n%d",var->val);
return;
}
else
{
printf("\n%d",var->val);
printforward(var->before);
}
}
output:
Enter the number (-99) to quit:1
Enter the number (-99) to quit:2
Enter the number (-99) to quit:3
Enter the number (-99) to quit:4
Enter the number (-99) to quit:5
Enter the number (-99) to quit:6
Enter the number (-99) to quit:7
Enter the number (-99) to quit:8
Enter the number (-99) to quit:9
Enter the number (-99) to quit:0
Enter the number (-99) to quit:-99
Forward:
1
2
3
4
5
6
7
8
9
0
Backward:
0
9
0
Process returned 0 (0x0) execution time : 22.297 s
Press any key to continue.
Expected output:
Enter the number (-99) to quit:1
Enter the number (-99) to quit:2
Enter the number (-99) to quit:3
Enter the number (-99) to quit:4
Enter the number (-99) to quit:5
Enter the number (-99) to quit:6
Enter the number (-99) to quit:7
Enter the number (-99) to quit:8
Enter the number (-99) to quit:9
Enter the number (-99) to quit:0
Enter the number (-99) to quit:-99
Forward:
1
2
3
4
5
6
7
8
9
0
Backward:
0
9
8
7
6
5
4
3
2
1
Let me know What's problem in the code,I am learning linked list in c language,I want to write a code for double way linked list But I a have a logical error in above problem,I did not get clear idea Why The above code did not work,so I am request to clear the doubt.

Why you're doing this with recursion, I have no idea, but in that spirit, consider this.
You're invoking printforward from printbackward, which makes no sense.
Your casts are not helping, and in fact, they're masking the real problems. Memory allocations, nor like-pointer or to/from void-pointer casting is required, nor recommended, in C. Read here for why
All four operations can be done recursively, and in fact, you don't even need the "before" pointer but I kept it nonetheless. You can:
Build your list
Forward-print your list
Backward-print your list
Cleanup your list
... all using recursion (I leave why you would want to as a different issue).
Code
#include <stdio.h>
#include <stdlib.h>
struct linked
{
int val;
struct linked *before;
struct linked *next;
};
struct linked *get(struct linked *before);
void printforward(struct linked const *var);
void printbackward(struct linked const *var);
void cleanup(struct linked *lst);
int main()
{
struct linked *ptr = get(NULL);
printf("Forward: ");
printforward(ptr);
fputc('\n', stdout);
printf("Backward: ");
printbackward(ptr);
fputc('\n', stdout);
cleanup(ptr);
}
struct linked *get(struct linked *before)
{
printf("Enter the number (-99) to quit:");
int value = -99;
if (scanf("%d", &value) != 1 || value == -99)
return NULL;
struct linked *p = malloc(sizeof *p);
if (p != NULL)
{
p->before = before;
p->val = value;
p->next = get(p);
}
return p;
}
void printforward(struct linked const *var)
{
if (var)
{
printf("%d ", var->val);
printforward(var->next);
}
}
void printbackward(struct linked const *var)
{
if (var)
{
printbackward(var->next);
printf("%d ", var->val);
}
}
void cleanup(struct linked *lst)
{
if (!lst)
return;
cleanup(lst->next);
free(lst);
}
Console
Enter the number (-99) to quit:1
Enter the number (-99) to quit:2
Enter the number (-99) to quit:3
Enter the number (-99) to quit:4
Enter the number (-99) to quit:5
Enter the number (-99) to quit:-99
Forward: 1 2 3 4 5
Backward: 5 4 3 2 1

here is an example of a simple double linked list construction with basic operation on it, such as addition and insertion of a node, and iteration in both directions.
Basically, node is simple structure with two pointers on previous and next node in list, and simple data variable in form of an integer. Key point on operations is proper manipulation of prev-next pointers in a node and head-last pointers in list structure.
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
typedef struct tagNode
{
int data;
struct tagNode *next; /* pointer to previous node */
struct tagNode *prev; /* pointe to next node */
} NODE;
/* head of list */
typedef struct tagList
{
NODE *head; /* pointer to first node in list */
NODE *last; /* pointer to last node in list */
} LIST;
/* func proto's */
NODE* create_node(int data);
NODE* insert_node(LIST* l,NODE *p);
NODE* add_node(LIST* l, NODE *p);
void print_node(NODE *p);
int main()
{
LIST list = {NULL,NULL}; /* init list with NULLs */
/* add some nodes to list */
for( int i = 0; i < 6 ; i++ )
{
add_node(&list, create_node(i*5) );
}
/* print forward */
printf("Forward:\n");
NODE* p = list.head;
for( ;p != NULL; p = p->next )
{
print_node(p);
}
/* print backward */
printf("Backward\n");
for(p = list.last;p != NULL; p = p->prev )
{
print_node(p);
}
/* insert some nodes */
printf("Insert some nodes\n");
insert_node(&list, create_node(33));
insert_node(&list, create_node(23));
insert_node(&list, create_node(13));
/* print forward -list after inserts */
printf("Print forward after insert\n");
for(p = list.head; p != NULL; p = p->next )
{
print_node(p);
}
/* print backward */
printf("print backward after insert\n");
for( p = list.last;p != NULL; p = p->prev )
{
print_node(p);
}
}
NODE* create_node(int data )
{
NODE *p = malloc(sizeof(NODE));
p->next = NULL;
p->prev = NULL;
p->data = data;
}
/* add node to end of list */
NODE* add_node(LIST* list, NODE* p)
{
if(list->last == NULL )
{
printf("add first node into list\n");
list->last = p;
list->head = p;
p->next = NULL;
p->prev = NULL;
}
else
{
printf("add num %d\n", p->data);
list->last->next = p;
p->prev = list->last;
list->last = p;
p->next = NULL; /* terminate list */
}
return list->last;
}
void print_node(NODE *p)
{
printf("node data: %d\n",p->data);
}
/* insert a node into list,
* position depends on value of data
**/
NODE* insert_node(LIST* l, NODE *q)
{
/* scan list ... */
for( NODE* p = l->head;p != NULL; p = p->next )
{
if( p->next != NULL )
{
if( p->next->data > q->data )
{
q->next = p->next;
q->prev = p;
p->next->prev = q;
p->next = q;
return q; /* indicate success */
}
}
}
return NULL; /* indicate failure */
}

Related

Cannot store elements in a linked list

My goal is to create a linked list and store elements inside that list.
struct node
{
int a;
struct node *b;
} p,*temp,*head;
void create ( struct node *temp)
{
char c;
temp = malloc (sizeof(struct node));
printf("enter data\n");
scanf(" %d",&temp->a);
printf("do you want to insert another node y/n\n");
scanf("%s", &c);
if (c=='y')
{
create(temp->b);
}
else if ( c=='n')
{
temp->b= NULL;
temp=&p;
return;
}
}
void traverse ( struct node *head)
{
while(head != NULL)
{
printf("%d ",head->a);
head=head->b;
}
}
int main ()
{
int i,j,k,l,m,n;
do{
if(i==1)
{
printf("enter data\n");
scanf("%d",&p.a);
create (p.b);
}
else if ( i==2)
traverse(temp);
}
while(i!=3);
printf("%d",temp->a);
}
I can't recover the elements once i've stored them. When I try to traverse the list, it only gives me the first element of the list and nothing else.
In main
do {
if(i==1)
{
...
}
else if ( i==2)
traverse(temp);
}
while(i!=3);
must be something like
do {
if (scanf("%d", &i) != 1)
break;
if(i==1)
{
...
}
else if ( i==2)
traverse(temp);
}
while(i!=3);
to know what the user want (i not initialized in your code)
in create
scanf("%s", &c);
is wrong because c is a char rather than a string
Do not mix read of int and char because you will read newline and space when reading a character, so read a string for c, for instance
char c[2];
...
scanf("%1s", &c);
if (*c == 'y')
...
else if (c == 'n')
...
the return in else branch is useless, and in case the answer is not 'y' or 'n' you do nothing so you do not set temps, probably you have to just check if 'y' and all other answers must be considered to be 'n', or you need to ask again for the choice
in create you assign the local variable temps, that has no effect on p.b in main, you need to get a node** for instance
in main temp is used but never set elsewhere, and the variables j,k,l,m,n are useless. You also ask for the data in main while you also do in create, must not be done in main. The way you manage your variables do not allow you to modify/print the list
I encourage you to not use global variables the must you can, and to not use the same name for a global and local variable like you do for temp and head because that do not help the reader of your code
A proposal solving the problems :
#include <stdlib.h>
#include <stdio.h>
struct node
{
int a;
struct node * b;
};
/* flush input up to the end of the line */
void flush()
{
int c;
while ((c = getchar()) != '\n') {
if (c == EOF)
exit(-1);
}
}
void create (struct node ** l)
{
/* go to the end of the list */
while (*l != NULL)
l = &(*l)->b;
for (;;) {
char c[2];
int v;
printf("enter data\n");
if (scanf("%d", &v) != 1) {
puts("invalid value");
flush();
}
else {
*l = malloc (sizeof(struct node));
(*l)->a = v;
(*l)->b = NULL;
l = &(*l)->b;
for (;;) {
printf("do you want to insert another node y/n\n");
scanf("%1s", c);
if (*c == 'y')
break;
else if (*c == 'n')
return;
}
}
}
}
void traverse ( struct node *head)
{
while(head != NULL)
{
printf("%d ",head->a);
head = head->b;
}
putchar('\n');
}
int main ()
{
int i;
struct node *head = NULL;
for (;;) {
puts("enter choice : 1 to create new node, 2 to print list, 3 to exit");
if (scanf("%d", &i) != 1)
flush();
switch(i) {
case 1:
create(&head);
break;
case 2:
traverse(head);
break;
case 3:
return 0;
default:
break;
}
}
}
Compilation and execution :
/tmp % gcc -pedantic -Wextra -Wall t.c
/tmp % ./a.out
enter choice : 1 to create new node, 2 to print list, 3 to exit
2
enter choice : 1 to create new node, 2 to print list, 3 to exit
1
enter data
11
do you want to insert another node y/n
y
enter data
22
do you want to insert another node y/n
n
enter choice : 1 to create new node, 2 to print list, 3 to exit
2
11 22
enter choice : 1 to create new node, 2 to print list, 3 to exit
1
enter data
3
do you want to insert another node y/n
n
enter choice : 1 to create new node, 2 to print list, 3 to exit
2
11 22 3
enter choice : 1 to create new node, 2 to print list, 3 to exit
4
enter choice : 1 to create new node, 2 to print list, 3 to exit
3
I encourage you to add the free of the list
There are several issues here:
struct node
{
int a;
struct node *b;
} p,*temp,*head;
Why do you declare global variables and use it as function parameters ? Global variables are available globally, there is no need to pass them into functions. On the other hand, global variables should be avoided and used with care, so it would be better to create local variables (e.g. in main function) and pass them as parameters into next functions.
void create ( struct node *temp)
{
char c;
temp = malloc (sizeof(struct node));
printf("enter data\n");
scanf(" %d",&temp->a);
printf("do you want to insert another node y/n\n");
scanf("%s", &c);
if (c=='y')
{
create(temp->b);
}
else if ( c=='n')
{
temp->b= NULL;
temp=&p;
return;
}
}
This function looks wrong. temp function parameter is actually an internal function's variable, that is not an in/out parameter. In that case you can assign to the temp variable, but it will not for a list. Also temp function parameter shadows temp global variable. It is also a good think to return status of operation, usually '0' means no error, any other error value.
Another thing is to keep things as simple as possible. This will allow for more reuseability and goes with single responsibility principle. If function actually performs two tasks it should be split into two functions.
One more thing, you allocate memory dynamically but never free the memory. This will lead into memory losses.
A possible implementation of your list could be:
#include <stdio.h>
#include <stdlib.h>
typedef struct _node_t
{
int a;
struct _node_t * next;
} node_t;
static node_t * head = NULL;
static node_t * tail = NULL;
node_t * create(void)
{
node_t * temp = malloc(sizeof(node_t));
if (NULL == temp)
{
return NULL;
}
printf("Enter data\n");
scanf("%d", & temp->a);
return temp;
}
void append(node_t * data)
{
if (NULL == head)
{
head = tail = data;
}
else
{
tail->next = data;
tail = tail->next;
}
tail->next = NULL;
return;
}
int add_data(void)
{
node_t * data = NULL;
char answer = 'y';
data = create();
if (NULL == data)
{
return 1;
}
append(data);
return 0;
}
void traverse(void)
{
node_t * current = NULL;
for (current = head; current != NULL; current = current->next)
{
printf("%d ", current->a);
}
printf("\n");
return;
}
void cleanup(void)
{
node_t * current = head;
while (NULL != current)
{
head = head->next;
free(current);
current = head;
}
return;
}
int main(int argc, char ** argv)
{
int option = 3;
do
{
printf("Enter option:\n 1 - add data\n 2 - traverse list\n 3 - exit\n\n");
scanf("%i", & option);
switch (option)
{
case 1:
if (0 != add_data())
{
printf("ERROR:: Cannot allocate memory.\n");
cleanup();
return 1;
}
break;
case 2:
traverse();
break;
default:
if (option > 3)
{
printf("ERROR:: Improper option, try again.\n");
}
break;
}
}
while (option != 3);
cleanup();
return 0;
}
I tried making it as simple as possible and keeping your logic there.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
// create a new node
struct node* create(int data)
{
struct node *n = malloc(sizeof(struct node));
n->data = data;
n->next = NULL; // by default its not NULL, so we must set it
return n;
}
void traverse(struct node *head)
{
struct node *tmp = head;
while(tmp != NULL)
{
printf("%d\t",tmp->data);
tmp = tmp->next;
}
}
void cleanup(struct node *head)
{
struct node *cur = head;
struct node *next;
while(cur != NULL)
{
next = cur->next;
free(cur);
cur = next;
}
}
int main ()
{
int data;
struct node *head, *tmp;
// head node is always created
printf("enter data\n");
scanf("%d",&data);
head = tmp = create(data);
if(head == NULL) return -1;
// now we loop until we don't want to create any more nodes
while(1)
{
char another;
printf("do you want to insert another node y/n\n");
scanf(" %c", &another); // ignore all the previous whitespace
if(another == 'y')
{
printf("enter data\n");
scanf("%d",&data);
tmp->next = create(data);
tmp = tmp->next;
}
else break;
/*
// anything but 'y' breaks the loop, but it can be set to continue if neither 'y' nor 'n' was read:
else if(another == 'n') break;
else continue;
*/
}
traverse(head);
cleanup(head);
}
EDIT: as #Diodacus stated, i added cleanup and checking if malloc returned NULL

How can I reverse the order of a linked list?

I am trying to print out the results of the linked list in the reverse order that they were entered in. The program takes 3 inputs, Song name, song length (in seconds) and copyright. The program should take the list of songs and print the in the reverse order that they were entered in.
I am not too familiar with linked list. This is my first time using it as sort of a database.
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
//defining struct
typedef struct node
{
char songName[20];
int songLength;
int copyright;
struct node * next;
}node;
//defining prototypes
node *create(int n);
void display(node *head);
int main()
{
int n = 0;
node *head = NULL;
printf("How many entries?\n");
scanf("%d", &n);
//call to create list
head = create(n);
printf("\nThe linked list in order is:\n");
display(head);
return 0;
}
node *create(int n)
{
node *head = NULL;
node *temp = NULL;
node *p = NULL;
for (int i = 0; i < n; i++)
{
temp = (node*)malloc(sizeof(node));
printf("What is the name of song %d\n", i + 1);
//fgets(temp->songName, 20, stdin);
scanf("%s", &temp->songName);
printf("What is the length of song %d (in seconds)?\n", i + 1);
scanf("%d", &temp->songLength);
printf("Is song %d copyrighted?(1 = YES, 0 = NO)\n", i + 1);
scanf("%d", &temp->copyright);
temp->next = NULL;
if (head == NULL)
{
head = temp;
}
else
{
// if not empty, attach new node at the end
p = head;
while (p->next != NULL)
{
p = p->next;
}
p->next = temp;
}
}
return head;
}
void display(node *head)
{
node *p = NULL;
if (head == NULL)
{
printf("List is empty\n");
}
else
{
p = head;
while (p != NULL)
{
printf("Song: %s, ", p->songName);
printf("%d minutes, ", p->songLength);
if (p->copyright == 1)
{
printf("Copyrighted\n");
}
else if (p->copyright == 0)
{
printf("No copyright\n");
}
p = p->next;
}
}
}
So if Input the following:
Song 1 - All Star (song name), 237 (seconds), 0 (no copyrights)
song 2 - Crab Rave, 193, 0
song 3 - 7 rings, 185, 1(copyrights)
The output should be:
7 rings, 185, 1
Crab Rave, 193, 0
All Star, 237, 0
If you have a single (forward) linked list, the probably easiest way to print it in reverse order is using recursion:
void display_recursive(node *n) {
if (!n) {
return;
}
display_recursive(n->next);
printf("Song: %s, ", n->songName);
...
}
Recursion means that a function is calling itself (until some end-condition, the anchor, is reached).
By that way, program flow will build up a "stack" of display_recursive- function calls, with the first node, then the second node, ..., until it reaches the last node; by then, recursion stops, and the print part of display_recursive is handled, starting with the last node backwards.
Hope this explanation helps; Try it out in the debugger to see what happens.

scanf() running endlessly, program stops running on a statement

This is the code for BFT(breadth first traversal) for a connected graph.
I run the code then I successfully make the adjacency list and also successfully print the adjacency list but after it program stops at when I take input from user to start the BFS from that inputed node.
scanf() is running infinitely or other error I can't able to identify.
#include<stdio.h>
#include<stdlib.h>
typedef struct root //the adjacency list which have all the vertices
{
int info;
struct adjacent *adj;
struct root *next;
} root;
typedef struct adjacent //Linked list which store adjacent nodes of any nodes in adj list.
{
int info;
struct adjacent *adj;
} adjacent;
typedef struct node // to make queue to store nodes to be explored.
{
int info;
struct node *next;
} nodeQ;
void insert(nodeQ **ft,nodeQ **rr,int n) // insert func of Q
{
nodeQ * new=(nodeQ *)malloc(sizeof(nodeQ));
new->info = n;
new->next = NULL;
if(*ft == NULL)
{
*ft=new;
*rr=new;
}
else
{
(*rr)->next = new;
*rr = new;
}
}
int delete(nodeQ **ft,nodeQ **rr) //delete func of Q
{
int value=(*ft)->info;
nodeQ *temp=*ft;
*ft=(*ft)->next;
free(temp);
if(*ft==NULL)
*rr=NULL;
return value;
}
void BFS(int total_nodes,int node_tobe_explored,root *head,nodeQ **ft,nodeQ **rr)
{
printf("ff");
int * visited=(int *)malloc(sizeof(int)*total_nodes);
for(int i=0;i<total_nodes;i++)
visited[i]=0; //initialize all value in visited array with 0
printf("aa");
visited[node_tobe_explored] = 1;
printf("%d",node_tobe_explored);
while(1) // this loop iterates until all nodes are not explored.
{
root *t=head;
while(t->info != node_tobe_explored) // this find the node address(t) of the node_tobe_explored.
t=t->next;
printf("bb");
adjacent * adj_node = t->adj;
while(adj_node)
{
if(visited[adj_node->info] == 0) //if that adjacent node is not visited then also we visit it.
{
int adj_node_val = adj_node->info;
visited[adj_node_val] = 1;
insert(ft,rr,adj_node_val);
printf(", %d",adj_node_val);
}
}
printf("cc");
if(*rr==NULL) //if Q is empty, means all nodes are explored, so we return.
return;
else //otherwise explore first node present in Q
node_tobe_explored = delete(ft,rr);
}
}
int main()
{
char ch;
int no,tot_nodes,start;
nodeQ *front=NULL,*rear=NULL;
printf("enter the no. of nodes: ");
scanf("%d",&tot_nodes);
root *head = NULL;
no = tot_nodes;
while(no!=0)
{ //to make the main chain of adjacency list.
root *new=(root *)malloc(sizeof(root));
new->info = no;
new->adj = NULL;
new->next = head;
head = new;
no--;
}
root *temp = head;
while(temp!=NULL)
{ // to add the adjacent nodes to main chain.
printf("enter the nodes adjacent to %d:\n",temp->info);
do
{
int element;
printf(" enter node: ");
scanf("%d",&element);
adjacent *nw = (adjacent *)malloc(sizeof(adjacent));
nw->info = element;
nw->adj = temp->adj;
temp->adj = nw;
printf("more adjacent nodes y/n: ");
ch=getchar();
ch=getchar();
}while(ch=='Y'||ch=='y');
temp=temp->next;
}
printf("display of the structur of the linked list formed:\n");
root * head1=head;
while(head1) // to display the formed adj. list.
{
printf("%d--",head1->info);
adjacent *t = head1->adj;
while(t)
{
printf("%d,",t->info);
t=t->adj;
}
printf("\n");
head1=head1->next;
}
do
{
printf("enter the node value from which you want to start BFS: ");
printf("before [enter image description here][1]");
int st;
scanf("%d",&st);
printf("after");
BFS(tot_nodes,st,head,&front,&rear); //calling BFS func.
printf("do you want to print more traversals y/n: ");
ch=getchar();
ch=getchar();
}while(ch=='Y'||ch=='y');
}
Excerpt from OPs source code:
printf("do you want to print more traversals y/n: ");
ch=getchar();
ch=getchar();
}while(ch=='Y'||ch=='y');
The intention was probably to read a letter (y or n) and the \n which confirmed the input.
So, the 2nd ch=getchar(); (for ENTER) overrides the previously read letter. The following fix would change this:
printf("do you want to print more traversals y/n: ");
ch=getchar();
getchar(); /* ignore the returned value - it's just to consume '\n'. */
}while(ch=='Y'||ch=='y');
Btw. this is something which should have been uncovered by a step-wise debugging of the cited four lines...

Command terminated by signal 11

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
struct node{
char data;
int p;
struct node *ptr;
};
struct node *start=NULL;
struct node *insert()
{
struct node *new_node,*z;
int num;
char s;
printf("\nEnter -1 to stop.");
printf("\nEnter the characters and their priorities: ");
scanf("\n%c %d",&s,&num);
while(num!=-1)
{
new_node=(struct node *)malloc(sizeof(struct node));
new_node->data=s;
new_node->p=num;
if(start==NULL)
{
start=new_node;
z=start;
new_node->ptr=NULL;
}
else
{
z->ptr=new_node;
new_node->ptr=NULL;
z=z->ptr;
}
scanf("%c %d",&s,&num);
}
return start;
}
struct node *display()
{
struct node *z;
z=start;
printf("\nDisplaying elements:\n");
while(z!=NULL)
{
printf("\t%c [Priority=%d]\n",z->data,z->p);
z=z->ptr;
}
return start;
}
struct node *sortit()
{
struct node *z,*q;
int t;
char x;
z=start;
while(z->ptr!=NULL)
{
q=z->ptr;
while(q!=NULL)
{
if(z->p>q->p)
{
t=z->p;
x=z->data;
z->p=q->p;
z->data=q->data;
q->p=t;
q->data=x;
}
q=q->ptr;
}
z=z->ptr;
}
return start;
}
struct node *new_insert()
{
struct node *y,*z;
int n;
char s;
y=(struct node *)malloc(sizeof(struct node));
printf("\nEnter character and priority for new node:");
scanf("%c %d",&s,&n);
printf("%c",s);
y->data=s;
y->p=n;
printf("%c",y->data);
printf("%d",y->p);
if(n<start->p)
{
y->ptr=start;
start=y;
printf("%d",y->p);
}
else
{printf("\nff");
z=start;
while(z->ptr->p<=n&&z->ptr!=NULL)
z=z->ptr;
y->ptr=z->ptr;
z->ptr=y;
}
return start;
}
int main()
{
insert();
display();
sortit();
display();
new_insert();
display();
return 0;
}
In this C code, I have tried to implement priority queues.
Everything works perfectly fine except the new_insert() function. The print statements after y->p=n; in new_insert() function print 0.
Hence, the function doesn't work properly. Also, in display() function the print statement prints the [Priority] twice.
Hence, I am not able to add an external node in my priority queue.
Well, you code is not far from working I think.
There are some problems that can be corrected:
the scanf usage is problematic
%c selector must be use with caution, use " %c %d" to prevent end of line problems
return value must be checked
in function insert, z may not be initialized (if insert() is called when start is not NULL)
You don't need to cast malloc returned value.
I tested the following code with this input:
a 2
b 3
c 1
d -1
e 0
And I got this result:
Enter -1 to stop.
Enter the characters and their priorities:
Displaying elements:
a [Priority=2]
b [Priority=3]
c [Priority=1]
Displaying elements:
c [Priority=1]
a [Priority=2]
b [Priority=3]
Enter character and priority for new node:
s: 'e' n: '0'
e00
Displaying elements:
e [Priority=0]
c [Priority=1]
a [Priority=2]
b [Priority=3]
Seems to work isn't? You can test it online
And here's the corrected code:
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
struct node{
char data;
int p;
struct node *ptr;
};
struct node *start=NULL;
struct node *insert()
{
/* initialize z in case of start is not null */
struct node *new_node,*z = start;
int num, ok;
char s;
printf("\nEnter -1 to stop.");
printf("\nEnter the characters and their priorities: ");
/* read the scanf return value */
ok = scanf(" %c %d",&s,&num);
/* and assert two elements have been read*/
while(ok == 2 && num!=-1)
{
new_node=malloc(sizeof(struct node));
new_node->data=s;
new_node->p=num;
if(start==NULL)
{
start=new_node;
z=start;
new_node->ptr=NULL;
}
else
{
z->ptr=new_node;
new_node->ptr=NULL;
z=z->ptr;
}
ok = scanf(" %c %d",&s,&num);
}
return start;
}
struct node *display()
{
struct node *z;
z=start;
printf("\nDisplaying elements:\n");
while(z!=NULL)
{
printf("\t%c [Priority=%d]\n",z->data,z->p);
z=z->ptr;
}
return start;
}
struct node *sortit()
{
struct node *z,*q;
int t;
char x;
z=start;
while(z->ptr!=NULL)
{
q=z->ptr;
while(q!=NULL)
{
if(z->p>q->p)
{
t=z->p;
x=z->data;
z->p=q->p;
z->data=q->data;
q->p=t;
q->data=x;
}
q=q->ptr;
}
z=z->ptr;
}
return start;
}
struct node *new_insert()
{
struct node *y,*z;
int n, ok;
char s;
printf("\nEnter character and priority for new node:");
ok = scanf(" %c %d",&s,&n);
if (2 == ok)
{
/* alloc y after having check that user gave usage stuff */
y = malloc(sizeof(struct node));
y->data=s;
y->p=n;
printf("%c",y->data);
printf("%d",y->p);
if(n<start->p)
{
y->ptr=start;
start=y;
printf("%d",y->p);
}
else
{
printf("\nff");
z=start;
while(z->ptr->p<=n&&z->ptr!=NULL)
z=z->ptr;
y->ptr=z->ptr;
z->ptr=y;
}
}
return start;
}
int main()
{
insert();
display();
sortit();
display();
new_insert();
display();
return 0;
}

Ascending order Linked List in C

I have been tasked with implementing an insert function which will be used in a project. If user input is 1 2 3 4, the desired output of the print statement would be 1, 2, 3, 4. Currently, my print statement is returning 4, 3, 2, 1 but I believe this to be correct. I think my issues lie within my input function (which is nested within a while loop to get user input). This is using C
Any help would be appreciated.
struct set {
int data;
struct set* next_p;
};
struct set* getInput( struct set* head_p, int val ) {
struct set* temp;
temp->data = val;
temp->next_p = head_p;
return temp;
} /* getInput */
struct set* makeSet( struct set* head_p ) {
int val;
printf( "Please enter a positive integer, or a negative to stop: \n" );
scanf("%d", &val);
while ( 100 ) {
head_p = getInput( head_p, val );
scanf("%d", &val);
}
return head_p;
}
Sorry mate was busy but hey i fixed your code.I already mentioned the problem was that you were appending the newNode before the head.
#include <stdio.h>
#include <stdlib.h>
struct set {
int data;
struct set* next_p;
};
struct set* getInput( struct set* ptr, int val )//appends a newNode to ptr which is the last node of Linked list
{
struct set* temp=NULL;
temp = (struct set*)malloc(sizeof(struct set));
temp->data = val;
temp->next_p = NULL;
if(ptr!=NULL)//if Linked list has been created,i.e.,only if we have a head run this
ptr->next_p=temp;
return temp;
} /* getInput */
struct set* makeSet( struct set* head_p ) {
int val;
struct set* ptr=head_p;
printf( "Please enter a positive integer, or a negative to stop: \n" );
while (1) {
scanf("%d", &val);
if(val>=0)
ptr=getInput( ptr, val );//appends only value>=0 to linked list else breaks from the infinite loop
else
break;
if(head_p==NULL)//To set the head of the linked List! True only for the 1st node in the linked list
head_p=ptr;
}
return head_p;
}
void display(struct set* head_p)
{
if(head_p==NULL)
printf("\nno List in Memory\n"); //
else
{
struct set* ptr=head_p;
printf("\n the linked list is\nHead");
while(ptr!=NULL)
{
printf("-->%d",ptr->data);
ptr=ptr->next_p;
}
}
}
int main()
{
struct set* head_p=NULL;
head_p=makeSet((head_p));//returns the head of the linked list created
display(head_p);//displays the linked list
return 0;
}
struct set* make_aSet(int val ) {
struct set* temp;
if((temp = malloc(sizeof(*temp))) != NULL){
temp->data = val;
temp->next_p = NULL;
} else {
fprintf(stderr, "can't make new a set\n");
}
return temp;
}
struct set* makeSet(void) {
struct set dummy_head, *current = &dummy_head;
int val;
printf( "Please enter a positive integer, or a negative to stop: \n" );
while (1==scanf("%d", &val) && val >= 0 ) {
current->next_p = make_aSet( val );
current = current->next_p;
}
return dummy_head.next_p;
}

Resources