why searching function does not printing the position the element i searched? - c

//declaing headers
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<conio.h>
//creating nodes which having data and next ptr
struct Node{ //creating node
int data;
struct Node *next;
}node;
struct Node *head;
//function declarations
void start_insertion();
void end_insertion();
void display();
void start_deletion();
void end_deletion();
void searching();
//main function
int main(){
int ch;
do{
printf("\n1: Insertion in begining\n2: Insertion in End\n");
printf("3: Deletion from beigning\n4: Deletion from End\n");
printf("5: search\n 0: Exit\n");
display();
printf("\nEnter the choice : ");
scanf("%1d",&ch);
switch(ch){
case 1: start_insertion();
break;
case 2: end_insertion();
break;
case 3: start_deletion();
break;
case 4: end_deletion();
break;
case 5: searching();
break;
case 0: exit(0);
break;
default:printf("Entered wrong choice\n");
}
//system("cls");
}while(ch!=0);
return 0;
}
//insertion from starting
void start_insertion() {
struct Node *ptr,*temp;
ptr=(struct Node*)malloc(sizeof(struct Node));
if(ptr==NULL){
printf("overflow");
}
else{
int item;
printf("Enter the data: ");
scanf("%d",&item);
if(head==NULL){
ptr->data=item;
ptr->next=NULL;
head=ptr;
}
else {
temp=head;
ptr->data=item;
ptr->next=temp;
head=ptr;
}
}
}
//insertion in end
void end_insertion(){
struct Node *ptr,*temp;
ptr=(struct Node*)malloc(sizeof(struct Node));
if(ptr==NULL){
printf("Memory overflow");
}
else{
int item;
printf("\nEnter the data : ");
scanf("%d",&item);
if(head==NULL){
ptr->data=item;
ptr->next=NULL;
head=ptr;
}
else{
temp=head;
while(temp->next!=NULL){
temp=temp->next;
}
temp->next=ptr;
ptr->data=item;
ptr->next=NULL;
}
}
}
//deletion from start
void start_deletion(){
if(head==NULL){
printf("\n************List is Empty******************\n");
}
else{
struct Node *temp;
temp=head;
head=temp->next;
free(temp);
}
}
//deletion from end
void end_deletion(){
struct Node *temp,*temp1;
temp=head;
if(temp==NULL){
printf("\n**********List is empty************\n");
}
else{
if(head->next==NULL){
head=NULL;
free(head);
}
else{
while(temp->next!=NULL){
temp1=temp;
temp=temp->next;
}
temp1->next=NULL;
free(temp);
}
}
}
//traverse the entire linkedlist display
void display(){
struct Node *temp;
temp=head;
if(temp==NULL){
printf("\nNo Node existed\n");
}
else{
while(temp!=NULL){
printf("-> %d ->",temp->data);
temp=temp->next;
}
}
}
//its not printing the position
//searching function to print the position of the element you searched.
void searching(){
if(head==NULL){
printf("List is Empty cant search");
}
else{
struct Node *temp;
temp=head;
int flag=0,p[flag],item,i=0;
printf("Enter the data you want to search: ");
scanf("%d",&item);
while(temp!=NULL){
if(temp->data==item){
p[flag]=i;
flag++;
}
i+=1;
temp=temp->next;
}
if(flag==0){ //if flag=0 the their is no data in the list
printf("no data element exist");
}
else{
for(int j=0;j<=flag;j++){
printf("*******found********%d",p[j]+1);
}
}
}
}

void searching(){
if(head==NULL){
printf("List is Empty cant search");
}
else{
struct Node *temp;
temp=head;
int flag=0,item,i=0;
int p[100];
printf("Enter the data you want to search: ");
scanf("%d",&item);
while(temp!=NULL){
if(temp->data==item){
p[flag] = i;
flag++;
}
i+=1;
temp=temp->next;
}
if(flag==0){ //if flag=0 the their is no data in the list
printf("no data element exist");
}
else{
for(int j=0;j<flag;j++){
printf("*******found********%d",p[j]+1);
}
}
}
}
i edit your search function like above.
there are 2 problems:
first, you have to init the array with number of element, your code just init the array with flag elements while flag is 0 in this line.
int flag=0,p[flag],item,i=0;
second, because your trace array p start from 0, with flag elements so you only have to go from 0 -> flag-1, so i edit your for loop to print the result:
for(int j=0;j<flag;j++)
but i think you better do other way to search in linked list:
when you go through your linked list, if you meet the data, you can print the result and break the loop.
if you meet the end of the list (NULL pointer) but still no matched data found, so that means list is not includes the data you want.
it's no need to use additional variables flag or p array to trace result.
like this:
void searching() {
if (head == NULL) {
printf("List is Empty cant search");
} else {
struct Node *temp;
temp = head;
int item, i = 0;
printf("Enter the data you want to search: ");
scanf("%d", &item);
while (temp != NULL) {
if (temp->data == item) {
printf(" found %d at %d", item, i);
break;
}
i += 1;
temp = temp->next;
}
if (temp == NULL) printf("no data element exist");
}
}

