Find item in a Linked List in C - c

Following the tutorial, I wrote down this function to find the key in a linked list. However, it doesn't seem to work for me, curious about the reason. Here's part of the find function:
node_t *find_node(node_t *head, int number_to_find)
{
node_t *tmp = head;
while (tmp != NULL)
{
if(tmp->value == number_to_find)
{
return tmp;
tmp = tmp->next;
}
}
return NULL;
}
I embedded this function into my program. It successfully compiled but as it runs, the terminal did not show anything.
#define MAX_LIST 25
typedef struct node
{
int value;
struct node *next;
}node_t;
node_t *create_new_node(int value)
{
node_t *new = malloc(sizeof(node_t));
new->value = value;
new->next = NULL;
return new;
}
node_t *add_to_list(node_t *head, node_t *next_node)
{
next_node->next = head;
return next_node;
}
/*
TO FIND VALUE IN THE LINKED LIST
*/
node_t *find_link_list(node_t *head, int number_to_find)
{
node_t *tmp = head;
while (tmp != NULL)
{
if(tmp->value == number_to_find)
{
return tmp;
tmp = tmp->next;
}
}
return NULL;
}
bool print_linked_list(node_t *head)
{
if(head == NULL)
{
return false;
}
else
{
node_t *tmp = head;
while(tmp != NULL)
{
printf("%d ", tmp->value);
tmp = tmp->next;
}
return true;
}
}
int main()
{
node_t *head = NULL;
node_t *tmp;
for(int i = 0; i < MAX_LIST; i++)
{
tmp = create_new_node(i);
head = add_to_list(head, tmp);
}
tmp = find_link_list(head, 9);
printf("%d \n", tmp->value);
print_linked_list(head);
}
Anyone has a clue why this happen? It would be much appreciated : )

tmp = tmp->next;
should be outside of the if statement. Currently, you're saying, get to the next node in the list only if the value is equal to the target value. So instead you can have
while (tmp != NULL)
{
if(tmp->value == number_to_find)
{
return tmp;
}
tmp = tmp->next;
}

Related

Circular doubly linked list in C delete function

I have a circular doubly linked list.
The deletefront() function is not working: the output is wrong. What is the mistake?
The other functions are working. But I get a wrong output after displaying after calling deletefront function. The 100 value which should be deleted is still appearing. Please correct it.
I have included the C source code:
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *rlink;
struct node *llink;
} node;
node *head = NULL;
node *getnode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
void insertfront(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
head->llink = newnode;
newnode->rlink = head;
head = newnode;
}
}
void insertend(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
node *temp = head;
do {
temp = temp->rlink;
} while (temp != head->llink);
newnode->rlink = temp->rlink;
temp->rlink = newnode;
newnode->llink = temp;
}
}
int lenlist() {
node *temp;
int count = 0;
temp = head;
do {
temp = temp->rlink;
count++;
} while (temp != head);
return count;
}
void insertatpos(int ele,int pos) {
if (pos == 1) {
insertfront(ele);
} else
if (pos == (lenlist() + 1)) {
insertend(ele);
} else
if (pos > 1 && pos <= (lenlist() + 1)) {
node *prev, *curr;
node *newnode = getnode(ele);
int count = 1;
curr = head;//curr points to 1st node
do {
prev = curr;
count++;
curr = curr->rlink;
if (count == pos) {
prev->rlink = newnode;
newnode->llink = prev;
newnode->rlink = curr;
curr->llink = newnode;
}
} while (curr != head);
} else {
printf("invalid position");
}
}
void delfront() {
if (head == NULL)
printf("empty list");
node *aux;
node *lastnode, *secondnode;
aux = head;
lastnode = head->llink;
secondnode = head->rlink;
secondnode->llink = lastnode;
lastnode->rlink = secondnode;
free(aux);
head = secondnode;
}
void display() {
node *aux = head;
do {
printf("%d->", aux->data);
aux = aux->rlink;
} while (aux != head);
printf("\n");
}
int main() {
insertfront(100);
insertend(20);
printf("\n%d\n", lenlist());
insertatpos(45, 2);
display();
delfront();
display();
}
The problem is not in the deletefront() function, instead, you have missed updating a few links in the insertfront() and insertend() functions.
I have updated the code here and also added the comment where I made the changes. Try to visualise it using an example.
However, I suggest that you solve such issues using a debugger or go through the code with a sample test case. It will improve you debugging as well as coding skills!
Your code have a lot of mistakes.
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
/*i changed the names of your pointers here*/
typedef struct node {
int data;
struct node *prev, *next;
} node;
/*
node *head = NULL;
This will be removed.
Avoid using globals as much as you can.
*/
/*
This function is unecessary.
node *createNode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
*/
char insertFront(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
}
*head=newNode;
return 1;
}
char insertEnd(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
*head=newNode;
}
return 1;
}
/*You could simple create a struct list that would have as members
the head of your list and its height to avoid calculating it each time
you want it but anyway. I will fix that.
int lenList(node *head) {
if (*head==NULL) return 0;
node *temp=head;
int count = 0;
do {
temp = temp->next;
count++;
} while (temp != head);
return count;
}
*/
char insertNatP(node **head, int ele, int pos) {
If (pos<1 || pos>lenList(head)){
printf("Invalid Position\n");
return 0;
}
int i;
for(i=0; i<pos-1; head=&head->next, i++);
node *newNode=malloc(sizeof(node));
If (newNode==NULL){
printf("Memory could not be allocated\n");
return 0;
}
newNode->data=ele;
If (*head!=NULL){
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode
newNode->next=*head;
} else {
newNode->prev=newNode;
newNode->next=newNode;
}
*head=newNode;
return 1;
}
char delFront(node **head) {
if (*head == NULL) return 0;
node garbage=*head;
*head=(*head)->next;
if (*head==garbage) *head=NULL; else{
(*head)->prev=garbage->prev;
garbage->prev->next=*head;
}
free(garbage);
return 1;
}
void printList(node *list) {
if (list==NULL) return;
node *sentinel=list->prev;
while (list!=sentinel) {
printf("%d->", list->data);
list=list->next;
}
printf("%d\n", list->data);
}
int main() {
node *l1=NULL;
insertFront(&l1, 100);
insertEnd(&l1, 20);
printf("\n%d\n", lenList(l1));
insertNatP(&l1, 45, 2);
printList(l1);
delFront(&l1);
printList(l1);
}
Try this

