This is the code of priority queue using linked list
i have two doubts in this code
1) This code is part of my insert function
if((*addofhead)->priority <= newnode->priority ){
struct node* temp=*addofhead;
while(temp->next!=NULL&&temp->priority <newnode->priority ){
temp=temp->next;
}
newnode->next=temp->next;
temp->next=newnode;
return;
}
why we can not do temp!=NULL in while loop instead of temp->next!=NULL because temp!=NULL will also make loop exit in one more iteration but it is crashing what is the reason of crashing
2)I want to make a priority queue such that the element which has least priority
should be removed first and elements which has same priority then the element will be removed first which was added first
input part from main function
insert(&head,3,5);
insert(&head,2,2);
insert(&head,1,1);
insert(&head,7,1);
insert(&head,11,1);
insert(&head,8,5);
insert(&head,9,5);
I am getting output for this 1 2 11 7 3 8 9 but its output should be 1 7 11 2 3 8 9
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
int priority;
struct node* next;
};
struct node* getnewnode(int data,int priority){
struct node* newnode=malloc(sizeof(struct node));
newnode->data=data;
newnode->next=NULL;
newnode->priority=priority;
return newnode;
}
void insert(struct node** addofhead,int data,int priority){
struct node* newnode=getnewnode(data,priority);
if(*addofhead==NULL){
*addofhead=newnode;
printf("head in insert is %d",*addofhead);
return;
}
if((*addofhead)->priority > newnode->priority){
newnode->next=*addofhead;
*addofhead=newnode;
return;
}
if((*addofhead)->priority <= newnode->priority ){
struct node* temp=*addofhead;
while(temp->next!=NULL&&temp->priority <newnode->priority ){
temp=temp->next;
}
newnode->next=temp->next;
temp->next=newnode;
return;
}
}
int removee(struct node** head){
if(*head==NULL)
return -1;
int temp=(*head)->data;
*head=(*head)->next;
return temp;
}
int main(){
struct node* head=NULL;
insert(&head,3,5); /// 3
insert(&head,2,2); /// 2,3
insert(&head,1,1); /// 1,2,3
insert(&head,7,1);
insert(&head,11,1);
insert(&head,8,5); /// 1,7,2,3
insert(&head,9,5);
struct node* temp=head;
while(temp)
{
printf(" %d ",temp->data);
temp=temp->next;
}
printf("\n head in main after insertion is %d",head);
}
why we can not do temp!=NULL in while loop instead of temp->next!=NULL (?)
Because the line after the loop has temp->next; #Jonathan Leffler.
The usual goal on marching down a linked list for insertion is to know the pointer of the previous node so its .next member may be updated.
Code has 2 functional problems
Comparing wrong priorities
// while(temp->next!=NULL&&temp->priority <newnode->priority ){
while(temp->next!=NULL&&temp->next->priority <newnode->priority ){
// ^^^^^^
Wrong compare when ==
// while(temp->next!=NULL&&temp->next->priority <newnode->priority ){
while(temp->next!=NULL&&temp->next->priority <= newnode->priority ){
// ^^^^^^ ^^
Also use %p to print a void *, not "%d" to print a pointer.
// printf("head in insert is %d",*addofhead);
printf("head in insert is %p",(void *) (*addofhead));
What was very useful to advance this was to create a helper function to print the data. It was then easy to call it after each insertion to narrow the issues.
void pq(const struct node* p) {
while (p) {
printf("(data %d,pri %d) ", p->data, p->priority);
p = p->next;
}
puts("");
}
I found OP's insert() overly complex. See #wildplasser.
Related
This program should delete the N-node in a singly linked list. If i put N = 1 or N = 2 it's ok, the program works. But with N = 0 the output prints infinite nodes with random values (after deleting the node 0). I think the program can't see the new head. Thx for the help!
#include <stdio.h>
#include <stdlib.h>
#define N 0
struct node {
int data;
struct node *next;
};
void printlist(struct node *head){
struct node *current=head;
int i=0;
while (current!=NULL){
printf("node number %d \t : %d\n", i, current->data);
current=current->next;
i++;
}
}
int deletenode(struct node *head,int n){
struct node *current=head;
struct node *previous=head;
int i=0;
while(current!= NULL){
if (n==i && i!=0){
previous->next=current->next;
free(current);
return 1;
}
else if (n==i && i==0){
head=head->next;
free(current);
return 1;
}
i++;
previous=current;
current=current->next;
return 0;
}
printf("error\n");
exit(EXIT_FAILURE);
}
void main(){
struct node *n1=malloc(sizeof(struct node));
struct node *n2=malloc(sizeof(struct node));
struct node *n3=malloc(sizeof(struct node));
struct node *head=n1;
n1->data=5;
n1->next=n2;
n2->data=10;
n2->next=n3;
n3->data=15;
n3->next=NULL;
printf("\n\nbefore\n");
printlist(head);
deletenode(head,N);
printf("\n\nafter\n");
printlist(head);
}
I'm using currentas a temp pointer , because after the head shift on the second node i need a pointer to the old head and use free.
C always passes by value, so changing a parameter has no effect on the caller.
void foo(int i) {
i = 1234; // No effect on caller.
}
void foo(int *p) {
p = NULL; // No effect on caller.
}
If you want to modify a variable (such as the caller's head), you need to pass a pointer to it. (You can still change that to which a pointer references.)
int deletenode(struct node **head, int n) {
...
}
deletenode(&head, N);
Now, you could simply replace every instance of head in your code with (*head) to account for the new calling convention, but that would waste an opportunity for simplification. By having a pointer to a struct node *, we don't need to handle head (a struct node *) and prev_node->next (a struct node *) differently.
int delete_node_n(struct node **ptr, unsigned n) {
// Make `ptr` point to the pointer we want to modify.
// This will either be the `head` variable
// or the `next` field of some node.
while (1) {
if (!*ptr)
return 0;
if (!n)
break;
ptr = &( (*ptr)->next );
--n;
}
struct node *to_free = *ptr;
*ptr = (*ptr)->next;
free(to_free);
return 1;
}
This program is of priority queue where i am storing string as data and queue is created using linked list the element having least number (as priority no) has higher priority that is it will be inserted towards head node and so while the time of removing (pop or dequeue) that element will be removed first.(for eg 1 has higher Priority than 2)
#include<stdio.h>
#include<stdlib.h>
struct node {
char *string;
int priority;
struct node* next;
};
struct node *head;
struct node* getnewnode(char *s,int p){
struct node* newnode=(struct node*)malloc(sizeof(struct node));
newnode->string=s;
newnode->priority=p;
newnode->next=NULL;
return newnode;
}
void push(char* str,int p){
struct node* node1=getnewnode(str,p);
if(head==NULL){ //if the element is inserted in empty list
head=node1;
}
if(head->priority > p )
{
node1->next=head;
head=node1;
}
else
{
struct node* temp=head;
while(temp->next!=NULL&&temp->priority <= p){
temp=temp->next;
}
while(temp->next!=NULL&&temp->priority <= p) is correct or not because if the pushed element priority is matching than this new element will be placed after the present one(having same priority)
node1->next=temp->next;
temp->next=node1;
}
}
void pop(){
struct node* temp=head;
head=head->next;
free(temp);
}
char* peek(){
return head->string;
}
int main(){
head=NULL; //head is null initially
char a[10]="akash";
push(a,1);
char b[20]="rahul";
push(b,3);
printf("%s",peek());
}
It is not showing desired output but it is crashing
int main(){
head=NULL;
char* a=(char *)malloc(sizeof(char)*10);
a="akash";
push(a,1);
char* b=(char *)malloc(sizeof(char)*10);
b="rahul";
push(b,3);
char* c=(char *)malloc(sizeof(char)*10);
c="neymar";
push(c,1);
printf("%s",peek());
pop();
printf("%s",peek());
}
I give akash as priority 1 rahul as 2 and neymar again as 1 it should print akash and neymar for last two printf statements but it is printing akash rahul #dbush
In your push function, in the case where head is NULL, you set head to the new node, and then later try to put the node into the list again. You end up with the next field pointing to itself, so future inserts fall into an infinite loop.
When inserting into an empty list, you only need to set head to the new node and nothing else, so just return right away.
if(head==NULL){ //if the element is inserted in empty list
head=node1;
return;
}
Also, you should make a copy of the string that's passed in when you make a new node. Otherwise, you could end up with a pointer to memory that is no longer valid or multiple pointers pointing to the same buffer, with only the most recent update being viewable:
struct node* getnewnode(char *s,int p){
struct node* newnode = malloc(sizeof(struct node)); // don't cast return value of malloc
newnode->string = strdup(s); // create copy of given string
newnode->priority=p;
newnode->next=NULL;
return newnode;
}
I am trying to return the head of a linked list in the function Insert of the following program. However, it is failing with compilation error.
Can anyone please tell me what wrong I have done:
#include<stdio.h>
#include<stdlib.h>
struct ListNode
{
int data;
struct ListNode *next;
};
int ListLength(struct ListNode *head)
{
int count = 0;
struct ListNode *temp=head;
while(temp!=NULL)
{
count++;
temp=temp->next;
}
return count;
}
struct ListNode *Insert(struct ListNode *head, int value, int pos)
{
struct ListNode *temp,*curr;
curr=head;
int k=1;
temp=(struct ListNode *)malloc(sizeof(struct ListNode));
if(pos==1)
{
temp->data=value;
if(head==NULL)
{
temp->next=NULL;
head=temp;
}
else
{
temp->next=head;
head=temp;
}
}
else
{
while((curr!=NULL) && (k<pos))
{
k++;
curr=curr->next;
}
temp->data=value;
temp->next=curr->next;
curr->next=temp;
}
return head;
}
void printList(struct ListNode *head)
{
struct ListNode *temp;
temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
printf(" ");
temp=temp->next;
}
}
int main
{
struct ListNode *head=NULL;
//head = NULL;
head=Insert(head,10,1);
//Insert(head,11,2);
printList(head);
return 0;
}
I am trying to return the head of the new linked list after the insertion. I don't know where I am going wrong. Thanks in advance for the help.
(i) Firstly, include int main(void) as mentioned in the comments.
(ii) Next, with your current code, when you try printing the list, you are going to be in an infinite loop and get a stack overflow.
To avoid this, increment the temp to point to the next node after each print.
So your print function should look like:
void printList(struct ListNode *head)
{
struct ListNode *temp;
temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
printf(" ");
temp=temp->next; // this line is required
}
}
(iii) And in your main function, call the printList with an argument, that is the head of the node like this:
printList(head);
(iv) And don't forget to return the count in your finding the length of the list function. Add the return statement at the end of your ListLength function:
return count;
(v) Your current code does not handle a case when head is NULL, and user wants to insert at a position greater than 1. Or more generally, when a user wants to insert at a position that is greater than the current list's length.
While you trust such an input would not be given, always handle such exceptions (you would probably get a SEGMENTATION FAULT here when trying to access memory of null nodes).
To handle this, you can add a check at the start of the Insert function like,
int lenList = ListLength(head);
if (lenList < pos)
{
printf("Please provide a position less than %d to insert", lenList);
return 0; // don't proceed with inserting node with NULL pointers
}
If head is declared global you don't have to return it. (Sorry, my answer is short)
I wrote a recursive function to reverse a linked list as follows:
struct node{
int val;
struct node *next;
};
//Global pointer to structure
struct node *start=NULL,*head=NULL;
//*Function to input node*
void create(int data){
struct node *temp;
temp=(struct node *)malloc(sizeof(struct node));
if(start == NULL){
temp->val=data;
temp->next=NULL;
start=temp;
head=temp;
}
else{
temp->val=data;
temp->next=NULL;
head->next=temp;
head=temp;
}
}
*Function to reverse the linked list*
void* rev(struct node *prev,struct node *cur){
if(cur!=NULL){
printf("Works");
rev(cur,cur->next);
cur->next=prev;
}
else{
start=prev;
}
}
And the related code in main is:
main(){
struct node *temp;
temp=start;
/*Code to insert values*/
rev(NULL,temp);
}
Now the code takes input and prints it perfectly, but after I call rev() function the same traversal function prints nothing.
I did run the code on debugger line by line n it gave me the following output:
rev (prev=0x0, cur=0x0)
Also since cur is somehow NULL, the if part of rev() never gets executed and only the else executes once.
When I take input in my create() function I do update start to the first element of the linked list and even in main a print statement proves it is so.
But then why the function rev() always receives input parameters as NULL?
Please comment if any extra information is required.
Specific problems with your code: your main() function lacks sufficient code to test the reversal functionality (e.g. it doesn't create any nodes!); your create() routine really needs a head and tail pointer to work correctly, not the current head and start; your reversal function maintaines the head/start pointer but doesn't handle a tail pointer; you've redundant code in your if and else clauses that can be pulled out of the conditional; you declared rev() a void * instead of simply a void.
I've reworked your code below with addressing the above changes along with some style issues:
#include <stdlib.h>
#include <stdio.h>
struct node {
int value;
struct node *next;
};
// Global pointers to structure
struct node *head = NULL, *tail = NULL;
// Function to add node
void create(int data) {
struct node *temporary = malloc(sizeof(struct node));
temporary->value = data;
temporary->next = NULL;
if (head == NULL) {
head = temporary;
} else {
tail->next = temporary;
}
tail = temporary;
}
// Function to reverse the linked list
void reverse(struct node *previous, struct node *current) {
if (current != NULL) {
reverse(current, current->next);
current->next = previous;
} else {
head = previous;
}
if (previous != NULL) {
tail = previous;
}
}
void display(struct node *temporary) {
while (temporary != NULL) {
printf("%d ", temporary->value);
temporary = temporary->next;
}
printf("\n");
}
// And the related code in main is:
int main() {
/* Code to insert values */
for (int i = 1; i <= 10; i++) {
create(i);
}
display(head);
reverse(NULL, head);
display(head);
create(0);
display(head);
return 0;
}
OUTPUT
> ./a.out
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1 0
>
You should add a routine to free the nodes in the linked list.
I'm working on a singly linked list in C. This is what I've written so far.
C program
#include<stdio.h>
#include<stdlib.h>
struct Node{
int value;
struct Node *next;
};
struct Node* init()
{
struct Node* head=NULL;
head=malloc(sizeof(struct Node));
head->value=-1;
return head;
}
int length(struct Node* head)
{
struct Node* current=head;
int length=0;
while(current!=NULL)
{
length++;
current=current->next;
}
return length;
}
void print(struct Node* head)
{
int i=0;
int len=length(head);
for(i=0;i<len;i++)
{
printf("%d%d",i,head[i].value);
printf("\n");
}
}
struct Node* insert(int data,struct Node* head)
{
struct Node* current=NULL;
if(length(head) > 0)
{
int val=head->value;
if (val==-1)
{
head->value=data;
head->next=NULL;
}
else
{
current=malloc(sizeof(struct Node));
current->value=data;
current->next=head;
head=current;
}
}
else
{
printf("List is empty");
}
return head;
}
int main()
{
/* printf("Hello"); */
struct Node *head=init();
head=insert(20,head);
head=insert(30,head);
head=insert(40,head);
print(head);
printf("%d",length(head));
return 0;
}
The output values I get are:
Index Value
0 40
1 0
2 0
and for length is 3. I'm not able to grasp what I'm doing wrong here in pointer manipulation.
One obvious problem is not setting next to NULL on init - that would fail when checking length on the empty list
But your real problem is the print function
You can't use:
head[i].value
That notation is only valid for arrays, you need to use next to find each member
The Init function should set Next to NULL
struct Node* init()
{
struct Node* head=NULL;
head=malloc(sizeof(struct Node));
head->value=-1;
head->next=NULL;
return head;
}
otherwise the first call to length return an undefined result ( or GPF ).
Here:
for (i = 0; i < len; i++)
{
printf("%d%d", i, head[i].value);
printf("\n");
}
You need to advance from one node to another with head = head->next in the same manner as you do it in length(). head[i] won't do it.
It's unclear why your init() and insert() are so unnecessarily complicated and I don't even want to try to guess why. I want to suggest a better insert() and no init():
struct Node* insert(int data, struct Node* head)
{
struct Node* current;
current = malloc(sizeof(struct Node));
current->value = data;
current->next = head;
return current;
}
And then you do this:
int main(void)
{
struct Node *head = NULL;
head = insert(20, head);
head = insert(30, head);
head = insert(40, head);
print(head);
printf("%d", length(head));
return 0;
}
The notation head[i].value is only valid for arrays but not for linked lists. Arrays and linked lists are completely different, allocation of memory towards arrays is premeditated where as for linked lists it's dynamic. That is the reason why we use pointers for linked lists.
In init() you didn't assign null which causes the loop to run infinite times when you call length() for first time.
I am posting the modified code of print function:
void print(struct Node* head)
{
int i=0;
int len=0;
struct Node* current=head;
for(i=0;i<len;i++)
{
printf("%d %d",i,current->value);
print("\n");
current=current->next;
}
}