C语言——单链表

本文详细介绍了单链表的基本概念,包括结构定义、增删查改等核心操作的实现原理及代码示例,通过具体实例展示了如何使用单链表。

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

单链表

所有元素没有紧挨在一起,但每个元素知道下一个元素的地址

定义:

struct Node
{
	DataType d;
	struct Node *next;
};

单链表思路图:
在这里插入图片描述
我会在下面附上单链表代码,有增、删、查、改、倒置、打印功能,并且尽量加上注释,如果还有不懂可以在评论区留言,我会尽我所能解答

单链表代码:

link.h 头文件,用来定义结构体,声明函数

#ifndef __Link_H__	//如果不存在则定义以下内容
#define __Link_H__
#include <stdbool.h>
typedef int dType;			//重命名int为dType,方便改数据类型
typedef struct Node			//定义一个单链表
{
        dType s;
        struct Node *next;
}node,*pnode;				//重命名
//声明函数,添加,打印,查找,更改,删除,倒置
//add
extern bool add(pnode*,student);
//list
extern void list(pnode);
//find
extern pnode find(pnode,char*);
//update
extern bool update(pnode,char*,student);
//drop
extern bool drop(pnode*,char*);
//rease
extern void rease(pnode *pph,pnode first,pnode second,pnode third);
#endif

link.c 主要函数文件,写实现方法,被调用

#include <stdio.h>		//标准库
#include <stdlib.h>		//堆区
#include "link.h"		//自定义头文件

bool add(pnode *pph,Dtype d)		//头插法,增加一个链表元素
{
        pnode pn=NULL;				//创建新的节点
        pn=malloc(sizeof(node));	//分配堆区空间
        if(NULL==pn)				//分配失败返回false
                return false;
        pn->d=d;					//填充内容
        pn->next=*pph;
        *pph=pn;					//让头结点指向该节点
        return true;				//返回true
}

void list(pnode ph)			//打印
{
        while(NULL!=ph)		//头节点不为空
        {
                printf("%d ",ph->d);	//打印内容
                ph=ph->next;			//指向下一个节点
        }
        printf("\n");
}

pnode find(pnode ph,Dtype d)				//查找元素,返回节点指针
{
        while(NULL!=ph && d!=ph->d)			//节点不为空,且数据不相等,指向下一个节点
                ph=ph->next;
        return ph;							//返回ph,若没找到ph指向NULL,返回也为空
}

bool update(pnode ph,Dtype oldd,Dtype newd)	//更新
{
        pnode pn=NULL;						//创建新的节点
        if((pn=find(ph,oldd))==NULL)		//调用查找函数,若没找到返回false
                return false;
        pn->d=newd;							//否则,更新数据
        return true;						//返回true
}

bool drop(pnode *pph,Dtype key)	//删除,前一个节点指向下一个节点
{
		//创建两个节点,用来找到前一个的节点(first)与当前节点(ploc)
        pnode first=NULL,ploc=*pph;	
        while(ploc!=NULL && ploc->d!=key)	//循环查找需要删除的节点,first始终指向ploc上一个节点
        {
                first=ploc;
                ploc=ploc->next;
        }
        if(NULL==ploc)					//循环结束后若ploc等于NULL,说明没有改元素
                return false;			//返回false
        else if(ploc==*pph)				//否则如果ploc==头指针,说明第一个元素就是需要删除的
                *pph=ploc->next;		//让头指针直接指向下一个节点
        else							//否则就是找到该元素,且不是第一个
                first->next=ploc->next;	//让前一个节点指向下一个节点
        free(ploc);						//释放堆区,一定不要忘记
        return true;					//删除成功返回true
}

void rease(pnode *pph,pnode first,pnode second,pnode third)	//递归倒置
{
//先让first,second=NULL,third=头结点,然后每次往后移动一个元素
//主要对second进行判断,让second一直指向前一个元素,让third起到一直读取的作用
        if(NULL!=second)			//second不等于NULL,则让second指向first(前一个元素)
                second->next=first;
        if(NULL==third)				//递归结束条件,third已经指向了空,这时second指向最后一个元素
        //则让头结点指向second,结束递归
        {
                *pph=second;
                return;
        }
        rease(pph,second,third,third->next);
        //调用自己,first指向second,second指向third,third指向third的next
}

main.c 主文件,用来调用函数,测试链表

#include <stdio.h>	//标准库
#include "link.h"	//自定义头文件
int main()
{
        pnode head=NULL;		//定义头节点
        printf("添加1,2,3,4\n");	
        add(&head,1);
        add(&head,2);
        add(&head,3);
        add(&head,4);
        list(head);
        printf("-------------------------\n");
        printf("查找元素:2\n");
        pnode pf=NULL;
        if((pf=find(head,2))!=NULL)
                printf("%d\n",pf->d);
        else
                printf("not found\n");
        printf("-------------------------\n");
        printf("更改元素2—>5\n");
        if(update(head,2,5))
                printf("success\n");
        else
                printf("fail\n");
        list(head);
        printf("-------------------------\n");
        printf("删除元素:4\n");
        drop(&head,4);
        list(head);
        printf("-------------------------\n");
        rease(&head,NULL,NULL,head);
        list(head);

        return 0;
}

程序运行结果:
在这里插入图片描述
头插法,所以存放数据会像栈一样存入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值