Why Does this particular code throw an exeption?

Critical error detected c0000374
#pragma once
typedef struct node
{
int value;
node* next;
node* before;
} node;
void print_nodes(node* list) {
node *current = (node*)malloc(sizeof(node));
//current->value = 0;
current->next = list;
while (current->next != nullptr) {
printf("%i\n", current->next->value); <-THROW an Exception in the Fist loop
current->next = current->next->next;
}
free(current);
}
void add_node(node* list) {
}
inline void new_nodes(node* list, size_t anzahl) {
list[0].before = NULL;
for (int i = 0; i <= anzahl; i++) {
list[i].value = i + 1;
list[i].next = &list[i + 1];
list[i + 1].next = &list[i - 1];
}
list[anzahl].next = NULL;
}
The printf statement Throws an Exception ... but only sometimes.
My cpp calls the function new_nodes with the size_t = 10 so it cant be tooooo big.
Additional Info one time even the heap "broke".
Thanks for your Help.
this:
void print_nodes(node* list)
{
node *current = (node*)malloc(sizeof(node));
//current->value = 0;
current->next = list;
while (current->next != nullptr)
{
printf("%i\n", current->next->value); <-THROW an Exception in the Fist loop
current->next = current->next->next;
}
free(current);
}
Needs to be heavily modified: Suggest:
modified (after clarification by the OP) to use a 'headless' linked list
void print_nodes(node* list)
{
node * current = list;
while (current)
{
printf("%i\n", current->value);
current = current->next;
}
}

linked list c programming error by inserting new element

