c语言链表基本操作(4)

双向链表的定义:

typedef struct node
{
    int data;
    struct node *next;
    struct node *prior;
} Node;

在单链表里添加一个prior指针指向上一个节点,就是一个双向链表。如果链表的最后一个节点指向开始节点,即end->next = head就构成双向循环链表,双向循环链表代码实现如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

typedef struct node
{
    int data;
    struct node *next;
    struct node *prior;
    int length;
} Node;

typedef Node *DuLinkList;

void initDuLinkList(DuLinkList *L)
{
    *L = (struct node *)malloc(sizeof(struct node));
    scanf("%d", &((*L)->data));
    while (getchar() != '\n')
    {
        ;
    }
    (*L)->length = 1; // 循环链表的长度
    (*L)->next = NULL;
    (*L)->prior = NULL;
    struct node *prev, *current;
    prev = *L;
    while (1)
    {
        current = (struct node *)malloc(sizeof(struct node));
        scanf("%d", &current->data);
        while (getchar() != '\n')
        {
            ;
        }
        current->next = NULL;
        if (current->data == 0)
        {
            break; // 输入0就跳出无限循环
        }
        current->prior = prev;
        prev->next = current; // (*L)->next = current; 下次循环是上次的current的next指向当前的current,即(*L)->next->next = current
        (*L)->length++;       // 长度+1
        prev = current;
    }
    // 跳出循环以后,prev指向了最后一个节点,让prev的next指向表头构成循环链表,表头的prior指向prev构成双向链表
    (*L)->prior = prev;
    prev->next = *L;
}

void print(DuLinkList *L)
{
    struct node *head;
    head = *L;
    int i = 1;
    while (head)
    {
        printf("双向链表的第%d个节点的数据是%d\n", i, head->data);
        head = head->next;
        i++;
        // 当节点的下一个节点指向头部时
        if (head == *L)
        {
            break;
        }
    }
}

int getLength(DuLinkList *L)
{
    return (*L)->length;
}

int getLengthByMap(DuLinkList *L)
{
    struct node *p = *L;
    int i = 0;
    while (p)
    {
        i++;
        p = p->next;
    }
    
    return i;
}

struct node *getElem(DuLinkList *L, int i)
{
    struct node *head = *L;
    int index = 1;
    while (head)
    {
        if (index == i)
        {
            return head;
        }
        index++;
        head = head->next;
    }
    return NULL;
}

// 第i个节点的前面插入数据
void insertElem(DuLinkList *L, int i, int data)
{
    struct node *insertNode, *current;
    current = (struct node *)malloc(sizeof(struct node));
    current->data = data;
    current->next =
    insertNode = getElem(L, i);
    if (insertNode)
    {
        printf("要插入的节点的数据是%d\n", insertNode->data);
        // 插入需要操作四个指针,current的next和prior,上一个节点的next指针,和当前节点的prior指针
        insertNode->prior->next = current;
        insertNode->prior = current;
        current->next = insertNode;
        current->prior = insertNode->prior;
        if(*L == insertNode) {
            *L = current; // 在第一个节点前插入当前新的节点,链表的表头要从新的节点开始
        }
        (*L)->length++;
        puts("插入成功");
    }
}

int main()
{
    DuLinkList list;
    initDuLinkList(&list);
    print(&list);
    int index = 3;
    struct node *node1;
    node1 = getElem(&list, index);
    if (node1)
    {
        printf("第%d个节点的数据值为:%d\n", index, node1->data);
        printf("第%d个节点的前一个节点数据值为:%d\n", index, node1->prior->data);
    }

    insertElem(&list, 1, 100); // 在第一个节点前面插入一个节点
    print(&list);
    return 0;
}

 程序包括初始化函数、输出打印函数、获取指定位置节点函数、插入函数。执行结果如下:

 删除函数请自行实现,注意删除第一个头结点,要让链表的head指向head的下一个节点。

添加函数操作四个指针,删除函数只需要操作两个指针,即current->prior->next = current->next和

current->next->prior = current->prior。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heine162

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值