基于C语言的双链表操作(包含完整代码)

该文详细介绍了如何使用C语言创建和操作双链表,包括定义结构体Node,初始化链表,头插法和尾插法插入元素,删除指定节点以及遍历输出链表内容。文中还提供了主函数来验证各个操作的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先加上#include <stdio.h>和#include <stdlib.h>两个头文件

1、定义结构体变量

typedef struct Node
{
    int data;//数据域 
    struct Node *pre;//前驱指针
    struct Node *next;//后继指针 
}Node;

2、初始化指针函数

Node *iniList()
{
    Node *node = (Node *)malloc(sizeof(Node));//申请新的指针空间 
    node->data = 0;//头指针data域表示链表中有多少个元素,初始设为0 
    node->pre = NULL;//前驱节点指向空 
    node->next = NULL;//后继节点也指向空 
    return node;//返回这个初始头指针 
}

3、头插法建立双链表

void headList(Node *L,int data)
{
    Node *node = (Node *)malloc(sizeof(Node));//为新节点申请内存空间 
    node->data = data;//首先将新数据写入新申请的节点内 
    if(L->data==0)//判断链表是否为空,也就是头节点data域是否为0 
    {
        node->next = L->next;//空链表,node指针直接链接到头节点后面 
        node->pre = L;//node前驱节点链接到头节点 
        L->next = node;//头节点后继节点链接到node 
        L->data++;//头节点data域数字加一 ,表明新增一个元素
    }
    else//头指针后面有节点 
    {
        node->pre = L;//首先将node节点的前驱指针指向头节点 
        node->next = L->next;//然后将node的后继节点指针指向头节点指针的后继节点 
        L->next = node;//头节点后继指针指向node,此时之前的L->next断裂 
        node->next->pre = node;//再将node的后继节点的前驱指向node 
        L->data++;//全部完成后,头节点data域加一,表明新增一个元素            
    }

4、尾插法建立双链表

void tailList(Node *L,int data)
{
    Node *node = (Node *)malloc(sizeof(Node));//申请空间 
    node->data = data;//写入数据 
    node->next = NULL;//node是最后节点指向空 
    Node *tail = L;//设立尾指针
    while(tail->next!=NULL)//使得尾指针能真正指向链表的尾部    
    {
        tail = tail->next;
    }
    tail->next = node;//尾指针的后继指向node 
    node->pre = tail;//node的前驱指向尾节点 
    L->data++;//全部完成后,头节点data域加一,表明新增一个元素    

5、删除节点操作(可删除重复节点)

void deleteList(Node *L,int data)
{
    Node *current = L;//定义当前需要移动的指针 
    Node *temp;//定义中间指针,方便删除链表中相同元素的节点 
    while(current->next!=NULL)
    {
        if(current->data==data)
        {
            temp = current->next;//首先将要删除节点的前一个节点赋值给中间指针 
            current->pre->next = current->next;//将前一个节点后继指向下下节点 
            current->next->pre = current->pre;//将当前节点的下一个节点的前驱指向前一个节点 
            L->data--;//头指针中的data元素值减一 
            current = temp;//将当前要删除节点的上一个节点赋值给current,以便继续删除        
        }
        else
            current = current->next;//没有符合节点,current向后走 
    }
    /*上面的操作不能删除重复元素链表尾部的最后一个元素*/
    if(current->data==data)//查看最后节点的元素是否符合要求 
    {
        current->pre->next = NULL;
        free(current);
    }
}

6、遍历输出函数

void printList(Node *L)
{
    L = L->next;//头指针不打印 
    while(L)//L不为空则继续循环 
    {
        printf("%d ",L->data);
        L = L->next;//L指向下一个节点 
    }
    printf("\n");
}

7、主函数验证各个函数的正确性

int main()
{
    int i;
    Node *L = iniList();//初始化 
    for(i=0;i<=5;i++)
        headList(L,i);//验证头插法 
    for(i=6;i<=10;i++)
        tailList(L,i);//验证尾插法
    tailList(L,1);
    tailList(L,5);
    tailList(L,5);
    tailList(L,5);
    tailList(L,1);
    printList(L);
    deleteList(L,5);//验证删除函数 
    printList(L);//验证遍历输出    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值