linked linked insertion function - c

Hello I am trying to create n number of lists. Each list is ordered linked list with a new instance. However, I also need a combined ordered linked list. Following is the code for the same. When it comes to each independent list I do not have any problems. However, when I am trying to insert every node into a globally declared linked list nodes, I am getting error(The input crashes with iteration of one node value.) Please have a look at the function and call highlighted to make things clear where I am exactly getting the error. Please make a note of global declarations. Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node{
int number;
struct node*next;
};
typedef struct node NODE;
NODE*createlist(int),*rel_strt,*new_entry[100];
NODE *start1=NULL,*rear1,*m1,*temp11;
NODE *insert_in_end(NODE*node1);
int i,num,n2,j,v,u;
int main() {
v=0;u=0;
printf("\n Enter the number of lists:");
scanf("%d",&n2);
for(j=0;j<n2;j++) {
printf("\n\n Enter the number of inputs to the list %d: \n ",j+1);
scanf("%d",&num);
new_entry[v]=createlist(num);
display(new_entry[v]);
v++;
}
printf("\nThe final List is:");
display(start1);
return 0;
}
NODE*insert_in_end(NODE *node11) { //problem in this function
int inf1=node11->number;
if(start1==NULL) {
start1=rear1=node11;
} else {
m1=start1;
if(m1->number>inf1) {
node11->next=m1;
start1=node11;
} else {
while(m1->next) {
if(m1->next->number < inf1)
m1=m1->next;
else
break;
}
temp11=m1->next;
m1->next=node11;
node11->next=temp11;
}
}
return start1;
}
void display(NODE*nodex) {
while(nodex!=NULL) {
printf("%d ->",nodex->number);
nodex=nodex->next;
}
}
NODE *createlist(int n1) {
NODE *node1,*start,*rear,*m,*temp1;
start=NULL;
for(i=0;i<n1;i++) {
node1=(NODE*) malloc(sizeof(NODE));
int inf;
printf("Enter node value %d:",i+1);
scanf("%d",&inf);
node1->number=inf;
node1->next=NULL;
insert_in_end(node1); // error during second fuction call check function definition
if(start==NULL) {
start=rear=node1;
} else {
m=start;
if(m->number>inf) {
node1->next=m;
start=node1;
} else {
while(m->next) {
if(m->next->number < inf)
m=m->next;
else
break;
}
temp1=m->next;
m->next=node1;
node1->next=temp1;
}
}
}
return start;
}

I suggest you define a function insertValue that would make it much more convenient for you. It will also make your code much more readable.
The function is below and you should see that it is very close to what you have.
// Returns the new start of the list after inserting value in increasing order
Node* insertValue(Node * list, int value)
{
Node *newNode, *m;
newNode = malloc(sizeof(NODE));
newNode->number = value; // added this
newNode->next = NULL; // added this
if(list == NULL)
return newNode;
if(value < list->number)
{
newNode->next = list;
return newNode;
}
m = list;
while(m->next)
{
if(value < m->next->number)
break;
m = m->next;
}
newNode->next = m->next;
m->next = newNode;
return list;
}
Your main function should now iterate over reading the numbers for the different short lists as below. As you see, variable names are more explicit than yours. They are limited to the minimum and there are no global variables.
int main(int argc, char* argv[])
{
NODE *globalList = NULL, *lists[100];
int nbrOfLists, listNo, nbrOfVal, valNo, val;
printf("\n Enter the number of lists:");
scanf("%d", &nbrOfLists);
if(nbrOfLists < 0 || nbrOfLists > 100)
return -1;
for(listNo = 0; listNo < nbrOfLists; listNo++)
{
printf("\n\n Enter the number of inputs to the list %d: \n ",listNo+1);
scanf("%d", &nbrOfVal);
lists[listNo] = NULL;
for(valNo = 0; valNo < nbrOfVal; valNo++)
{
printf("Enter node value %d:", valNo+1);
scanf("%d", &val);
// Here we insert the value in both lists
lists[listNo] = insertValue(lists[listNo], val);
globalList = insertValue(globalList, val);
}
display(lists[listNo]);
}
display(globalList);
return 0;
}
Your display function is correct. I provide it below, but it's the same as yours. The problem you encountered was because I forgot to initialize the fields of the node after I malloc it.
void display(NODE * list)
{
while(list)
{
printf("%d ->", list->number);
list = list->next;
}
}

Related

not being able to delete the first node in a linked list

