c语言单链表的基本操作

该程序包含了链表的头插法、尾插法、求表长、按位查找、按值查找、插入、删除、销毁等几种操作;

#include <stdio.h>
#include <stdlib.h> //malloc和free都需要这个系统库函数头文件; 
	typedef struct node//这里一定要有结构体变量名 
	{
		char data;
		struct node *next;
	 }listnode;
	 typedef listnode* linklist;
	 linklist head;//一般像这样经常要调用的头指针,定义在全局外面;head是一个没有空间的指针类型; 
	 
	 
	 linklist creatlistr()//创建尾插法,有头节点;有返回值为linklist类型; 
	 {
	 	char ch; 
	 	listnode *s,*r;     //此处定义两个指针,没有空间 ; 
	 	head=(listnode*)malloc(sizeof(listnode));      //创建一个头节点; 
	 	if(head==NULL)
	 	{
	 	    printf("申请存储空间失败");return head;	//此处返回值为链表(结构体)类型,所以函数声明为linklist类型 
		}
		r=head;    //r是辅助作用; 
		printf("请输入链表各个结点的数据(尾插字符型):");
		while((ch=getchar())!='\n')
		{
			s=(listnode*)malloc(sizeof(listnode));   // 创建一个结点; 分配空格键给地址,不用加*号; 
			if(s==NULL)
			{
				printf("申请存储空间失败");break; 
			}
			s->data=ch;    //赋值data 
			r->next=s;     //同时指向head结点的r的next链接新节点 
			r=s;      //r指针指向这个结点,以此类推; 
		 } 
	 }
	 
	  linklist creatlistf()//创建头插法 
	 {
	 	char ch; 
	 	listnode *s;//定义结点指针 ; 
	 	head=NULL;//将头指针指向空; 
	 	printf("请输入链表各个节点的数据(头插字符型)");
		while((ch=getchar()!='\n'))//按enter键结束; 数据倒序输入; 
		{
			s=(listnode*)malloc(sizeof(listnode));//获取一个新的链表空间; 
			if(s==NULL)
			{
			printf("空间申请失败");break; 
		    }
		    s->data=ch;
		    s->next=head;//插入第一个元素不太好理解,第二个就好; 
		    head=s;//把s接到head后面; 
		} 
		return head;//空; 
	 }
	 
	 listnode *locadelist(int i)//查找第i个元素;linklist定义一个新的链表,返回值不是NULL,就是p的地址; 
	 {
	 	listnode *p=head->next;               //这是在已经建立链表的基础上实现的; 
	 	int j=1;
	 	while(p&&j<i)//为空跳出;等于i跳出; 
	 	{
	 		p=p->next;//一个接着一个指下去; j指向位置,p指向值;找到了位置,返回值,值没找到,返回空; 
	 		j++;
		 }
		if(j==i)
		return p;//如果找到了第i个元素,就输出p的值 
		else
		return NULL; 
	 }
	 
	 char valuelist(char i)//linklist定义一个新的链表,返回值不是NULL,就是p的地址; 
	 {
	 	listnode *p=head->next;//定义一个指向头节点的指针; 
	 	while(p&&i!=p->data)//为空跳出;等于i跳出; 
	 	{
	 		p=p->next;//一个接着一个指下去; 
		 }
		if(p==NULL)
		printf("没有查找到该数据"); 
		else
		return p->data;
	 }
	 
	 int insertlist(char x,int i)//插入; 
	 {
	 	listnode *p,*g;
	 	p=locadelist(i-1);    //插入的前提是先查找; 
	 	if(p==NULL)
	 	{
	 	printf("没有找到该结点");return 0;
	    }
	 	g=(listnode *)malloc(sizeof(listnode));
	 	if(g==NULL)
	 	{
	 		printf("申请存储空间失败");return 0; 
		}
		g->data=x;
		g->next=p->next;
		p->next=g;
		return 1; 
	 }
	 
	 int deletelist(int i)//删除;linklist定义一个新的链表,返回值不是NULL,就是p的地址; 
	 {
	 	listnode *a,*b;
	 	a=locadelist(i-1);//删除插入事先都要先查找 ;把要删除的前面那个数给p; 
		if(!a->next)
		{
			printf("未查找到"); return 0;   //空的不会执行,所以要加非空符号; 
		 } 
		b=a->next;
		a->next=b->next;
		free(b);//释放内存,但是;若使用a->next=a->next->next形式,最后释放a->next的时候, 相当于释放了a->next和a->next->next
		return 1;
	 }
	 
	 void destroylist() //销毁 
	 {
	 	listnode *c,*d;
	 	c=head;
	 	while(c)
	 	{
	 		d=c->next;
	 		free(d);    //此处只是清楚内内存单元,但是结构和指针还是存在; 
	 		c=d;
		 }
		c=NULL;//最后还省剩一个,直接为空; 
	 }
	 
	 int lengthlist()//表长;返回值是什么类型,这里就要定义为什么类型; 
	 {
	 	listnode *e=head->next;
	 	int j=0;
	 	while(e)//为空跳出;
	 	{
	 		e=e->next;//一个接着一个指下去; 
	 		j++;   //e一开始指向第一个,若e不是了空就加1; 
		 }
		 return j;//返回值为int类型; 
	 }
	 
	 void main()
	 {
	 	int i,n,y;
	 	char x,z;
	    creatlistr();
	    creatlistf();
	    printf("请输入查找的位置");
	    scanf("%d",&y);
	    locadelist(y);
	    printf("请输入查找的值");
	    scanf("%c",&z);
	 	printf("%c",valuelist(z));
	 	printf("请输入插入的字符型数值和被插入的位置:"); 
		scanf("%c",&x,&i); 
	 	insertlist(x,i);
	 	printf("请输入要删除的位置:");
		scanf("%d",&n); 
	 	deletelist(n);
	 	printf("表长为:%d",lengthlist());
	 }

