C语言链表的创建,遍历,加入,删除,完整代码

创建

首先链表这个数据结构的结构体由两个部分组成,分别是数据域和指针域,也就是存放数据的变量和指针

struct student{
	char name[30];   //数据域
	float number;    //数据域
	struct student *pNext;   //指针域
};

链表的创建,就是在创建节点(malloc)和输入数据的同时让每个节点(结构体)都连接起来,连接的方式就是靠指针域中的指针,让每个结点的pNext都指向下一个节点,最后一个节点没节点可指的呀,那就让最后一个节点的指针(pNext)指向空(NULL)
这样,每个节点都连在了一起,就形成了一个长链,链表就创建好啦

struct student *create(){
	struct student *pHead=NULL;   //头节点,指向第一个结构体
	struct student *pNew,*pEnd;   //新节点和最后一个节点
	pNew=pEnd=(struct student*)malloc(sizeof(struct student));  //给新节点和最后一个节点分配内存
	printf("名字 学号:");
	scanf("%s %f",&pNew->name,&pNew->number);  //输入数据
	/*判断当数据中的number等于0时停止分配新节点*/
	while(pNew->number!=0){
		len++;  //长度(将会在后面完整代码中出现,这是个全局变量)
		if(len==1){
			pNew->pNext=NULL;  //当长度等于1时让新节点的指针指向空(NULL)
			pEnd=pNew;
			pHead=pNew;
		}
		else{
			pNew->pNext=NULL;  //当长度大于1时新节点指针指向空
			pEnd->pNext=pNew;  //最后一个节点指向新节点
			pEnd=pNew;  
		}
		pNew=(struct student*)malloc(sizeof(struct student));  //分配新节点
		scanf("%s %f",&pNew->name,&pNew->number);
	}
	free(pNew);  //将多分配出的节点释放掉
	return pHead;  //返回链表的的头节点
}

或者还可以这样创建

struct student *create(){
	struct student *pHead,*pNew,*p;  
	pNew=(struct student*)malloc(sizeof(struct student));
	printf("输入名字 学号:\n");
	scanf("%s %f",&pNew->name,&pNew->number);
	pNew->pNext=NULL;
	pHead=pNew;
	p=pNew;
	pNew=(struct student*)malloc(sizeof(struct student));
	scanf("%s %f",&pNew->name,&pNew->number);
	while(pNew->number!=0){
		p->pNext=pNew;
		p=p->pNext;
		pNew=(struct student*)malloc(sizeof(struct student));
		scanf("%s %f",&pNew->name,&pNew->number);
	}
	p->pNext=NULL;
	free(pNew);
	return pHead;
}

遍历

知道如何创建了,下一步就是遍历
遍历的话就很简单了,就是用循环让指针指向下一个节点然后输出数据域里的数据就好了

void print(struct student *pHead){  //遍历函数,传入头节点
	struct student *tep;    //遍历指针
	int i=1;    //长度
	tep=pHead;  //让遍历指针指向头节点
	printf("----------共%d个成员----------\n",len);  //输出长度
	/*当指针等于NULL,停止循环*/
	while(tep!=NULL){
		printf("No.%d名字:%s\n",i,tep->name);  //输出数据
		printf("学号:%g\n\n",tep->number);  //输出数据
		i++;  //第i个数据
		tep=tep->pNext;  //指向下一个节点
	}
	printf("\n\n");
}

加入新节点

基本的创建和遍历学会后,现在来学如何在操作过程中加入新结点

1.在头节点后加入
头节点后好说,先在新开辟的结构体里输入新数据,然后让新节点的pNext指向头节点的pNext,再让头节点的pNext指向新节点,这样,新的数据就被加入到了头节点后面

struct student *addah(struct student *pHead){  //加入函数,传入头节点
	struct student *pNew,*tep;  //新的节点(这里的*tep没有实际意义,可不要)
	pNew=(struct student*)malloc(sizeof(struct student));  //为新节点开辟内存
	printf("姓名 学号:");
	scanf("%s %f",&pNew->name,&pNew->number);  //输入新数据
	pNew->pNext=pHead->pNext;  //让新节点的pNext指针指向头节点的pNext
	pHead->pNext=pNew;  //让头节点的pNext指向新节点
	len+=1;  //长度加1
	return pHead;  //返回头节点
}

2.在链表末尾加入
这个同样非常简单,方法就是先创建一个结构体指针(*tep)和新节点(*pNew),先输入新节点的数据,接着让 tep指向头节点,然后让 tep类似于遍历时那样一路往下指,直到 tep指向了最后一个节点为止, 最后让 *tep的pNext指向新节点,新节点的pNext等于NULL就可以啦

