I'm looking for the most commonly used style for writing the delete_item()
function of a singly linked list, that find a matching item and deletes it. Is what I have the 'typical' or 'normal' solution? Are there more elegant ones?
What seems inelegant to me about my solution below, although I don't know a better way to express it, is that the code needs to check the first record individually (i.e. a special case), then as it goes through the iteration, it's not checking iter
, it's checking iter->next
, ahead of the iterator's present location, because in a singly linked list you can't go backwards.
So, is there a cleaner way to write the delete_item()
function?
#include <stdio.h>
#include <stdlib.h>
struct node {
int x;
struct node *next;
};
struct node *head;
struct node *create_item(int x);
void print_list();
void delete_item(int x);
int main(int argc, int argv) {
struct node *n;
int i;
// initialise a linked list with a few items
head = create_item(1);
n = head;
for (i = 2; i < 10; i++) {
n->next = create_item(i);
n = n->next;
}
// before
print_list();
// delete 7.
delete_item(7);
// after
print_list();
// lets delete all odd numbers for effect.
delete_item(1);
delete_item(3);
delete_item(5);
delete_item(9);
print_list();
}
struct node *create_item(int x) {
struct node *new;
new = (struct node *) malloc (sizeof(struct node));
new->x = x;
return new;
}
void print_list() {
struct node *iter;
iter = head;
while (iter != NULL) {
printf("num: %i\n", iter->x);
iter = iter->next;
}
}
//We're looking for the best way to right this.
//This is _my_ standard solution to the problem.
// (that is, to test the first element explicitly
// the use current->next != NULL to be one behind
// the search).
//I wondered what other people's is or if there
//is a convention?
void delete_item(int x) {
struct node *iter;
iter = head;
if (iter == NULL) {
printf("not found\n");
return;
}
if (iter->x == x) {
printf("found in first element: %i\n", x);
head = head->next;
return;
}
while (iter->next != NULL) {
if (iter->next->x == x) {
printf("deleting element: %i\n", x);
iter->next = iter->next->next;
return;
}
iter = iter->next;
}
printf("not found\n");
}
This is a complete example that can be compiled and tested. The output:
23:28: ~$ gcc -o ll linked_list.c
23:28: ~$ ./ll
num: 1
num: 2
num: 3
num: 4
num: 5
num: 6
num: 7
num: 8
num: 9
deleting element: 7
num: 1
num: 2
num: 3
num: 4
num: 5
num: 6
num: 8
num: 9
found in first element: 1
deleting element: 3
deleting element: 5
deleting element: 9
num: 2
num: 4
num: 6
num: 8