C语言~链表的相关操作

1、链表的插入操作

链表的插入操作可以在链表的头节点位置进行,也可以在某个节点的位置进行,或者可以像创建结构时在链表的后面添加节点。这3种插入操作的思路都是一样的。
  下面主要介绍第一种插入方式,在链表的头节点位置插入节点。
在这里插入图片描述
设计一个函数用来向链表中添加节点:

struct Student* Insert(struct Student* pHead)
{
	struct Student* pNew;		/*指向新分配的空间*/
	printf("----Insert member at first----\n");	/*提示信息*/
	pNew=(struct Student*)malloc(sizeof(struct Student));	/*分配内存空间,并返回指向该内存空间的指针*/

	scanf("%s",&pNew->cName);
	scanf("%d",&pNew->iNumber);

	pNew->pNext=pHead;			/*新结点指针指向原来的首结点*/
	pHead=pNew;					/*头指针指向新结点*/
	iCount++;					/*增加链表结点数量*/
	return pHead;
}

在代码中,为要插入的新节点分配内存,然后向新节点中输入数据,这样一个节点就创建完成了。接下来就是将这个节点插入到链表中。首先将新节点的指针指向原来的首节点,保存首节点的地址。然后将头指针指向新节点,这样就完成了节点的连接操作,最后增加链表的节点数量。

2、链表的删除操作

在一个链表中删除其中的一点,如下图所示:

在这里插入图片描述  
  通过上图可以发现,要删除一个节点,首先要找到这个节点的位置,例如图中的NO2节点。然后将NO1节点的指针指向NO3节点,最后将NO2节点的内存空间释放掉,这样就完成了节点的删除操作。
  根据这种思想编写删除链表节点操作的函数:

void Delete(struct Student* pHead,int iIndex)	/*pHead表示头结点,iIndex表示要删除的结点下标*/
{
	int i;  /*控制循环变量*/
	struct Student* pTemp;		 /*临时指针*/
	struct Student* pPre;		/*表示要删除结点前的结点*/
	pTemp=pHead;				/*得到头结点*/
	pPre=pTemp;					

	printf("----delete NO%d member----\n",iIndex);	/*提示信息*/
	for(i=1;i<iIndex;i++)		/*for循环使得pTemp指向要删除的结点*/
	{
		pPre=pTemp;
		pTemp=pTemp->pNext;
	}
	pPre->pNext=pTemp->pNext;	/*连接删除结点两边的结点*/
	free(pTemp);				/*释放掉要删除结点的内存空间*/
	iCount--;					/*减少链表中的元素个数*/
}

Delete函数传递两个参数,pHead表示链表的头指针,ilndex表示要删除节点在链表中的位置。定义整型变量i用来控制循环的次数,然后定义两个指针,分别用来表示要删除的节点和这个节点之前的节点。
  输出一行提示信息表示要进行删除操作,之后利用for语句进行循环操作找到要删除的节点,使用pTemp保存要删除节点的地址,pPre保存前一个节点的地址。找到要删除的节点后,连接删除节点两边的节点,并使用free函数将pTemp指向的内存空间进行释放。

3、完整链表操作代码

#include<stdio.h>
#include<stdlib.h>

struct Student
{
	char cName[20];						/*姓名*/
	int iNumber;							/*学号*/
	struct Student* pNext;					/*指向下一个结点的指针*/
};

int iCount;									/*全局变量表示链表长度*/

struct Student* Create()
{
	struct Student* pHead=NULL;				/*初始化链表头指针为空*/
	struct Student* pEnd,*pNew;
	iCount=0;								/*初始化链表长度*/
	pEnd=pNew=(struct Student*)malloc(sizeof(struct Student));
	printf("please first enter Name ,then Number\n");
	scanf("%s",&pNew->cName);
	scanf("%d",&pNew->iNumber);
	while(pNew->iNumber!=0)
	{
		iCount++;
		if(iCount==1)
		{
			pNew->pNext=pHead;			/*使得指向为空*/
			pEnd=pNew;					/*跟踪新加入的结点*/
			pHead=pNew;					/*头指针指向首结点*/
		}
		else
		{
			pNew->pNext=NULL;			/*新结点的指针为空*/
			pEnd->pNext=pNew;				/*原来的为结点指向新结点*/
			pEnd=pNew;					/*pEnd指向新结点*/
		}
		pNew=(struct Student*)malloc(sizeof(struct Student));	/*再次分配结点内存空间*/
		scanf("%s",&pNew->cName);
		scanf("%d",&pNew->iNumber);
	}
	free(pNew);							/*释放没有用到的空间*/
	return pHead;
}

void Print(struct Student* pHead)
{
	struct Student *pTemp;					/*循环所用的临时指针*/
	int iIndex=1;							/*表示链表中结点的序号*/

	printf("----the List has %d members:----\n",iCount);		/*消息提示*/
	printf("\n");							/*换行*/
	pTemp=pHead;							/*指针得到首结点的地址*/

	while(pTemp!=NULL)
	{
		printf("the NO%d member is:\n",iIndex);
		printf("the name is: %s\n",pTemp->cName);		/*输出姓名*/
		printf("the number is: %d\n",pTemp->iNumber);		/*输出学号*/
		printf("\n");						/*输出换行*/
		pTemp=pTemp->pNext;				/*移动临时指针到下一个结点*/
		iIndex++;							/*进行自加运算*/
	}
}

struct Student* Insert(struct Student* pHead)
{
	struct Student* pNew;		/*指向新分配的空间*/
	printf("----Insert member at first----\n");	/*提示信息*/
	pNew=(struct Student*)malloc(sizeof(struct Student));	/*分配内存空间,并返回指向该内存空间的指针*/

	scanf("%s",&pNew->cName);
	scanf("%d",&pNew->iNumber);

	pNew->pNext=pHead;			/*新结点指针指向原来的首结点*/
	pHead=pNew;					/*头指针指向新结点*/
	iCount++;					/*增加链表结点数量*/
	return pHead;
}

void Delete(struct Student* pHead,int iIndex)	/*pHead表示头结点,iIndex表示要删除的结点下标*/
{
	int i;  /*控制循环变量*/
	struct Student* pTemp;		 /*临时指针*/
	struct Student* pPre;		/*表示要删除结点前的结点*/
	pTemp=pHead;				/*得到头结点*/
	pPre=pTemp;					

	printf("----delete NO%d member----\n",iIndex);	/*提示信息*/
	for(i=1;i<iIndex;i++)		/*for循环使得pTemp指向要删除的结点*/
	{
		pPre=pTemp;
		pTemp=pTemp->pNext;
	}
	pPre->pNext=pTemp->pNext;	/*连接删除结点两边的结点*/
	free(pTemp);				/*释放掉要删除结点的内存空间*/
	iCount--;					/*减少链表中的元素个数*/
}

int main()
{
	struct Student* pHead;					/*定义头结点*/
	pHead=Create();							/*创建结点*/
	pHead=Insert(pHead);					/*插入结点*/
	Delete(pHead,2);						/*删除第二个结点的操作*/
	Print(pHead);							/*输出链表*/
	return 0;								/*程序结束*/
}

输出结果:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值