I'm quite new to C, and I'm looking for feedback on this (doubly) linked list code.
Once I get to the add and remove methods, I feel like the code goes downhill. I'm looking for any potential errors I haven't spotted, and improvements that could be made for efficiency/tidiness.
struct node {
int data;
struct node *next;
struct node *previous;
};
struct listset {
struct node *head;
struct node *tail;
int current_elements;
};
struct listset * new_listset(){
struct listset *new_list = malloc(sizeof(struct listset));
new_list ->head = NULL;
new_list ->tail = NULL;
return new_list;
};
struct node *listset_lookup(struct listset *this, int item){
struct node *curr_elem = this->head;
if(!curr_elem) return NULL;
while(item != curr_elem->data){
if(curr_elem->next==NULL)return NULL;
curr_elem = curr_elem->next;
}
return curr_elem;
}
void listset_add(struct listset *this, int item){
struct node *new_node = malloc(sizeof(struct node));
new_node -> data = item;
new_node ->next = NULL;
if(!this->head) {
new_node->previous = NULL;
this->head = this->tail = new_node;
}
else{
this->tail->next = new_node;
}
this->current_elements++;
}
void listset_remove(struct listset *this, int item){
struct node *elem_remove = listset_lookup(this, item);
if(!elem_remove) return;
if(elem_remove->next && elem_remove->previous) elem_remove->previous->next = elem_remove->next;
else if (elem_remove->previous && !elem_remove->previous){
elem_remove->previous->next=NULL;
this->tail = elem_remove->previous;
}
else{
this->tail = NULL;
this->head = NULL;
}
free(elem_remove);
}
else
block:this->tail = new_node
\$\endgroup\$