This code is a revised version of implementation which asked for an improvement. Original question is asked here: remove kth last element from singly-linked list
credits to: Toby, Andreas, Arkadiusz
What has changed:
- remove length from
xllist
struct - check if k is bigger than list length on the fly
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
typedef struct llnode
{
int value;
struct llnode *next;
} llnode;
typedef struct xllist
{
llnode * head;
llnode * tail;
} xllist;
bool create_node(xllist *list, int value)
{
llnode *node = malloc(sizeof *node);
if(!node)
{
return false;
}
node->value = value;
node->next = NULL;
if(!list->head)
{
list->head = node;
list->tail = node;
}
list->tail->next = node;
list->tail = node;
return true;
}
bool del_element_from_last(xllist *llist, int k)
{
//window with 2 pointers, length of k
//prev is the prev node to the window
llnode *prev;
llnode *last;
int len; //list length
if(llist->head)
{
last = llist->head;
prev = llist->head;
len = 1;
}
for(; last; last=last->next)
{
len++;
if(len > k+1)
prev = prev->next;
}
if(len < k) //len is smaller than k
{
return false;
}
if(len == k) //means del 1st element from the list
{
llist->head = llist->head->next;
}
//remove first node of the window
printf("deleted element:%d \n", prev->next->value);
prev->next = prev->next->next;
return true;
}
int main(void)
{
xllist llist = {NULL, NULL};
for(int i=0; i<100; i++)
{
if(!create_node(&llist, 100+i))
printf("create fail\n");
}
del_element_from_last(&llist, 15);
}
if(!list->head) { ... list->tail = node; } list->tail->next = node;
is questionable. After the firstcreate_node()
, shouldlist->tail->next
beNULL
? \$\endgroup\$(list->head ? list->tail->next : list->head) = node; list->tail = node;
. \$\endgroup\$