i used online compiler i tested the code with
-> 65 ->-> 45 ->-> 89 ->-> 12 ->-> 8 ->-> 45 ->
Enter the choice : 5
Enter the data you want to search: 45
*******found********2*******found********6
add it work but just remove the = here
for(int j=0;j<flag;j++){ //j<flag not j<=flag
printf("*******found********%d",p[j]+1);
}

Related

when compiling this c program "non portable pointer conversion" warning is occuring so what is the reason behind this warning?

Defination :
Create a “Queue” user-defined structure with the following data members:
A Data
A link to the next node
Perform the following operations on Simple queue using user-defined functions:
Insert an element
Remove an element
Display
Isfull
Isempty
Create a file which stores all values of list.
Code :
#include<stdio.h>
#include<stdlib.h>
struct queue{
int data;
struct queue *next;
};
typedef struct queue node;
node *start=NULL,*rear=NULL;
int choice,i;
void insert();
void rem();
void display();
void isfull();
void isempty();
int main()
{
do
{
printf("\n\t 1.Insert\n\t 2.Remove\n\t 3.Display\n\t 4.isfull\n\t 5.isempty\n\t 6. Exit\n");
printf("\n Enter the Choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
insert();
break;
}
case 2:
{
rem();
break;
}
case 3:
{
display();
break;
}
case 4:
{
isfull();
break;
}
case 5:
{
isempty();
break;
}
case 6:
{
printf("\n\t EXIT POINT ");
break;
}
default:
{
printf ("\n\t Please Enter a Valid Choice(1/2/3/4/5/6)");
}
}
}
while(choice!=6);
return 0;
}
void insert()
{
node *temp;
temp = (node*)malloc(sizeof(node));
if(temp==NULL){
printf("\n\tQueue is Full\n");
}
else{
printf("Enter a value to be inserted:");
scanf("%d",&i);
temp->data = i;
temp->next=NULL;
if(start==NULL){
start = temp;
rear = temp;
}
else{
rear->next = temp;
rear = temp;
}
}
}
void rem()
{
node *temp;
if(start==NULL)
{
printf("\n\t Queue is Empty \n");
}
else
{
temp = start;
start = start->next;
printf("\n\t The deleted element is %d",temp->data);
free(temp);
}
}
void display()
{
node *temp;
if(start!=NULL)
{
temp = start;
while(temp->next!=NULL){
printf(" %d -> ",temp->data);
temp = temp->next;
}
printf(" %d",temp->data);
}
else
{
printf("\n The Queue is empty");
}
}
void isfull()
{
node *temp;
if (rear == temp - 1)
printf("Queue Overflow \n");
else
printf("Queue is not a Overflow\n");
}
void isempty()
{
node *temp;
if (start == - 1)
printf("Queue is empty \n");
else
printf("Queue is not a empty\n");
}
Looking out for some genuine solution please anyone who can answer this one.
This is because you are comparing an integer value to pointer value you can fix it by replacing -1 to NULL in isempty function it will work perfectly without any warning. There is no need of -1 you need it when you make start and rear variables inside the structure and there data type should be int.
hope it solves your problem

How do i make the two nodes doubly linked? after some debugging i found that in Create(...) -> in else, there is something wrong with (*H)->next=...;