#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct music_student *StudentPtr;
typedef struct music_student
{
int student_ID;
double hw_average;
int exam_grade;
int final_grade;
StudentPtr next;
} Music_student;
StudentPtr creatnew(int id,double hw,int exam);
StudentPtr Del(int id,StudentPtr list);
StudentPtr insert(int id,double hw,int exam,StudentPtr list);
void Proportion(float prop,StudentPtr list);
int main()
{
int req,id,exam;
double avg;
float prop;
StudentPtr list=NULL;
printf("Course Management Menu\nPlease choose among the following:\n");
printf("***\n");
printf("0: Quit.\n1: Insert student at first place on the list.\n2: Delete by ID.\n3: Find lucky student.\n4: Change homework exam ratio.\n5: Print List.\n");
while (N<15)
{
if(scanf("%d",&req)!=1)
{
printf("Input Error!");
return 1;
}
while(req>6||req<0)
{
printf("Invalid Selection\n");
if(scanf("%d",&req)!=1)
{
printf("Input Error!");
return 1;
}
}
switch (req)
{
case 1:
printf("insert student ID\n");
scanf("%d",&id);
while(id<10000||id>99999)
{
printf("Invalid student id try_again: value between 10,000 and 99,999\n");
scanf("%d",&id);
}
printf("insert hw grade\n");
scanf("%lf",&avg);
while(avg>100||avg<0)
{
printf("Invalid hw grade: value between 0 and 100\n");
scanf("%lf",&avg);
}
printf("insert exam grade\n");
scanf("%d",&exam);
while(exam>100||exam<0)
{
printf("Invalid exam grade: value between 0 and 100\n");
scanf("%d",&exam);
}
list=insert(id,avg,exam,list);
break;
case 2:
printf("Enter student to expunge from records:\n");
scanf("%d",&id);
Del(id,list);
break;
case 3:
Lucky(list);
break;
case 5:
lilPrint(list);
break;
case 0:
printf ("bye bye!");
return 0;
}
}
}
void lilPrint(StudentPtr list)
{
StudentPtr temp = list;
if(list==NULL)
return;
while (temp != NULL)
{
printf("Student Id: %d\nFinal Grade: %d\n",temp->student_ID,temp->final_grade);
temp = temp->next;
}
return;
}
StudentPtr Del(int id, StudentPtr list)
{
StudentPtr curr = list, prev = NULL;
if(curr->student_ID==id)
{
list=list->next;
free(curr);
curr=list;
}
while (curr != NULL)
{
if (curr->student_ID == id)
{
if (prev == NULL)
{
list = curr->next;
}
else
{
prev->next = curr->next;
}
free(curr);
return list;
}
prev = curr;
curr = curr->next;
}
return list;
}
StudentPtr insert(int id,double hw,int exam,StudentPtr list)
{
StudentPtr cell=creatnew(id,hw,exam);
if(cell==NULL)
{
free(list);
exit(1);
}
cell->next=list;
list=cell;
return list;
}
StudentPtr creatnew(int id,double hw,int exam)
{
StudentPtr cell=(StudentPtr)malloc(sizeof(Music_student));
if(cell == NULL)
{
printf("Allocation failed!");
return NULL;
}
cell->exam_grade=exam;
cell->student_ID=id;
cell->hw_average=hw;
cell->final_grade=(my_round(0.7*cell->exam_grade)+my_round(cell->hw_average*0.3));
cell->next=NULL;
return cell;
}
im trying to enter 4 or 5 nodes in it and the use lilprint to print some info about the linked list.
when i enter some nodes and then delete the firstnode(only delting the first one does this problem)
the program doesnt delete it fully so it only delets the student_id in that node and returns the rest. so when i print it it prints normally but the student_id is trash value .
This definition and using of N with the magic number 10 along with another magic number 15
#define N 10
//...
while (N<15)
//...
makes your code unclear.
Also this typedef declaration for a pointer
typedef struct music_student *StudentPtr;
is a bad idea.
For example if you will write const StudentPtr then it will be equivalent to struct music_student * const instead of const struct music_student * and the last type specification should be used in the function lilPrint because within the function the list is not changed.
void lilPrint( const struct music_student *list);
And by the way you forgot to place the function declaration before main.
In the function insert this statement
free(list);
does not make sense because it does not free all the allocated memory.
The function Del can invoke undefined when the list is empty due to using a null pointer accessing memory as for example in this statement
if(curr->student_ID==id)
Also it seems the list should store nodes with unique student_ID but the function Del is designed such a way that it deletes at most two nodes with the same student_ID due to the following while loop after the first if statement
if(curr->student_ID==id)
{
list=list->next;
free(curr);
curr=list;
}
while (curr != NULL)
{
if (curr->student_ID == id)
{
if (prev == NULL)
{
list = curr->next;
}
else
{
prev->next = curr->next;
}
free(curr);
return list;
}
//...
That is the function should delete either all nodes with the same student_ID or only one node with the given id.
And in main you forgot to assign the returned pointer to the pointer list
Del(id,list);
Instead you need to write
list = Del(id,list);

Link List Add elements in recursion language C

#include <stdio.h>
#include <stdlib.h>
typedef struct nodeNum
{
int num;
struct nodeNum *next;
} t_nodeNum;
// Functions declaration ----------------------------
int menu(); // display menu and return choice
t_nodeNum* addition(t_nodeNum *node, int n);
void print_list(t_nodeNum *node);
// ----------------------------------------------------
// Main program to test link list functions
int main()
{
int choice;
t_nodeNum *pnode = NULL;
t_nodeNum *head = NULL;
t_nodeNum *temp = NULL;
int numAdd = 0;
int len = 0;
int first = 1;
do
{
choice = menu();
switch (choice)
{
case 1:
{
printf("Please enter number : \n");
scanf("%d", &numAdd);
if (first)
{
pnode = (t_nodeNum *)malloc(sizeof(t_nodeNum));
if (pnode == NULL)
{
printf("\n Error in allocation\n");
exit(0);
}
pnode->num = numAdd;
pnode->next = NULL;
first = 0;
head = pnode;
}
pnode = addition(pnode, numAdd);
break;
}
case 4:
{
printf("\n Print List: ");
print_list(head);
break;
}
}
}
while (choice != 5);
return 0;
}
// function menu display menu and return choice
int menu()
{
int choice = 0;
do
{
printf("Please choose option to do: \n");
printf("1. addition\n");
printf("2. deletion\n");
printf("3. search\n");
printf("4. print\n");
printf("5. exit\n");
printf("\n option = ");
scanf("%d", &choice);
}
while (choice < 1 || choice > 5);
return choice;
}
// function addition to add item to linked list in recursion
t_nodeNum* addition(t_nodeNum *p, int numAdd)
{
int len = 0;
if (p == NULL)
{
p = (t_nodeNum *)malloc(sizeof(t_nodeNum));
if (p == NULL)
{
printf("\n Error in allocation\n");
exit(0);
}
p->num = numAdd;
p->next = NULL;
}
else
{
p = addition(p->next, numAdd);
}
return (p);
}
// function print_list to print linked list in recursion
void print_list(t_nodeNum *head)
{
printf("%d ", head->num);
if (head->next == NULL)
{
printf("\n");
return;
}
print_list(head->next);
}
There is problem with the addition function it does not work correctly to add new item to the linked list and I does not know what is wrong please help
After adding new items and do print list it display only the first item
In you main function -
pnode = addition(pnode, numAdd);
instead of pnode you need to pass pnode->next -
pnode = addition(pnode->next, numAdd);
Problem with first call is that pnode is not NULL so it just adds new element at head position replacing previous value and returns.
Therefore, new node is not being created.

Printing and Deleting queue in C

I'm trying to write a program that enqueue, dequeue, delete a chosen number and print the list. I have problems with the dequeue that i think is because of the menu part when you write a number, I've tried to fix it but the it removes the last number and not the first. The print shows the wrong number and when I tried to solve that problem I got the same problem as I had in dequeue. It's sometinhg wrong in delete but i cant figure it out.
I appreciate all the help i can get
edit:
I've changed it a lot and now everything else works except delete. I want delete to find the number i enter and delete it.
queue.c
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
struct node
{
int info;
struct node *ptr;
int next;
}*first, *last, *temp, *first1;
void enq(int data);
void deq();
void empty();
void display();
void create();
void delete_queue();
int count = 0;
void main()
{
int no, ch;
printf("\n 1 - Enqueue");
printf("\n 2 - Dequeue");
printf("\n 3 - Delete");
printf("\n 4 - Display");
printf("\n 5 - Exit");
create();
while (1)
{
printf("\n Enter choice : ");
scanf_s("%d", &ch);
switch (ch)
{
case 1:
printf("Enter data : ");
scanf_s("%d", &no);
enq(no);
break;
case 2:
deq();
break;
case 3:
printf("Enter data : ");
scanf_s("%d", &no);
delete_queue(no);
case 4:
display();
break;
case 5:
exit(0);
default:
printf("Wrong choice, Please enter correct choice ");
break;
}
}
}
void create()
{
first = last = NULL;
}
void enq(int data)
{
if (last == NULL)
{
last = (struct node *)malloc(1 * sizeof(struct node));
last->ptr = NULL;
last->info = data;
first = last;
}
else
{
temp = (struct node *)malloc(1 * sizeof(struct node));
last->ptr = temp;
temp->info = data;
temp->ptr = NULL;
last = temp;
}
count++;
}
void display()
{
first1 = first;
if ((first1 == NULL) && (last == NULL))
{
printf("Queue is empty");
return;
}
while (first1 != last)
{
printf("%d ", first1->info);
first1 = first1->ptr;
}
if (first1 == last)
printf("%d", first1->info);
}
void deq()
{
first1 = first;
if (first1 == NULL)
{
printf("\n Error: Trying to display elements from empty queue");
return;
}
else
if (first1->ptr != NULL)
{
first1 = first1->ptr;
printf("\n Dequed value : %d", first->info);
free(first);
first = first1;
}
else
{
printf("\n Dequed value : %d", first->info);
free(first);
first = NULL;
last = NULL;
}
count--;
}
void delete_queue()
{
int retval = -1;
if (first)
{
struct node *temp = first;
first = first->next;
if (!first) { last = first; }
retval = temp->next;
free(temp);
}
return retval;
}
void empty()
{
if ((first == NULL) && (last == NULL))
printf("\n Queue empty");
else
printf("Queue not empty");
}
Let me start with a few points of advice about design and style:
I do not recommend this:
typedef struct node {
int data;
struct node *next;
} node;
you are typedefing struct node to node. while it is not illegal, it is confusing. I would recommend
typedef struct _node {
int data;
struct _node *next;
} node;
Additionally, I do not recommend use of global variable with static storage class to keep track of your queue, instead you should create a queue in your main. Use global variables only when you have compelling reasons to do so.
Do remember that when you get rid of your global variable, you will need to rewrite your enqueue dequeue delete etc... functions to take in a queue_c * as parameter (because it wont have access to queueref any more)
Now for the reason that your code is not working properly and #Weather Vane alluded to:
you have a big problem in your delete function.
int delete(int data)
{
int result = 0;
node *curr_ptr; //pointer just created and not initialized
node *prev_ptr; //not initialized
node *temp_ptr; //not initialized
while (curr_ptr != NULL)
//curr_ptr was just created, where is it pointing? fatal error here
{
//inside this block lets imagine curr_ptr is pointing to a valid
//node in the global queue
if (curr_ptr->data == data)
{
result = 1;
if (curr_ptr->next != NULL)
{
temp_ptr = curr_ptr;
//both pointers point to the same thing
destroy_node(temp_ptr);
//now you just destroyed both nodes
prev_ptr->next = curr_ptr->next;
//the first time this block runs prev_ptr is uninitialized
//so prev_ptr->next will most likely seg fault
//this happens for example if you call this function
//for the first time with a long queue
}
else
{
temp_ptr = curr_ptr;
queueref.last = prev_ptr;
prev_ptr->next = NULL;
destroy_node(temp_ptr);
//again you are destroying both curr_ptr and temp_ptr
}
}
curr_ptr = curr_ptr->next;
prev_ptr = prev_ptr->next;
return result;
}
}
Perhaps it would be better if you think edge cases very carefully and rethink some of the logic from scratch. (test edge cases as you go)

Linked List of Ordered Linked Lists

I am trying to create an (ordered) linked list of (ordered) linked lists. The list-of-list links are carried by the first nodes of its member lists. I am trying to achieve this via the following code, but my program crashes right after I try to view the second node into the list of lists.
Here's a schematic of the data structure I am trying to construct:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node{
int number;
struct node*next;
struct node*lsnext;
};
typedef struct node Node;
Node* insertValue(Node * list, int value);
void display(Node*);
Node* insertArr(Node * list, int value);
int main()
{
Node *globalList = NULL, *lists,*start,*save;
int nbrOfLists, listNo, nbrOfVal, valNo, val;
printf("\n Enter the number of lists:");
scanf("%d", &nbrOfLists);
if(nbrOfLists < 0)
return -1;
for(listNo = 0; listNo < nbrOfLists; listNo++)
{
printf("\n\n Enter the number of inputs to the list %d: \n ",listNo+1);
scanf("%d", &nbrOfVal);
lists = NULL;
for(valNo = 0; valNo < nbrOfVal; valNo++)
{
printf("Enter node value %d:", valNo+1);
scanf("%d", &val);
// Here we insert the value in both lists
lists= insertValue(lists, val);
globalList = insertValue(globalList, val);
}
start=lists;
if(listNo==0){
save=start;
}
start=start->lsnext;
printf("\n The list %d is: ",listNo+1);
display(lists);
}
printf("\n\n The final list is: ");
display(globalList);
printf("The first list is");
display(save);
printf("The second list is");
display(save->lsnext); // CRASHES HERE
return 0;
}
Node* insertValue(Node * list, int value)
{
Node *newNode, *m;
newNode = malloc(sizeof(Node));
newNode->number=value;
if(list == NULL)
{
newNode->next=NULL;
return newNode;
}
if(value < list->number)
{
newNode->next = list;
return newNode;
}
m = list;
while(m->next)
{
if(value < m->next->number)
break;
m = m->next;
}
newNode->next = m->next;
m->next = newNode;
return list;
}
void display(Node*nodex){
while(nodex)
{
printf("%d ->",nodex->number);
nodex=nodex->next;
}
}
The problem is you never assign the lsnext node pointer. You will want to make sure you set this pointer equal to "lists" prior to resetting your start pointer. And you shouldn't need the following line of code:
start=start->lsnext;
That fixes your crashing issue that you mention, however the source code has other errors. Running your application through GDB will be invaluable in ensuring your pointer values are what you think they should be at each step, as well as a source code formatter to ensure readability, making it easier to tell which code belongs inside which blocks.

