C language to implement circular double linked list

In C language, implementing a circular doubly linked list requires defining a node structure. This structure contains three fields: data field, pointer to the previous node, and pointer to the next node. Define the node structure:

1) Define the node structure:

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

2) Create node: Create a new node and initialize its data and pointers.

Node* createNode(int data) {  
    Node* newNode = (Node*)malloc(sizeof(Node));  
    if (!newNode) {  
        printf("Memory error\n");  
        return NULL;  
    }  
    newNode->data = data;  
    newNode->next = NULL;  
    newNode->prev = NULL;  
    return newNode;  
}

3) Insert node: Add a new node at the end of the linked list. What needs to be considered is how to update the pointers of the new node and the previous node.

void insertNode(Node** head, int data) {  
    Node* newNode = createNode(data);  
    if (*head == NULL) { // 如果链表为空,新节点就是头节点  
        *head = newNode;  
        newNode->next = newNode;  
        newNode->prev = newNode;  
    } else { // 否则,将新节点添加到链表的末尾  
        Node* curr = *head;  
        while (curr->next != *head) { // 找到链表的末尾  
            curr = curr->next;  
        }  
        curr->next = newNode; // 更新末尾节点的next指针  
        newNode->prev = curr; // 更新新节点的prev指针  
        newNode->next = *head; // 新节点的next指针指向头节点  
        (*head)->prev = newNode; // 更新头节点的prev指针指向新节点  
    }  
}

 4) Delete node: Delete a specified node. What needs to be considered is how to update the pointers of the nodes before and after the deleted node, and how to handle the situation where the deleted node is the head node.

void deleteNode(Node** head, int data) {  
    Node* curr = *head;  
    if (*head == NULL) { // 如果链表为空,直接返回  
        return;  
    }  
    if (curr->data == data) { // 如果头节点就是要删除的节点  
        Node* temp = *head;  
        *head = (*head)->next; // 将头节点的next指针作为新的头节点  
        (*head)->prev = *head; // 新的头节点的prev指针指向自己  
        free(temp); // 释放旧的头节点内存空间  
        return;  
    }  
    while (curr->data != data) { // 找到要删除的节点  
        curr = curr->next;  
        if (curr == *head) { // 如果链表中没有找到要删除的节点,直接返回  
            return;  
        }  
    }  
    Node* temp = curr; // 保存要删除的节点的指针  
    curr = curr->next; // 将要删除节点的next指针作为当前节点  
    curr->prev = temp->prev; // 更新当前节点的prev指针指向要删除节点的prev指针所指向的节点  
    temp->prev->next = curr; // 更新要删除节点的prev指针所指向的节点的next指针指向当前节点  
    free(temp); // 释放要删除的节点的内存空间  
}

 5) Print the linked list: Traverse the linked list and print the data of each node.

void printList(Node* head) {  
    if (head == NULL) { // 如果链表为空,直接返回  
        printf("List is empty.\n");  
        return;  
    }  
    Node* curr = head; // 从头节点开始遍历链表  
    do { // 使用do-while循环,保证至少打印一次头节点的数据值,即使链表只有一个节点。注意使用前置++运算符。  
        printf("%d ", curr->data); // 打印当前节点的数据值,注意没有换行。使用后置++运算符。    } while ((curr = curr->next) != head); // 移动到下一个节点,如果当前节点是头节点,结束循环。注意使用前置++运算符。    printf("\n"); // 在打印完最后一个数据值后换行。 

Guess you like

Origin blog.csdn.net/MyLovelyJay/article/details/133189150