I have a school project in which I have to make such a menu to handle a double linked list with float content, but i have massive trouble making it double-linked,and after some debugging it looks like its all (*H)->next...'s fault, (apart from mine),when i get a new_node, i make its 'next' part point to the head's adress, and head's 'prev' part point to the new_node's adress, and then making head's adress that of new_node, thus head, becoming actually the head.
#include <stdio.h>
#include <stdlib.h>
struct node {
char data;
struct node *next;
struct node *prev;
};
void Create(struct node **H,char val) {
struct node *new_node;
new_node=malloc(1*sizeof(struct node));
new_node->data=val;
if(new_node==NULL){
printf("RIP");
return;
}else{
new_node->next=*H;
new_node->prev=NULL;
(*H)->prev=new_node;
}
}
void Delete(struct node **H){
if(*H!=NULL){
struct node *temp = H;
temp->next=NULL;
printf("Deleting last element with value: %c\n",(*H)->data);
*H=(*H)->next;
free(temp);
}else{
printf("Empty list.\n");
}
}
void DisplayF(struct node *H){
int i = 0;
if(H==NULL){printf("Empty list\n");return;};
while(H!=NULL){
i++;
printf("Element #%d: %c\n",i, H->data);
H=H->next;
}
return;
}
void DisplayB(struct node *H){
int i = 0;
if(H==NULL){printf("Empty list\n");return;};
while(H!=NULL){
i++;
printf("Element #%d: %c\n",i, H->data);
H=H->prev;
}
return;
}
void Search(struct node *H,char val){
int i = 0;
while(H!=NULL){
i++;
if(H->data==val){
printf("Character '%c' was found in element %d\n",H->data,i);
return;
}
H=H->next;
}
printf("The value you are looking for does not exist.\n");
}
int main(){
struct node *head=NULL;
int inp;
char d;
do{
printf("1.Create\n2.Delete\n3.Display\n4.Search\n0.Exit\n");
scanf("%d",&inp);
switch (inp){
case 1:
printf("Enter the new node's character value: ");
scanf(" %c",&d);
Create(&head,d);
break;
case 2:
Delete(&head);
break;
case 3:
DisplayF(head);
break;
case 4:
DisplayB(head);
case 5:
printf("What character do you want to search for? ");
scanf(" %c",&d);
Search(head,d);
break;
case 0:
exit(0);
default:
printf("Enter a valid option from the menu below:\n");
break;
}
}while(inp!=0);
return 0;
}

Infinitely printing upon inserting before an existing element in linked list using C

