C语言之单链表(头结点与节点结构相同)

本文详细介绍了单链表的各种操作实现,包括初始化、创建、添加、搜索、移除、删除节点及链表,同时提供了完整的代码示例和测试函数。

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

头文件

typedef int datatype ;

typedef struct  node
{
    datatype data;
    struct node *Next;

}node , list;


list *InitList(void);                       //初始化头节点
node *CreateNode(node *data);               //创建一个节点
int AddNode(list *head, node *newNode);     //加入一个节点
node *SearchNode(list *head, datatype date);//搜索一个节点
int RemoveNode(list *head, node *data);     //移除一个节点,但不删除该节点的内存
int DeleteNode(node *data);                 //删除一个节点的内存
int DestroyList(list *head);                //删除整条链表的节点和内存

int DeleteNumNode(list *head, int num);     //删除第几个节点(1,2,3,...)
int InsterNumNode(list *head, node *data, int num); //向链表插入或追加一个节点(num:1,2,3,...)
int SingleList(void);         //单链表给函数测试
int PrintfList(list *head);   //打印链表  

单链表的各个处理函数.c文件

//初始化头节点
list *InitList(void)
{
    list *head = (list *)malloc(sizeof(list) );
    if(NULL != head)
    {
        head->Next = NULL;
    }

    return head;
}

//创建一个节点
node *CreateNode(node *data)
{
    node *newData = (node *)malloc(sizeof(node) );
    if(newData == NULL) return NULL;

    if(data != NULL)
    {
        memcpy(newData, data, sizeof(node) );
    }
    else
    {
        memset(newData, 0, sizeof(node));
    }
    newData->Next = NULL;

    return newData;
}

//加入一个节点
int AddNode(list *head, node *newNode)
{
    node *pNode = head;

    if(head == NULL || newNode == NULL) return -1;

    while (pNode->Next != NULL)
    {
        pNode = pNode->Next;
    }
    newNode->Next = pNode->Next;
    pNode->Next = newNode;

    return 0;
}

//搜索一个节点
node *SearchNode(list *head, datatype data)
{
    node *temp = NULL;

    if(head == NULL ) return NULL;

    temp = head->Next;
    while(temp != NULL)
    {
        if(temp->data == data) break; //找到则跳出循环
        temp = temp->Next;
    }

    return temp;
}

//移除一个节点,但不删除该节点的内存
int RemoveNode(list *head, node *data)
{
    node *nodePre = NULL;
    node *nodeTemp = NULL;

    if(head == NULL || data == NULL) return -1;

    nodeTemp = head;
    while(nodeTemp != NULL)
    {
        if(nodeTemp->Next == data)  //找到对应的节点
        {
            nodePre = nodeTemp;     //节点的前一个节点
            nodeTemp = nodeTemp->Next; //目标节点
            break;
        }
        nodeTemp = nodeTemp->Next;
    }
    if(nodePre == NULL) return -1;
    else
    {
        nodePre->Next = nodeTemp->Next;
        nodeTemp->Next = NULL;
    }

    return 0;
}

//删除一个节点的内存
int DeleteNode(node *data)
{
    if(data == NULL) return -1;

    free(data);
    data = NULL;

    return 0;
}

//删除整条链表的节点和内存
int DestroyList(list *head)
{
    node *temp;
    node *next;

    if(head == NULL) return -1;

    temp = head->Next;
    while(temp != NULL)
    {
            next = temp->Next;
            DeleteNode(temp);
            temp = next;
    }
    DeleteNode(head);
    head = NULL;

    return 0;
}

//向链表插入或追加一个节点(num:1,2,3,...)
int InsterNumNode(list *head, node *data, int num)
{
    int findNum = num;
    node *pre = NULL;
    node *temp = NULL;
    node *add = CreateNode(data);

    if(head == NULL ||add == NULL || num <= 0) return -1;

    temp = head->Next;  //第一个节点

    if(num > 1)
    {
        while(temp != NULL)
        {
            if(findNum == 2)
            {
                pre = temp;
                break;
            }
            findNum--;
            temp = temp->Next;
        }
        if(pre == NULL) return -1; //插入的节点超出了链表的范围
    }

    temp = add;
    if(num == 1)
    {
        temp->Next = head->Next;
        head->Next = temp;
    }
    else
    {
        temp->Next = pre->Next;
        pre->Next  = temp;
    }

   return 0;
}

//删除第几个节点(1,2,3,...)
int DeleteNumNode(list *head, int num)
{
    node *temp = NULL;

    if(head == NULL || num <= 0) return -1;

    temp = head->Next;

    while(temp != NULL)
    {
        if(num == 1)
        {
            RemoveNode(head, temp); //从链表中移除一个节点
            DeleteNode(temp);       //将链表中移除的那个节点的内存删除
            break;
        }
        num--;
        temp = temp->Next;
    }

    return 0;
}

测试单链表函数

//打印链表  
int PrintfList(list *head)
{
     node *p = head->Next;

    if(head == NULL) return -1;

    while(p != NULL)
    {
        printf("%d\t", p->data);
        p = p->Next;
    }
    printf("\n");

    return 0;
}

//单链表给函数测试
int SingleList(void)
{
    node temp;
    node *delNode;
    node *newNode;
    list *head = InitList();
    if(head == NULL)
    {
        printf("malloc head is failed\n");
        return -1;
    }

    temp.data = 111;
    newNode = CreateNode(&temp);    //创建一个节点
    AddNode(head, newNode);         //向链表加入一个节点
    PrintfList(head);

    temp.data = 222;
    newNode = CreateNode(&temp);    //创建一个节点
    AddNode(head, newNode);         //向链表加入一个节点
    PrintfList(head);

    temp.data = 333;
    newNode = CreateNode(&temp);    //创建一个节点
    AddNode(head, newNode);         //向链表加入一个节点
    PrintfList(head);

    temp.data = 444;
    InsterNumNode(head, &temp, 4);  //向链表加入在第4个节点
    PrintfList(head);

    delNode = SearchNode(head, 222);    //搜索链表中节点对应的数据
    RemoveNode(head, delNode);          //从链表中移除该节点
    DeleteNode(delNode);                //被移除节点的内存
    PrintfList(head);

    DeleteNumNode(head, 1);         //删除第一个节点
    PrintfList(head);
    
    return 0;
}

代码效果图如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值