Implementing a Doubly Circular Linked List in C

A doubly circular linked list supports core operations such as initialization, destruction, emptiness checking, traversal, insertion, deletion, search, and modification. Insertion and deletion can further be categorized into head/tail vraiants.

This implementation is organized across three files:

  • List.h: Declares the node structure and function prototypes.
  • List.c: Defines all declared functions.
  • Test.c: Contains test cases to validate functionality.

List.h – Header File

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

typedef int LTDataType;

typedef struct ListNode {
    struct ListNode* prev;
    struct ListNode* next;
    LTDataType data;
} LTNode;

LTNode* LTInit(void);
void LTDestory(LTNode* phead);
void LTPrint(LTNode* phead);
bool LTEmpty(LTNode* phead);

void LTPushBack(LTNode* phead, LTDataType x);
void LTPopBack(LTNode* phead);

void LTPushFront(LTNode* phead, LTDataType x);
void LTPopFront(LTNode* phead);

LTNode* LTFind(LTNode* phead, LTDataType x);

void LTInsert(LTNode* pos, LTDataType x);
void LTErase(LTNode* pos);

void LTUpdate(LTNode* pos, LTDataType x);

List.c – Implementation File

Helper: Node Allocation

LTNode* CreateNode(LTDataType value) {
    LTNode* node = (LTNode*)malloc(sizeof(LTNode));
    if (!node) {
        perror("Failed to allocate node");
        exit(EXIT_FAILURE);
    }
    node->data = value;
    node->prev = NULL;
    node->next = NULL;
    return node;
}

Initialization

LTNode* LTInit(void) {
    LTNode* sentinel = CreateNode(0);
    sentinel->next = sentinel;
    sentinel->prev = sentinel;
    return sentinel;
}

Destruction

void LTDestory(LTNode* phead) {
    assert(phead);
    LTNode* current = phead->next;
    while (current != phead) {
        LTNode* next = current->next;
        free(current);
        current = next;
    }
    free(phead);
}

Emptiness Check

bool LTEmpty(LTNode* phead) {
    assert(phead);
    return phead->next == phead;
}

Traversal and Print

void LTPrint(LTNode* phead) {
    assert(phead);
    printf("HEAD<=>");
    LTNode* cur = phead->next;
    while (cur != phead) {
        printf("%d<=>", cur->data);
        cur = cur->next;
    }
    printf("\n");
}

Head Insertion

void LTPushFront(LTNode* phead, LTDataType x) {
    assert(phead);
    LTNode* new_node = CreateNode(x);
    new_node->next = phead->next;
    new_node->prev = phead;
    phead->next->prev = new_node;
    phead->next = new_node;
}

Head Deletion

void LTPopFront(LTNode* phead) {
    assert(phead && !LTEmpty(phead));
    LTNode* target = phead->next;
    phead->next = target->next;
    target->next->prev = phead;
    free(target);
}

Tail Insertion

void LTPushBack(LTNode* phead, LTDataType x) {
    assert(phead);
    LTNode* new_node = CreateNode(x);
    new_node->prev = phead->prev;
    new_node->next = phead;
    phead->prev->next = new_node;
    phead->prev = new_node;
}

Tail Deletion

void LTPopBack(LTNode* phead) {
    assert(phead && !LTEmpty(phead));
    LTNode* target = phead->prev;
    phead->prev = target->prev;
    target->prev->next = phead;
    free(target);
}

Generic Insertion

void LTInsert(LTNode* position, LTDataType x) {
    assert(position);
    LTNode* new_node = CreateNode(x);
    LTNode* prior = position->prev;
    prior->next = new_node;
    new_node->prev = prior;
    new_node->next = position;
    position->prev = new_node;
}

Generic Deletion

void LTErase(LTNode* node) {
    assert(node);
    node->prev->next = node->next;
    node->next->prev = node->prev;
    free(node);
}

Search

LTNode* LTFind(LTNode* phead, LTDataType x) {
    assert(phead);
    LTNode* cur = phead->next;
    while (cur != phead) {
        if (cur->data == x)
            return cur;
        cur = cur->next;
    }
    return NULL;
}

Update

void LTUpdate(LTNode* node, LTDataType x) {
    assert(node);
    node->data = x;
}

Test.c – Validation Examples

The test file verifies all operations:

  • Insertions at head and tail
  • Deletinos from head and tail
  • Arbitrary insertions and deletions using position pointers
  • Search followed by update or removal

Tags: C doubly-linked-list circular-linked-list data-structures

Posted on Sat, 25 Jul 2026 17:02:53 +0000 by Basdub