struct student *addend(struct student *pHead){  //加入函数,传入头节点
	struct student *tep,*pNew;  //一个用来指向原链表最后一个节点的结构体指针(*tep)和新节点(*pNew)
	pNew=(struct student*)malloc(sizeof(struct student));  //为新节点开辟内存
	tep=pHead;  //让tep指向头节点用来找原链表的最后一个节点
	printf("姓名 学号:");
	scanf("%s %f",&pNew->name,&pNew->number);  //输入新数据
	pNew->pNext=NULL;  //新节点的pNew指向NULL
	/*当tep的pNext不是NULL是,tep指向tep的下一个节点,直到tep的pNext是NULL*/
	while(tep->pNext!=NULL){
		tep=tep->pNext;
	}
	tep->pNext=pNew;  //原链表的最后一个节点的pNext指向新节点
	len+=1;  //长度加1
	return pHead;  //返回头节点
}

3.指定位置加入
这个就稍微多一些,加入方法就是先创建两个结构体指针( *pBefore和 *p)还有一个新节点(*pNew),一个要加入的位置数据(int location)和记录长度数据(int n=2)
先说指针部分,第一个指针pBefore是用来指向pHead的指针,至于before是在另一个指针p之前的意思,那么,第二个指针p就是pBefore的pNext所指向的节点,这样做,是为了能让新节点能够加入到两个相邻节点之间(不是头节点后,也不是末尾位置),加入方式和加入头节点后的方法一样,首先让新节点的pNext指向pBefore的pNext,然后再让pBefore的pNext指向新节点,这样,就完成了在两个相邻节点之间加入,这里只是把pBefore的pNext换成了p
然后就是那两个整形了,location是你要加入的位置,n就是去寻找那个位置,那为什么等于2?原因是当n=1的时候所加入的数据会是你输入的位置的下一位,比如你想要加入到第3个位置,如果n=1,那实际加入的位置就是4,所以n=2,从2开始

struct student *addlocation(struct student *pHead){  //加入函数,传入头节点
	struct student *pBefore,*p,*pNew;  //一个用于指向头节点的指针(*pBefore)和一个头节点下一个节点的指针(*p),还有一个新节点(*pNew)
	p=pHead->pNext;  //p指向头节点的下一个节点
	pBefore=pHead;  //pBefore指向头节点
	int location,n=2;  //要加入的指定位置(location)和用于寻找位置(n=2)的整形
	pNew=(struct student*)malloc(sizeof(struct student));  //为新节点开辟内存
	printf("姓名 学号:");
	scanf("%s %f",&pNew->name,&pNew->number);  //输入新数据
	printf("要加入的位置:");
	scanf("%d",&location);  //输入要加入的位置
	/*当要加入的位置是1时,直接让新节点的pNext指向头节点,然后返回pNew*/
	if(location==1){
		pNew->pNext=pHead;
		len+=1;  //长度加1
		return pNew;
	}
	/*当要加入的位置是末尾时,请参考上面的第二种加入方法*/
	if(location==(len+1)){
		while(p->pNext!=NULL){
			p=p->pNext;
		}
		pNew->pNext=NULL;
		p->pNext=pNew;
		len+=1;  //长度加1
		return pHead;
	}
	/*当要加入的位置不是开头和结尾时*/
	else{
	/*用n去寻找location是哪个位置*/
		while(n!=location){
			n++;
			p=p->pNext;  //让p指向p的下一个节点
			pBefore=pBefore->pNext;  //让pBefore指向pBefore的下一个节点
		}
	/*找到要加入的位置后*/	
		pNew->pNext=p;  //让新的节点指向相邻节点的后一个节点
		pBefore->pNext=pNew;  //让相邻节点的前一个节点指向新节点
		len+=1;  //长度加1
		return pHead;  //返回头节点
	}
}

删除

最后一个,如何在操作过程中删除某一个节点,同样也要去寻找位置,方法类似于加入方法的第三个,所以,现在来说说如何删除
删除的方法就是让被删除的上一个节点的pNext指向被删除的下一个节点然后将其free掉,两个指针一个before(等同于上面的pBefore),一个search(等同于上面的p),这里的search就是要被free的节点

