【C语言】单链表(一)

本文介绍了C语言中单链表的基本概念,包括结点结构、链接存储方法以及如何创建、插入数据、按值删除节点和打印链表。代码实现包括创建头节点、新建节点、头插法插入数据、按值删除节点和打印链表的函数,展示了链表操作的基本步骤。
摘要由CSDN通过智能技术生成

1、基本叙述

1.1概念介绍

链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
以“结点的序列”表示线性表称作线性链表(单链表),单链表是链式存取的结构。

1.2链接存储方法

链接方式存储的线性表简称为链表(Linked List)。
链表的具体存储表示为:
① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)
② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link))
链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。

1.3结点结构

┌───┬───┐
│data │next │
└───┴───┘
data域–存放结点值的数据域
next域--存放结点的直接后继的地址(位置)的指针域(链域)
链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的,每个结点只有一个链域的链表称为单链表(Single Linked List)

2、数据储存

在这里插入图片描述

3、代码实现

3.1创建一个结构体

typedef int Node_Data;

typedef struct node{
    Node_Data data;
    struct node* next;
}Lnode;

我们使用了typedef的两个用法:为基本数据类型定义新的类型名为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称,这样会使代码更简洁,而typedef int Node_Data方便更改链表储存其它数据类型
3.2创建头节点

//创建链表头节点,返回值为struct node*
Lnode* Create_Head_Node()
{
    //动态内存申请
    Lnode* Head_Node = (Lnode *)malloc(sizeof(Lnode));
    if(Head_Node == NULL)
    	return NULL;
    else
    {
	    //初始化头节点
	   // Head_Node->data = 1;  //这个可以随意赋值
	   Head_Node->next = NULL;
	   return Head_Node;
    }
}

3.3创建新的节点

//创建新的节点,并给此节点赋值
Lnode* Create_New_Node(Node_Data data)
{
    Lnode* New_Node = (Lnode *)malloc(sizeof(Lnode));
    
    if(New_Node == NULL)
    	return NULL;
    else
    {
	    New_Node->data = data;
	    New_Node->next = NULL;
	    
	    return New_Node;
    }
}

把创建新的节点封装成一个函数,方便后续使用
3.4头插法插入数据

//头插法插入数据
void Insert_Data_List(Lnode* Head_Node,Node_Data data)
{
    Lnode* New_Node = Create_New_Node(data);
    
    if(Head_Node == NULL || New_Node == NULL)
    {
        printf("插入失败\n");
        return ;
    }
    else
    {
        New_Node->next = Head_Node->next;
        Head_Node->next = New_Node;
        //printf("插入成功\n");
        return ;
    }
}

所谓的头插法,就是每次从Head_Node后面插入.
大概思路为:先创建一个待插入的节点New_Node,再把头节点Head_Node指针域的地址赋值给待插入节点New_Nodenext,最后把头节点Head_Nodenext指向New_Node
在这里插入图片描述

3.5按指定值删除

//按值删除
void Delete_AccordValue_List(Lnode* Head_Node,Node_Data posdata)
{
    Lnode* posNode = Head_Node->next;
    Lnode* posNodeFront = Head_Node;
    
    if(posNode == NULL)
    {
        printf("此链表为空,删除失败\n");
        return ;
    }
    else
    {
        while(posNode->data != posdata)
        {
            posNodeFront = posNode;
            posNode = posNode->next;
            //遍历到链表尾部,代表该值不存在
            if(posNode == NULL)
            {
                printf("删除失败,不存在该值\n");
                return ;
            }
        }
        posNodeFront->next = posNode->next;
        free(posNode);
        printf("删除成功\n");
    }
}

删除节点:假设posNode为待删除的节点,posNodeFront为待删除的节点的前一个节点,如要删除posNode,只需要把posNode所指向的节点赋值给posNodeFront,然后释放posNode这块内存,free(posNode)
在这里插入图片描述

思路如下:
1.判断该链表是否为空
2.遍历链表,确保posNodeposNodeFront一前一后
3.while(posNode->data != posdata)找到待删除的节点时,跳出此循环,若没跳岀循环,则代表该值不存在
4.删除节点posNode

3.6打印链表

//打印链表
void Printf_List(Lnode* Head_Node)
{
    Lnode* pMove = Head_Node->next;
    
    if(pMove == NULL)
    {
        printf("此链表为空,打印失败\n");
        return ;
    }
    else
    {
        while(pMove != NULL)
        {
            printf("%d->",pMove->data);
            pMove = pMove->next;
        }
        printf("NULL\n");
    }
}

4、全部代码如下

#include<stdio.h>
#include<malloc.h>

typedef int Node_Data;

typedef struct node{
    Node_Data data;
    struct node* next;
}Lnode;

//创建链表头节点,返回值为struct node*
Lnode* Create_Head_Node()
{
    //动态内存申请
    Lnode* Head_Node = (Lnode *)malloc(sizeof(Lnode));
    if(Head_Node == NULL)
    	return NULL;
    else
    {
	    //初始化头节点
	   // Head_Node->data = 1;  //这个可以随意赋值
	   Head_Node->next = NULL;
	   return Head_Node;
    }
}

//创建新的节点,并给此节点赋值
Lnode* Create_New_Node(Node_Data data)
{
    Lnode* New_Node = (Lnode *)malloc(sizeof(Lnode));
    
    if(New_Node == NULL)
    	return NULL;
    else
    {
	    New_Node->data = data;
	    New_Node->next = NULL;
	    
	    return New_Node;
    }
}

//打印链表
void Printf_List(Lnode* Head_Node)
{
    Lnode* pMove = Head_Node->next;
    
    if(pMove == NULL)
    {
        printf("此链表为空,打印失败\n");
        return ;
    }
    else
    {
        while(pMove != NULL)
        {
            printf("%d->",pMove->data);
            pMove = pMove->next;
        }
        printf("NULL\n");
    }
}

//头插法插入数据
void Insert_Data_List(Lnode* Head_Node,Node_Data data)
{
    Lnode* New_Node = Create_New_Node(data);
    
    if(New_Node == NULL)
    {
        printf("插入失败\n");
        return ;
    }
    else
    {
        New_Node->next = Head_Node->next;
        Head_Node->next = New_Node;
        //printf("插入成功\n");
        return ;
    }
}

//按值删除
void Delete_AccordValue_List(Lnode* Head_Node,Node_Data posdata)
{
    Lnode* posNode = Head_Node->next;
    Lnode* posNodeFornt = Head_Node;
    
    if(posNode == NULL)
    {
        printf("此链表为空,删除失败\n");
        return ;
    }
    else
    {
        while(posNode->data != posdata)
        {
            posNodeFornt = posNode;
            posNode = posNode->next;
            if(posNode == NULL)
            {
                printf("删除失败,不存在该值\n");
                return ;
            }
        }
        posNodeFornt->next = posNode->next;
        free(posNode);
        printf("删除成功\n");
    }
}




int main()
{
    Lnode* Head_Node = Create_Head_Node();
    
    Insert_Data_List(Head_Node,1);
    Insert_Data_List(Head_Node,2);
    Insert_Data_List(Head_Node,3);
    Insert_Data_List(Head_Node,4);
    Insert_Data_List(Head_Node,5);
    Insert_Data_List(Head_Node,6);
    Insert_Data_List(Head_Node,7);
    Printf_List(Head_Node);
    
    return 0;
}

查找、按位置插入请查看 【C语言】单链表(二)

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

点灯大师~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值