Delete from Beginning (Circular Linked List)

Removing the first node means updating tail->next to skip the old head. If the list had only one node, freeing it leaves the list empty (tail == NULL). Otherwise O(1) time: one free and one pointer move.

C program (return tail)

The sample builds 10 20 30 with insert_end (same as insert at end), prints, then calls delete_begin three times. Always assign tail = delete_begin(tail);.

  • head == tail: single-node ring—free(tail), return NULL.
  • Otherwise: tail->next = head->next, free(head), return tail (still last node).
#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node *next;
};

struct Node *insert_end(struct Node *tail, int data)
{
    struct Node *newNode = malloc(sizeof(struct Node));
    if (newNode == NULL)
        return tail;
    newNode->data = data;
    if (tail == NULL) {
        newNode->next = newNode;
        return newNode;
    }
    newNode->next = tail->next;
    tail->next = newNode;
    return newNode;
}

struct Node *delete_begin(struct Node *tail)
{
    if (tail == NULL)
        return NULL;
    struct Node *head = tail->next;
    if (head == tail) {
        free(tail);
        return NULL;
    }
    tail->next = head->next;
    free(head);
    return tail;
}

void print_list(struct Node *tail)
{
    if (tail == NULL) {
        printf("\n");
        return;
    }
    struct Node *head = tail->next;
    struct Node *cur = head;
    do {
        printf("%d ", cur->data);
        cur = cur->next;
    } while (cur != head);
    printf("\n");
}

int main(void)
{
    struct Node *tail = NULL;

    tail = insert_end(tail, 10);
    tail = insert_end(tail, 20);
    tail = insert_end(tail, 30);

    print_list(tail);   /* 10 20 30 */

    tail = delete_begin(tail);
    tail = delete_begin(tail);
    tail = delete_begin(tail);

    print_list(tail);   /* empty list: newline only */

    return 0;
}

Program output

10 20 30

First print_list shows the list. After three delete_begin calls, the second print_list prints only a newline (no numbers).

Ring after first delete

Before: 10 → 20 → 30 ─┘ (tail on 30, tail→next = 10)
After delete_begin:    20 → 30 ─┘ (tail still on 30, tail→next = 20)

Complexity summary

Operation Time Notes
delete_beginO(1)No scan of the ring.
print_listO(n)One full lap.

Compare Delete from Beginning (SLL) · Insert at Beginning (CLL)