I am trying to insert an element but it get the error "Process finished with exit code 11"
struct node {
int key;
struct node *next;
};
struct node* init(){
struct node *head =NULL;
return head;
}
void create(struct node * head,int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while(tmp!= NULL && tmp->key < num){
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp== NULL)
head=tmp;
}
int main() {
int num;
struct node* head;
head=init()
printf("Enter data:");
scanf("%d",&num);
create(head,num);
}
i am trying to insert an element into a linked list and the element should be sorted and entered at the same time.can someone tell me that the error is ? i cannot seem to find out the error.
It's not clear what your function create()
void create(struct node * head, int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while (tmp != NULL && tmp->key < num) {
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp == NULL)
head = tmp;
}
is supposed to do. You effectively pass it a NULL pointer and return void, so everything it does is meaningless to the outside world.
Thetm starting point for every no bs linked list implementation:
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct node_tag {
int value;
struct node_tag *next;
} node_t;
// write functions to encapsulate the data and provide a stable interface:
node_t* node_create_value(int value)
{
node_t *new_node = calloc(1, sizeof *new_node);
if(new_node) new_node->value = value;
return new_node;
}
node_t* node_advance(node_t const *node) { return node->next; }
typedef struct list_tag { // a list usually consists of
node_t *head; // a pointer to the first and
node_t *tail; // a pointer to the last element
// size_t size; // one might want to add that.
} list_t;
list_t list_create(void)
{
list_t list = { NULL, NULL };
return list;
}
// make code based on these functions "speak" for itself:
node_t* list_begin(list_t const *list) { return list->head; }
node_t* list_end (list_t const *list) { return list->tail; }
bool list_is_empty(list_t const *list) { return !list_begin(list); }
// common operations for lists:
node_t* list_push_front(list_t *list, int value)
{
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = list->head;
return list->head = new_node;
}
node_t* list_push_back(list_t *list, int value)
{
// push_back on an empty list is push_front:
if (list_is_empty(list))
return list->tail = list_push_front(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
list->tail->next = new_node;
return list->tail = new_node;
}
node_t* list_insert_after(list_t *list, node_t *node, int value)
{
if (list_end(list) == node)
return list_push_back(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = node->next;
return node->next = new_node;
}
node_t* list_insert_sorted(list_t *list, int value)
{
// first handle the special cases that don't require iterating the whole list:
if (list_is_empty(list) || value < list_begin(list)->value)
return list_push_front(list, value);
if (value > list_end(list)->value)
return list_push_back(list, value);
// the general (worst) case:
for (node_t *current_node = list_begin(list); node_advance(current_node); current_node = node_advance(current_node))
if (value < node_advance(current_node)->value)
return list_insert_after(list, current_node, value);
return NULL; // should never happen
}
void list_print(list_t const *list)
{
for (node_t *current_node = list_begin(list); current_node; current_node = node_advance(current_node))
printf("%d\n", current_node->value);
}
void list_free(list_t *list)
{
for(node_t *current_node = list_begin(list), *next_node; current_node; current_node = next_node) {
next_node = current_node->next;
free(current_node);
}
}
// user code should not be required to know anything about the inner workings
// of our list:
int main(void)
{
list_t list = list_create();
for (int i = 1; i < 10; i += 2) {
if (!list_push_back(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
putchar('\n');
for (int i = 0; i < 11; i += 2) {
if (!list_insert_sorted(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
list_free(&list);
}
Output:
1
3
5
7
9
0
1
2
3
4
5
6
7
8
9
10

searching in binary tree in c when data gets larger

void *node_search(node_t *root, void *key) {
node_t** curr = &root;
int outcome;
static int comparison = 0;
while (*curr){
outcome = strcmp(key, (*curr)->name);
comparison++;
printf("%d", outcome);
if(outcome<0) {
curr = &(*curr)->left;
} else {
if(outcome == 0){
printf("%s---> ", key);
printf("%d number of comparisions\n", comparison);
comparison=0;
return (*curr)->movie;
}
curr = &(*curr)->right;
}
}
printf("%s---> ", key);
printf("%d number of comparisions but NOT FOUND\n", comparison);
comparison = 0;
return (*curr);
}
when the number of data is small it finds what i need to find pefectly
but when the same data set but larger in size gets used it prints out not found
why is this??
here's my insertion to tree
node_t *insert_node(node_t *root, node_t *new)
{
node_t** curr = &root;
while (*curr)
{
if (strcmp(new->name, (*curr)->name) < 0) {
curr = &(*curr)->left;
} else {
curr = &(*curr)->right;
}
}
*curr = new;
return root;
}
In insert_node, you should be passing in root as a node_t ** instead of a node_t *. Otherwise, if you have an empty tree the root node won't get created. Also, be sure to initialize root to NULL in your main.
Since you'll be passing in the address of your root pointer, insert_node doesn't need to return anything.
void insert_node(node_t **root, node_t *new)
{
node_t** curr = root;
while (*curr)
{
if (strcmp(new->name, (*curr)->name) < 0) {
curr = &(*curr)->left;
} else {
curr = &(*curr)->right;
}
}
*curr = new;
}
int main()
{
node_t *root = NULL;
...
insert_node(&root, node1);
insert_node(&root, node2);
...
}

Delete elements from singly linked list

i would like to delete some elements from list specified by value in function. My function doesn't work if function's 'val' is equal to my first element in list. Otherwise it works well. Any ideas?
struct elem {
int val;
struct elem *next;
};
void del(struct elem *list, int val) {
struct elem* tmp = list;
struct elem* prev = NULL;
while (tmp != NULL) {
if (tmp->val == val) {
if (prev == NULL) {
tmp = tmp->next;
free(list);
list = tmp;
} else {
prev->next = tmp->next;
free(tmp);
tmp = prev->next;
}
} else {
prev = tmp;
tmp = tmp->next;
}
}
}
Your calling function cannot know that list has been updated. It will even go on referring to the same list, which has been deleted. Which is not good.
One solution is to pass the list as struct elem **list:
void del(struct elem **list, int val) {
struct elem* tmp = *list;
struct elem* prev = NULL;
while (tmp != NULL) {
if (tmp->val == val) {
if (prev == NULL) {
tmp = tmp->next;
free(*list);
*list = tmp;
} else {
prev->next = tmp->next;
free(tmp);
tmp = prev->next;
}
} else {
prev = tmp;
tmp = tmp->next;
}
}
}
Edit: There are other solutions. You could return the new list pointer:
struct elem *del(struct elem *list, int val) { ... }
And you call it like this:
list = del(list, 12);
This solution has the disadvantage that list is somewhat redundant in the call and that it is legal to omit the return value, thus actually not updating the list.
A solution I like is to define a control struct for your list. At the moment, that just contains the head pointer:
struct list {
struct elem *head;
};
Your functions that operate on the list then take a pointer to this structure as argument:
void del(struct list *list, int val) {
struct elem* tmp = list->head;
struct elem* prev = NULL;
while (tmp != NULL) {
if (tmp->val == val) {
if (prev == NULL) {
tmp = tmp->next;
free(list->head);
list->head = tmp;
} else {
prev->next = tmp->next;
free(tmp);
tmp = prev->next;
}
} else {
prev = tmp;
tmp = tmp->next;
}
}
}
The struct list can have additional fields, for example the tail pointer for quick appending to the end. You could also keep track of the list length.

Resources