If I insert an element before an existing element then the last two elements keeps printing infinitely. For example, if 10 20 30 are the existing elements and now if I want to insert 40 before 30(so that new list becomes 10 20 40 30) then 40 & 30 prints for an infinite number of times.
Thanks in advance.
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
}list;
list *start=NULL;
list *create(list *);
list *display(list *);
list *insert_before(list *);
int main()
{
int n;
printf("1: Create list\n");
printf("2: Display\n");
printf("3: Insert before an existing element\n);
for(;;)
{
printf("Enter your choice: ");
scanf("%d",&n);
switch(n)
{
case 1:start=create(start);
printf("\nList created successfully\n");
break;
case 2:start=display(start);
break;
case 3:start=insert_before(start);
break;
default:printf("Wrong input!!!");
exit(0);
}
}
}
list *create(list *start)
{
list *new_node, *ptr;
int num;
printf("Enter data: ");
scanf("%d",&num);
new_node=(list *)malloc(sizeof(list));
new_node->data=num;
if(start==NULL)
{
start=new_node;
new_node->next=NULL;
}
else
{
ptr=start;
while(ptr->next!=NULL)
{
ptr=ptr->next;
}
ptr->next=new_node;
new_node->next=NULL;
}
return start;
}
list *display(list *start)
{
list *ptr;
if(start==NULL)
{
printf("Empty list");
return start;
}
else
{
ptr=start;
while(ptr->next!=NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
return start;
}
list *insert_before(list *start)
{
int num,search,flag=0;
list *new_node, *ptr, *prev;
ptr=start;
printf("Enter the number before whom new data is to be inserted: ");
scanf("%d",&search);
while(ptr!=NULL)
{
prev=ptr;
if(ptr->data==search)
{
flag=1;
break;
}
ptr=ptr->next;
}
if(flag==1)
{
printf("\nEnter the new data to be entered");
scanf("%d",&num);
new_node=(list *)malloc(sizeof(list));
new_node->data=num;
prev->next=new_node;
new_node->next=ptr;
}
else
{
printf("Entered data cannot be found");
}
return start;
}
In the function insert_before you should be checked if the first item is the searched and then analyse the other case. Well i did some change and this is the modificated code for in the funtion:
list *insert_before(list *start){
int num,search,flag=0;
list *new_node, *ptr, *prev;
ptr=start;
printf("Enter the number before whom new data is to be inserted: ");
scanf("%d",&search);
if(start != NULL && start->data == search){
printf("Enter the new data to be entered: ");
scanf("%d",&num);
new_node=(list *)malloc(sizeof(list));
new_node->data=num;
new_node->next = start;
if(start->next == start)
start->next=new_node;
else{
ptr=start;
while(ptr->next!=start) ptr=ptr->next;
ptr->next=new_node;
}
start=new_node;
}
else{
while(!flag && ptr->next!=start){
prev=ptr;
if(ptr->next->data==search) flag=1;
ptr=ptr->next;
}
if(flag==1){
printf("Enter the new data to be entered: ");
scanf("%d",&num);
new_node=(list *)malloc(sizeof(list));
new_node->data=num;
prev->next=new_node;
new_node->next=ptr;
}
else
printf("Entered data cannot be found\n");
}
return start;
}

Delete string from linked list - C [duplicate]

This question already has an answer here:
Delete element of linked list by a certain criterion
(1 answer)
Closed 7 years ago.
So the problem I'm running into is deleting a user-inputted string from a linked list full of strings.
I'm still having a few issues in understanding just precisely how linked lists work, so any explanation as to what I am doing wrong would be greatly appreciated!
Also, every other function seems to be working just fine, just having issues with the deleteItem function!
Edit - The problem I'm getting when I run the deleteItem function is just my terminal window crashing after getting hung up for a bit.
Here's my code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
char name[50];
struct node *next;
}*head;
void display();
void insert();
void count();
void deleteItem();
int main(){
int choice = 1;
char name[50];
struct node *first;
head = NULL;
while(1){
printf("Menu Options\n");
printf("----------------\n");
printf("Please enter the number of the operation you'd like to do: \n");
printf("----------------\n");
printf("1. Insert\n");
printf("2. Display\n");
printf("3. Count\n");
printf("4. Delete\n");
printf("5. Exit\n");
printf("----------------\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
insert();
break;
case 2:
display();
break;
case 3:
count();
break;
case 4:
if(head=NULL)
printf("The list is blank");
else
deleteItem();
break;
case 5:
return 0;
default:
printf("invalid option");
}
}
system("pause");
return 0;
}
void insert(){
char nameToInsert[50];
struct node *temp;
temp = head;
if(head == NULL){
head = (struct node *)malloc(sizeof(struct node));
printf("What's the name you wish to insert?\n");
scanf("%s", &nameToInsert);
strcpy(head->name, nameToInsert);
head->next = NULL;
}
else{
while(temp->next !=NULL){
temp = temp->next;
}
temp->next = malloc(sizeof(struct node));
temp = temp->next;
printf("What's the name you wish to insert?\n");
scanf("%s", &nameToInsert);
strcpy(temp->name, nameToInsert);
temp->next = NULL;
}
}
void display(){
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp = head;
if(temp == NULL)
printf("The list is empty\n");
else{
printf("%s\n", temp->name);
while(temp->next != NULL){
temp = temp->next;
printf("%s\n", temp->name);
}
}
}
void count(){
struct node *temp;
int c =0;
temp = head;
while(temp!=NULL){
temp=temp->next;
c++;
}
printf("\n%d", c);
}
void deleteItem(){
char nameToDelete[50];
struct node *temp, *previous;
temp = head;
printf("What is the name you wish to delete?\n");
scanf("%s", nameToDelete);
while(temp->next != NULL){
temp = temp->next;
if(strcmp(nameToDelete, temp->name)==0){
previous = temp->next;
free(temp);
printf("%s was deleted successfully\n", nameToDelete);
}
}
}
I see the following issues:
You are not dealing with the case where the item to delete is at the head of the list.
The linked list is not restored to a good state after you free the node that contains the item.
You continue to iterate over the list even after you free the node that contains the item.
Here's a version that should work.
void deleteItem(){
char nameToDelete[50];
struct node *temp, *previous;
temp = head;
printf("What is the name you wish to delete?\n");
scanf("%s", nameToDelete);
// First, locate the node that contains the item.
for ( ; temp->next != NULL; temp = temp->next )
{
if(strcmp(nameToDelete, temp->name)==0)
{
break;
}
prev = temp;
}
// Now take care of deleting it.
if ( temp != NULL )
{
if ( temp == head )
{
head = temp->next;
}
else
{
prev->next = temp->next;
}
free(temp);
printf("%s was deleted successfully\n", nameToDelete);
}
}

Doubly Linked List Delete Function Error

I have written the following program but the problem is in Delete function.Whenever i am trying to delete the value at first position.The whole list is lost don't know why.If i try to display list after that then some garbage values are printed.The function is working perfectly for other positions.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
struct Student
{
int rno;
char name[20];
struct Student *next;
struct Student *prev;
};
void Display(struct Student *head)
{
assert(head!=NULL);
while(head!=NULL)
{
printf("%d\t%s\t",head->rno,head->name);
head=head->next;
}
}
struct Student *Insert(struct Student *head,const int position,const int rno,const char name[])
{
//printf("%s\n",__FUNCTION__);
struct Student *temp=(struct Student *)malloc(sizeof(struct Student));
struct Student *traverse=head;
int pos=position;
if(temp==NULL)
exit(-1);
temp->rno=rno;
strcpy(temp->name,name);
temp->next=NULL;
temp->prev=NULL;
// printf("%s\n",__FUNCTION__);
if(pos==1)
{
if(head==NULL)
{
head=temp;
}
else
{
temp->next=head;
head->prev=temp;
head=temp;
}
}
else
{
for(traverse=head,pos=position;traverse->next!=NULL&&pos-2!=0;traverse=traverse->next,pos--);
if(traverse==NULL || pos-2!=0)
{
printf("Invalid Position");
}
else
{
temp->next=traverse->next;
if(temp->next!=NULL)
temp->next->prev=temp;
temp->prev=traverse;
traverse->next=temp;
}
}
return head;
}
void DeleteAll(struct Student *head)
{
struct Student *temp=head;
while(temp->next!=NULL)
{
head=head->next;
free(temp);
temp=head;
}
free(temp);
}
void Delete(struct Student *head,int pos)
{
assert(head!=NULL);
struct Student *temp=head;
struct Student *traverse=head;
int position=pos;
if(position==1)
{
if(head->next!=NULL)
head=head->next;
head->prev=NULL;
temp->next=NULL;
free(temp);
}
else
{
while(traverse->next!=NULL&&position-1!=0)
{
traverse=traverse->next;
position--;
}
if(traverse==NULL || position-1!=0)
{
printf(".............Invalid position..........\n");
}
else
{
traverse->prev->next=traverse->next;
if(traverse->next)
traverse->next->prev=traverse->prev;
}
}
}
struct Student *CreateStudentList(const int no_of_students)
{
struct Student *head=NULL;
int i;
int rno;
char name[20];
for(i=0;i<no_of_students;i++)
{
printf("Enter roll number and name:");
scanf("%d%s",&rno,name);
head=Insert(head,i+1,rno,name);
}
return head;
}
void SimulateDoublyLinkedList()
{
struct Student *cdscpp2013=NULL;
int no_of_students;
int choice,rno,position;
char name[20];
while(choice!=5)
{
if(NULL==cdscpp2013)
{
printf("Enter number of students:");
scanf("%d",&no_of_students);
cdscpp2013=CreateStudentList(no_of_students);
}
else
{
printf("\nMenu Operations\nPress 1 for Insert\nPress 2 for Delete\nPress 3 for DeleteAll\nPress 4 for Display\nPress 5 for Exit\nEnter your choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Enter roll number and name to ininsert:");
scanf("%d%s",&rno,name);
printf("Enter position to insert:");
scanf("%d",&position);
cdscpp2013=Insert(cdscpp2013,position,rno,name);
break;
case 2:
printf("Enter position to delete:");
scanf("%d",&position);
Delete(cdscpp2013,position);
break;
case 3:
DeleteAll(cdscpp2013);
break;
case 4:
Display(cdscpp2013);
break;
case 5:
exit(1);
default:
printf("Invalid choice....Please Enter proper option.....");
}
}
}
}
int main()
{
SimulateDoublyLinkedList();
}
When you remove the first element of a list, the caller must update its reference to the list. So your Delete function must return the pointer to the first element of the resulting list.
In this kind of operation I also find useful to use pointers to pointers... this would simplify a lot your code.
try this for delete this should work -
as temp = head , the temp->next =null will make the whole list disappear
//just removed temp->next = null;
if(position==1) {
if(head->next!=NULL)
head=head->next;
head->prev=NULL;
free(temp);
}
Edited --
make delete function to return the head pointer and in the switch case use this
cdscpp2013=Delete(cdscpp2013,position);
instead of this
Delete(cdscpp2013,position);
then change the same for deleteall function - it should work :)

Resources