各位兄弟,如果这篇文章对你有那么一点点的帮助的话,就给我一点鼓励点个赞吧,兄弟我在这里谢谢大家啦!

  • 20
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单链表基本操作包括插入、删除和查找等。在C语言中,可以通过定义结构体和指针来实现单链表的操作。 1. 插入操作: 在单链表的第i个位置插入一个元素e,可以分为带头结点和不带头结点两种情况。 带头结点的插入操作(ListInsert(&l, i, e)): - 如果输入的i小于1,则i的值不合法,返回false。 - 定义指针p指向当前扫描到的结点,初始化j为0,表示当前指针p指向的是第几个结点。 - 将指针p指向头结点L,头结点是第0个结点(不存储数据)。 - 循环找到第i-1个结点,即p指向第i-1个结点,直到p为空或者j为i-1为止。 - 如果p为空,则i的值不合法,返回false。 - 定义新的结点s,并申请一个结点空间。 - 将元素e存储在新结点s的数据域中。 - 将新结点s的指针域指向p指针指向的下一个结点。 - 将p指针指向的下一个结点的指针域指向新结点s,即将新结点插入到p之后。 - 返回true,表示插入成功。 不带头结点的插入操作(ListInsert(&l, i, e)): - 如果输入的i小于1,则i的值不合法,返回false。 - 如果i等于1,表示要在第1个位置插入元素,特殊处理: - 定义新的结点s,并申请一个结点空间。 - 将元素e存储在新结点s的数据域中。 - 将新结点s的指针域指向头指针L。 - 头指针L指向新结点s。 - 返回true,表示插入成功。 - 定义指针p指向当前扫描到的结点,初始化j为0,表示当前指针p指向的是第几个结点。 - 将指针p指向头指针L,p指向第一个结点。 - 循环找到第i-1个结点,即p指向第i-1个结点,直到p为空或者j为i-1为止。 - 如果p为空,则i的值不合法,返回false。 - 定义新的结点s,并申请一个结点空间。 - 将元素e存储在新结点s的数据域中。 - 将新结点s的指针域指向p指针指向的下一个结点。 - 将p指针指向的下一个结点的指针域指向新结点s,即将新结点插入到p之后。 - 返回true,表示插入成功。 2. 删除操作: 在单链表中删除第i个位置的元素,同样分为带头结点和不带头结点两种情况。 带头结点的删除操作(ListDelete(&l, i, e)): - 如果输入的i小于1,则i的值不合法,返回false。 - 定义指针p指向当前扫描到的结点,初始化j为0,表示当前指针p指向的是第几个结点。 - 将指针p指向头结点L,头结点是第0个结点(不存储数据)。 - 循环找到第i-1个结点,即p指向第i-1个结点,直到p为空或者j为i-1为止。 - 如果p为空,则i的值不合法,返回false。 - 如果第i-1个结点的下一个结点为空,表示第i-1个结点后已无其他结点,返回false。 - 定义指针q指向第i-1个结点的下一个结点。 - 用变量e返回被删除的元素的值,即e等于q指针指向的结点的数据域。 - 将第i-1个结点的指针域指向q指针指向的下一个结点,即将q结点从链中断开。 - 释放q结点的存储空间。 - 返回true,表示删除成功。 不带头结点的删除操作(ListDelete(&l, i, e)): - 如果输入的i小于1,则i的值不合法,返回false。 - 如果i等于1,表示要删除第1个位置的元素,特殊处理: - 定义指针q指向头指针L,q指向第一个结点。 - 用变量e返回被删除的元素的值,即e等于q指针指向的结点的数据域。 - 头指针L指向q指针指向的下一个结点。 - 释放q结点的存储空间。 - 返回true,表示删除成功。 - 定义指针p指向当前扫描到的结点,初始化j为0,表示当前指针p指向的是第几个结点。 - 将指针p指向头指针L,p指向第一个结点。 - 循环找到第i-1个结点,即p指向第i-1个结点,直到p为空或者j为i-1为止。 - 如果p为空,则i的值不合法,返回false。 - 如果第i-1个结点的下一个结点为空,表示第i-1个结点后已无其他结点,返回false。 - 定义指针q指向第i-1个结点的下一个结点。 - 用变量e返回被删除的元素的值,即e等于q指针指向的结点的数据域。 - 将第i-1个结点的指针域指向q指针指向的下一个结点,即将q结点从链中断开。 - 释放q结点的存储空间。 - 返回true,表示删除成功。 3. 查找操作: 在单链表中查找某个元素的位置或者判断单链表是否为空。 查找

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值