Sorting the numbers in a list / C

I need to sort the numbers that are entered in a list, but I am doing something wrong and it's sorting all of them except the first one.Any ideas how to fix this?
Here's my code:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node* List;
void Add (struct node* p, int d)
{
struct node* q;
q=malloc(sizeof(struct node));
if (q==NULL)
printf("Not enaugh memory!");
else
{
q->data=d;
if(List==NULL)
{
q->next=NULL;
List=q;
}
else
{
struct node *ptr=List;
while((ptr->next!=NULL)&&(ptr->next->data>d))
{
ptr=ptr->next;
}
q->next=ptr->next;
ptr->next=q;
}
}
}
int main()
{
int n,i,a;
printf("How much numbers are you going to enter? ");
scanf("%d",&n);
for (i=1; i<=n; i++)
{
printf("\nEnter a number: ");
scanf("%d",&a);
Add(List,a);
}
printf("\nThe sorted numbers are: ");
struct node *ptr=List;
while(ptr!=NULL)
{
printf("%d\t",ptr->data);
ptr=ptr->next;
}
printf("\n\n");
system("PAUSE");
return 0;
}
Thanks for the help in advance :-)
in add() function,
if(List==p)
this statement is true for all elements you insert to list since the call to add is,
Add(List,a);
so p=List. therefore the sorting code written in else part is not executed.
Also add statements to check for empty initial list.
You can use code similar to this,
void Add (int d)
{
struct node* q;
q=malloc(sizeof(struct node));
if (q==NULL)
printf("Not enaugh memory!");
else
{
q->data=d;
if(List==NULL)
{
q->next=NULL;
List=q;
}
else
{
struct node *ptr=List;
while((ptr->next!=NULL)&&(ptr->next->data>d))
{
ptr=ptr->next;
}
q->next=ptr->next;
ptr->next=q;
}
}
}
Since list is a global variable you dont need to pass it to Add() function. change the function call to
Add(a);
void Add (struct node* p, int d){
struct node* q;
q=malloc(sizeof(struct node));
if (q==NULL)
printf("Not enaugh memory!");
else{
q->data=d;
if(List==NULL || List->data < d){//modify this line
q->next= List;//and change NULL to List
List=q;
} else {
struct node *ptr=List;
while((ptr->next!=NULL)&&(ptr->next->data>d)){
ptr=ptr->next;
}
q->next=ptr->next;
ptr->next=q;
}
}
}
You always call Add with List as the first parameter, so it's alway true inside Add that (List==p). Consequently each new item is just inserted at the front of the list and there is no sorting at all.
EDIT 1
A good practice would be sending a list to the Add routine as a parameter. Or, if you want to keep it external, just don't give it to Add at all and test if(List == NULL)
void Add( int d)
{
// ... alloc 'q' and fill q->d here, then:
if(List == NULL)
{
q->next = NULL;
List = q;
}
else
{
struct node *b; // put q after b
for( b = List; b->next != NULL; b = b->next)
if( b->next->data >= d)
break;
q->next = b->next;
b->next = q;
}
}
EDIT 2
Example of transferring the list to a function by parameter
void Add( struct node **n, int d)
{
// ... alloc 'q' and fill q->d here, then:
while( *n != NULL && (*n)->data < d)
n = & (*n)->next;
q->next = *n;
*n = q;
}
int main()
{
// ...
Add( &List, a);
// ...
}

Resources