循环双链表(C语言,使用头节点)

注:
空链表状态头节点的前驱、后继节点都指向自己

代码部分

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct node {
    int data;
    struct node *prev;
    struct node *next;
}NODE, *PNODE;

void init(PNODE *);
bool is_empty(PNODE);
void traverse(PNODE);
bool head_add(PNODE, int);
bool rear_add(PNODE, int);
int len(PNODE);
bool insert(PNODE, int, int);
bool delete(PNODE, int, int *);
bool clear(PNODE);

bool clear(PNODE head)
{
    PNODE p, q;
    printf("clear...");

    if (NULL == head) {
        printf(" 未初始化无需操作\n");
        return false;
    }

    p = head->next;
    while (p != head) {
        q = p->next;
        p = q->next;
        // 有头节点的循环链表需要操作这一步
        head->next = p;
        free(q);
    }

    printf("成功\n");
    return true;
}

bool delete(PNODE head, int pos, int *pVal)
{
    PNODE p;
    int i = 0;
    printf("delete pos %d", pos);

    if (NULL == head) {
        printf(" 失败,链表未初始化\n");
        return false;
    }

    if (pos < 1 || pos > len(head)) {
        printf(" 失败, 无效的位置\n");
        return false;
    }

    p = head;
    while (i < pos) {
        p = p->next;
        ++i;
    }

    *pVal = p->data;
    p->prev->next = p->next;
    p->next->prev = p->prev;
    free(p);

    printf(" 成功,值为%d\n", *pVal);
    return true;
}

bool insert(PNODE head, int pos, int val)
{
    PNODE p, tmp;
    int i = 0;
    printf("insert pos %d, val %d", pos, val);

    if (NULL == head) {
        printf(" 失败,链表未初始化!\n");
        return false;
    }

    if (pos < 1 || pos > len(head)+1) {
        printf(" 失败, 插入位置无效\n");
        return false;
    }

    // 找插入位置的前驱节点,如果空链表,则p指向的是头节点
    p = head;
    while (i < pos-1) {
        p = p->next;
        ++i;
    }

    tmp = (PNODE)malloc(sizeof(NODE));
    if (! tmp) {
        printf("内存分配失败!\n");
        return false;
    }

    tmp->data = val;
    tmp->prev = p;
    tmp->next = p->next;
    p->next->prev = tmp;
    p->next = tmp;

    printf(" 成功\n");
    return true;
}

int len(PNODE head)
{
    PNODE p;
    int i = 0;

    if (NULL == head) {
        printf(" 失败,链表未初始化!\n");
        return false;
    }

    p = head->next;
    while (p != head) {
        ++i;
        p = p->next;
    }

    return i;
}

bool rear_add(PNODE head, int val)
{
    printf("rear_add %d", val);
    PNODE tmp;

    if (NULL == head) {
        printf(" 失败,链表未初始化!\n");
        return false;
    }

    tmp = (PNODE)malloc(sizeof(NODE));
    if (! tmp) {
        printf(" 内存分配失败!\n");
        return false;
    }
    tmp->data = val;
    tmp->prev = head->prev;
    tmp->next = head;
    head->prev->next = tmp;
    head->prev = tmp;

    printf(" 成功\n");
    return true;
}

bool head_add(PNODE head, int val)
{
    printf("head_add %d", val);
    PNODE tmp;

    if (NULL == head) {
        printf(" 失败,链表未初始化!\n");
        return false;
    }

    tmp = (PNODE)malloc(sizeof(NODE));
    if (! tmp) {
        printf(" 内存分配失败!\n");
        return false;
    }
    tmp->data = val;
    tmp->prev = head;
    tmp->next = head->next;
    head->next->prev = tmp;
    head->next = tmp;

    printf(" 成功\n");
    return true;
}

void traverse(PNODE head)
{
    PNODE p;
    int i = 1;
    if (is_empty(head)) {
        printf("链表为空\n");
        return;
    }

    p = head->next;
    while (p != head) {
        printf("node %d: prev(%p) data(%d) next(%p)\n", i, p->prev,  p->data, p->next);
        p = p->next;
        ++i;
    }
}

bool is_empty(PNODE head)
{
    if (head == head->next)
        return true;

    return false;
}

void init(PNODE *pHead)
{
    PNODE tmp, head;
    int val;

    head = (PNODE)malloc(sizeof(NODE));
    head->prev = head->next = head;

    printf("请输入所有节点的值:\n");
    while(1) {
        scanf("%d", &val);
        if (val == 0) {
            printf("初始化完毕!\n");
            break;
        }

        tmp = (PNODE)malloc(sizeof(NODE));
        if (! tmp) {
            printf("内存分配失败!\n");
            return;
        }
        tmp->data = val;
        tmp->prev = head->prev;
        tmp->next = head;
        head->prev->next = tmp;
        head->prev = tmp;

    }

    *pHead = head;
}

