C语言:数据结构-双向链表

目录

一、结构体

二、创建双向头结点

三、创建双向子节点

四、判空

五、插入

1.头插

2.尾插

3.任意位置插入

六、按位置查找

七、头删

1.头删

2.按位置删除

八、打印

一、结构体

typedef struct dblist
{
    union {
        int len;
        int data;
    };
    struct dblist *front;
    struct dblist *next;
} dblist;

二、创建双向头结点

dblist *dblist_create()
{
    dblist *L = (dblist *)malloc(sizeof(dblist));
    if (L == NULL)
    {
        printf("内存申请失败\n");
        return NULL;
    }
    printf("内存申请成功\n");
    L->len = 0;
    L->front = NULL;
    L->next = NULL;
    return L;
}

三、创建双向子节点

dblist *dbnode_create(int data)
{
    dblist *p = (dblist *)malloc(sizeof(dblist));
    if (p == NULL)
    {
        printf("节点内存空间创建失败\n");
        return NULL;
    }
    p->data = data;
    p->front = NULL;
    p->next = NULL;
    return p;
}

四、判空

int empty_dblist(dblist *L)
{
    if (L == NULL)
    {
        printf("入参为空\n");
        return -1;
    }
    return L->next == NULL && L->front == NULL ? 1 : 0;
}

五、插入

1.头插

void insert_head_dblist(dblist *L, int data)
{
    if (L == NULL)
    {
        printf("入参为空\n");
        return;
    }
    dblist *p = dbnode_create(data);
    if (L->next == NULL)
    {
        p->next = L->next;
        p->front = L;
        L->next = p;
    }
    else
    {
        p->next = L->next;
        L->next->front = p;
        p->front = L;
        L->next = p;
    }
    L->len++;
}

2.尾插

void insert_tail_dblist(dblist *L, int data)
{
    if (L == NULL)
    {
        printf("入参为空\n");
        return;
    }
    dblist *p = L;
    while (p->next != NULL)
        p = p->next;
    dblist *newnode = dbnode_create(data);
    newnode->next = NULL;
    p->next = newnode;
    newnode->front = p;
    L->len++;
}

3.任意位置插入

void insert_index_dblist(dblist *L, int index, int data)
{
    if (L == NULL)
    {
        printf("入参为空\n");
        return;
    }
    else if (index < 1 || index > L->len + 1)
    {
        printf("位置不合理,请检查\n");
        return;
    }
    else if (index == L->len + 1)
    {
        insert_tail_dblist(L, data);
        return;
    }
    dblist *p = L;
    for (int i = 1; i < index; i++, p = p->next)
        ;
    dblist *newnode = dbnode_create(data);
    newnode->next = p->next;
    p->next->front = newnode;
    p->next = newnode;
    newnode->front = p;
    L->len++;
}

六、按位置查找

dblist *search_dblist(dblist *L, int index)
{
    if (L == NULL)
    {
        printf("入参为空\n");
        return NULL;
    }
    if (index < 1 || index > L->len)
    {
        printf("位置不合理,请检查\n");
        return NULL;
    }
    dblist *p = L->next;
    for (int i = 1; i < index; i++, p = p->next)
        ;
    return p;
}

七、头删

1.头删

void delete_head_dblist(dblist *L)
{
    if (L == NULL)
    {
        printf("入参为空\n");
        return;
    }
    if (empty_dblist(L))
    {
        printf("链表为空,无法删除\n");
        return;
    }
    dblist *p = L->next;
    if (p->next == NULL)
    {
        free(p);
        L->next = NULL;
    }
    else
    {
        L->next = p->next;
        p->next->front = p->front;
        free(p);
    }  
    L->len--;  
}

2.按位置删除

void delete_index_dblist(dblist *L, int index)
{
    if (L == NULL)
    {
        printf("入参为空\n");
        return;
    }
    if (index < 1 || index > L->len)
    {
        printf("位置不合理,请检查\n");
        return;
    }
    dblist *p = L->next;
    for (int i = 1; i < index; i++, p = p->next)
        ;
    if (p->next == NULL)
    {
        p->front->next = NULL;
        free(p);
        return;
    }
    p->front->next = p->next;
    p->next->front = p->front;
    free(p);
    L->len--;
}

八、打印

void print_dblist(dblist *L)
{
    if (L == NULL)
    {
        printf("入参为空\n");
        return;
    }
    else if (empty_dblist(L))
    {
        printf("链表为空\n");
        return;
    }
    dblist *p = L->next;
    while (p != NULL)
    {
        printf("p->data=%d\n", p->data);
        p = p->next;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值