struct student *del(struct student *pHead){  //删除函数,传入头节点
   /*指针和整形数据类似于加入方法第三个*/
	struct student *before,*search;  //search是要被释放的节点,before是被释放节点的前一个
	int lead,i=2;
	before=pHead;
	search=pHead->pNext;
	printf("输入要删除的位置:");
	scanf("%d",&lead);
	/*寻找方式一样*/
	while(1){
		if(lead==1){
			len--;
			return search;
		}
		if(i==lead){
			before->pNext=search->pNext;  //before的pNext跳过search指向search的下一个节点(search的pNext)
			free(search);  //释放
			break;
		}
		i++;
		before=before->pNext;  //让before等于它下一个节点
		search=search->pNext;  //让search等于它下一个节点
	}
	len--;  //长度减1
	return pHead;  //返回头节点
}

完整代码

#include <stdio.h>
#include <stdlib.h>
int len; //链表长度
struct student{
	char name[30];
	float number;
	struct student *pNext;
};
/*创建*/ 
struct student *create(){
	struct student *pHead=NULL;
	struct student *pNew,*pEnd;
	pNew=pEnd=(struct student*)malloc(sizeof(struct student));
	printf("名字 学号:");
	scanf("%s %f",&pNew->name,&pNew->number);
	while(pNew->number!=0){
		len++;
		if(len==1){
			pNew->pNext=NULL;
			pEnd=pNew;
			pHead=pNew;
		}
		else{
			pNew->pNext=NULL;
			pEnd->pNext=pNew;
			pEnd=pNew;
		}
		pNew=(struct student*)malloc(sizeof(struct student));
		scanf("%s %f",&pNew->name,&pNew->number);
	}
	free(pNew);
	return pHead;
}
/*头表后加入*/
struct student *addah(struct student *pHead){
	struct student *pNew,*tep;
	pNew=(struct student*)malloc(sizeof(struct student));
	printf("姓名 学号:");
	scanf("%s %f",&pNew->name,&pNew->number);
	pNew->pNext=pHead->pNext;
	pHead->pNext=pNew;
	len+=1;
	return pHead;
}
/*加入结尾*/ 
struct student *addend(struct student *pHead){
	struct student *tep,*pNew;
	pNew=(struct student*)malloc(sizeof(struct student));
	tep=pHead;
	printf("姓名 学号:");
	scanf("%s %f",&pNew->name,&pNew->number);
	pNew->pNext=NULL;
	while(tep->pNext!=NULL){
		tep=tep->pNext;
	}
	tep->pNext=pNew;
	len+=1;
	return pHead;
}
/*指定位置删除*/ 
struct student *del(struct student *pHead){ 
	struct student *before,*search; 
	int lead,i=2;
	before=pHead;
	search=pHead->pNext;
	printf("输入要删除的位置:");
	scanf("%d",&lead);
	while(1){
		if(lead==1){
			len--;
			return search;
		}
		if(i==lead){
			before->pNext=search->pNext; 
			free(search);  
			break;
		}
		i++;
		before=before->pNext;
		search=search->pNext;
	}
	len--;  
	return pHead;
}
/*指定位置加入*/ 
struct student *addlocation(struct student *pHead){
	struct student *pBefore,*p,*pNew;
	p=pHead->pNext;
	pBefore=pHead;
	int location,n=2;
	pNew=(struct student*)malloc(sizeof(struct student));
	printf("姓名 学号:");
	scanf("%s %f",&pNew->name,&pNew->number);
	printf("要加入的位置:");
	scanf("%d",&location);
	if(location==1){
		pNew->pNext=pHead;
		len+=1;
		return pNew;
	}
	if(location==(len+1)){
		while(p->pNext!=NULL){
			p=p->pNext;
		}
		pNew->pNext=NULL;
		p->pNext=pNew;
		len+=1;
		return pHead;
	}
	else{
		while(n!=location){
			n++;
			pBefore=pBefore->pNext;
		}
		pNew->pNext=pBefore->pNext;
		pBefore->pNext=pNew;
		len+=1;
		return pHead;
	}
}
/*遍历*/ 
void print(struct student *pHead){
	struct student *tep;
	int i=1;
	tep=pHead;
	printf("----------共%d个成员----------\n",len);
	while(tep!=NULL){
		printf("No.%d名字:%s\n",i,tep->name);
		printf("学号:%g\n\n",tep->number);
		i++;
		tep=tep->pNext;
	}
	printf("\n\n");
}
int main(){
	struct student *pHead;
	pHead=create();
	print(pHead);
	pHead=addah(pHead);
	print(pHead);
	pHead=addend(pHead);
	print(pHead);
	pHead=addlocation(pHead);
	print(pHead);
	pHead=del(pHead);
	print(pHead);
}
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值