int main(void)
{
    PNODE head = NULL;
    int val;

    head_add(head, 13);
    init(&head);
    traverse(head);
    head_add(head, 13);
    head_add(head, 12);
    head_add(head, 11);
    traverse(head);
    rear_add(head, 31);
    rear_add(head, 32);
    rear_add(head, 33);
    traverse(head);
    printf("链表长度: %d\n", len(head));
    insert(head, 0, 100);
    insert(head, 50, 100);
    insert(head, 1, 9);
    insert(head, 1, 8);
    insert(head, 3, 10);
    insert(head, 13, 34);
    traverse(head);
    printf("链表长度: %d\n", len(head));
    delete(head, 5, &val);
    traverse(head);
    printf("链表长度: %d\n", len(head));
    clear(head);
    printf("链表长度: %d\n", len(head));

    return 0;
}

output

[root@8be225462e66 c]# gcc  circular_doubly_linklist.c && ./a.out
head_add 13 失败,链表未初始化!
请输入所有节点的值:
21 22 23 0
初始化完毕!
node 1: prev(0x20e96b0) data(21) next(0x20e9b00)
node 2: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 3: prev(0x20e9b00) data(23) next(0x20e96b0)
head_add 13 成功
head_add 12 成功
head_add 11 成功
node 1: prev(0x20e96b0) data(11) next(0x20e9b60)
node 2: prev(0x20e9b80) data(12) next(0x20e9b40)
node 3: prev(0x20e9b60) data(13) next(0x20e9ae0)
node 4: prev(0x20e9b40) data(21) next(0x20e9b00)
node 5: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 6: prev(0x20e9b00) data(23) next(0x20e96b0)
rear_add 31 成功
rear_add 32 成功
rear_add 33 成功
node 1: prev(0x20e96b0) data(11) next(0x20e9b60)
node 2: prev(0x20e9b80) data(12) next(0x20e9b40)
node 3: prev(0x20e9b60) data(13) next(0x20e9ae0)
node 4: prev(0x20e9b40) data(21) next(0x20e9b00)
node 5: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 6: prev(0x20e9b00) data(23) next(0x20e9ba0)
node 7: prev(0x20e9b20) data(31) next(0x20e9bc0)
node 8: prev(0x20e9ba0) data(32) next(0x20e9be0)
node 9: prev(0x20e9bc0) data(33) next(0x20e96b0)
链表长度: 9
insert pos 0, val 100 失败, 插入位置无效
insert pos 50, val 100 失败, 插入位置无效
insert pos 1, val 9 成功
insert pos 1, val 8 成功
insert pos 3, val 10 成功
insert pos 13, val 34 成功
node 1: prev(0x20e96b0) data(8) next(0x20e9c00)
node 2: prev(0x20e9c20) data(9) next(0x20e9c40)
node 3: prev(0x20e9c00) data(10) next(0x20e9b80)
node 4: prev(0x20e9c40) data(11) next(0x20e9b60)
node 5: prev(0x20e9b80) data(12) next(0x20e9b40)
node 6: prev(0x20e9b60) data(13) next(0x20e9ae0)
node 7: prev(0x20e9b40) data(21) next(0x20e9b00)
node 8: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 9: prev(0x20e9b00) data(23) next(0x20e9ba0)
node 10: prev(0x20e9b20) data(31) next(0x20e9bc0)
node 11: prev(0x20e9ba0) data(32) next(0x20e9be0)
node 12: prev(0x20e9bc0) data(33) next(0x20e9c60)
node 13: prev(0x20e9be0) data(34) next(0x20e96b0)
链表长度: 13
delete pos 5 成功,值为12
node 1: prev(0x20e96b0) data(8) next(0x20e9c00)
node 2: prev(0x20e9c20) data(9) next(0x20e9c40)
node 3: prev(0x20e9c00) data(10) next(0x20e9b80)
node 4: prev(0x20e9c40) data(11) next(0x20e9b40)
node 5: prev(0x20e9b80) data(13) next(0x20e9ae0)
node 6: prev(0x20e9b40) data(21) next(0x20e9b00)
node 7: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 8: prev(0x20e9b00) data(23) next(0x20e9ba0)
node 9: prev(0x20e9b20) data(31) next(0x20e9bc0)
node 10: prev(0x20e9ba0) data(32) next(0x20e9be0)
node 11: prev(0x20e9bc0) data(33) next(0x20e9c60)
node 12: prev(0x20e9be0) data(34) next(0x20e96b0)
链表长度: 12
clear...成功
链表长度: 0
[root@8be225462e66 c]#
上一篇:算法刷题【2】反向链表


下一篇:剑指 Offer 18. 删除链表的节点