链表的基本操作(C语言版):建立,插入,删除,查找,输出

本文介绍了一种不带头结点的单链表实现方法,包括初始化、插入、删除、查找等核心操作,并提供了完整的C语言代码示例。

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

//1、链表的基本操作(不带头结点)//**的含义把握不准确,要认真研究练习
#include<stdio.h>
#include<malloc.h>
typedef struct list
{
int data;
struct list *next;
}LIST;

void InitList(LIST **p)
{//初始化链表
	*p=NULL;
}
void InsertList1(LIST**p,int rc,int item)
{//向链表指定位置【rc】插入元素【item】
	int i;
	LIST *u,*q,*r;//u为新结点,q插入点前驱,r为插入点后继
	u=(LIST*)malloc(sizeof(LIST));
	u->data=item;
	for(i=0,r=*p;i<rc&&r!=NULL;i++)//i!=rc
	{	q=r;
		r=r->next;
	}
	if(r==*p)//p==NULL //插入首结点或p为空指针
		*p=u;
	else
		q->next=u;
		u->next=r;//两者顺序应该换下吧?卡壳?这两行代码加入大括号内报错!!
	
}


void InsertList2(LIST**p,int item)
//向有序链表【p】插入键值为【item】的结点
{
	LIST *u,*q,*r;//u为新结点,q插入点前驱,r为插入点后继
	u=(LIST*)malloc(sizeof(LIST));
	u->data=item;//p!=NULL
	for(r=*p;r!=NULL&&r->data<item;q=r,r=r->next);//从链表首结点开始顺序查找
	//插入首结点或p为空指针
	if(r==*p)
	*p=u;//r->next=u;
	else
	q->next=u;
	u->next=r;
}

int DeleteList(LIST**p,int item)//
//删除键值为【item】的链表结点,返回0为删除成功,1为没找到
{
	LIST *q,*r;//q为结点前驱,r为结点后继
	q=*p;
	if(q==NULL)//链表为空
		return 1;
	if(q->data==item)//要删除链表首结点
		{
			*p=q->next;//p=q->link 更改链表首结点指针
		free (q);//释放被删除结点的空间
		return 0;//删除头结点成功
		}
	for(;q->data!=item&&q->next!=NULL;r=q,q=q->next);//q!=NULL&&p
	//寻找键值为【item】的结点//r为结点,q为结点后继
	if(q->data==item)//找到结点
	{
		r->next=q->next;//被删结点从链表中脱离
		free(q);		//释放被删除结点的空间
		return 0;		//	删除成功
	}
return 1;			//没有指定值的结点,删除失败
}
int FindList(LIST*p,int item)
{	//查找键值【item】的链表结点位置,返回≥1为找到,-1为未找到
	int i;
	for(i=1;p->data!=item&&p!=NULL;p=p->next,i++);
	//查找键值【item】的链表结点
	return(p==NULL)?-1:i;//找到返回【i】

}
void OutputList(LIST *p)
{//输出链表结点的键值
	while(p!=NULL)
	{
		printf("%4d",p->data);
		p=p->next;
	}
}
void FreeList(LIST **p)
{//释放链表空间
	LIST *q,*r;
	for(q=*p;q!=NULL;)
	{	r=q;//q=*p
		q=q->next;
		free(r);
	}
	*p=NULL;//将链表首结点指针置空
}

void main()
{	
LIST *p;
int op,i,rc;
InitList(&p);
while(1)
{
	printf("\n请选择操作1:指定位置追加 2:升序追加 3:查找结点\n");
	printf("4、删除结点 5:输出结点 6、清空链表 0:退出\n");
	fflush(stdin);
	scanf("%d",&op);
	switch(op)
	{
	case 0:return;
	case 1:
		printf("\n请输入新增结点位置和键值:");
		scanf("%d %d",&rc,&i);
		InsertList1(&p,rc,i);
		break;
	case 2:
		printf("\n请输入新增结点键值:");
		scanf("%d",&i);
		InsertList2(&p,i);
		break;
	case 3:
		printf("\n请输入要查找结点的键值:");
		scanf("%d",&i);
		rc=FindList(p,i) ;
			if(rc>0)
				printf("位置为【%d】\n",rc);
			else 
				printf("没找到!");
			break;
	case 4:
		printf("\n请输入要删除结点的键值:");
		scanf("%d",&i);
		rc=DeleteList(&p,i);
		if(rc==0)
			printf("删除成功\n",rc);
		else
			printf("没找到\n");
		break;
	case 5:
		printf("\n链表内容为:\n");
		OutputList(p);
		break;
	case 6:
		FreeList(&p);
		break;
	}
}


}

补充:带头结点和不带头结点的单链表初始化区别:在创建链表的过程中实现的,可以这样区分:带头结点吗的必须用head->next访问第一个元素,而不带头结点的只须head就可可以访问第一个元素了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值