创建a、b两个链表,每个链表的结点包含学生学号、姓名。从a链表中删去与b链表中有相同学号的那些结点。

1声明结构体类型

结构体类型struct Student,包含成员学生学号(整型)、姓名(字符数组),next(结构体指针)。声明全局变量n,用于统计结点数量。

struct Student//声明一个全局的结构体类型struct Student
{
	int num;    //学号 
	char name[20];//姓名 
	struct Student *next;//结构体指针,用于指向下一个结点
};

int n;//全局变量n,用于统计结点数量

2.创建链表

定义结构体指针变量

struct Student *p1,*p2,*head;//定义结构体指针p1、p2、head

 用malloc的开辟动态空间,输入结点的信息(学号、姓名),直到链表创建完成。

p2=p1=(struct Student *)malloc(sizeof(struct Student));//p1、p2指向新开辟的结点位置
scanf("%d",&p1->num);//输入学生学号
gets(p1->name);//输入学生姓名
if(n==1) head=p1;//当前结点为第一个结点时,头指针指向新开辟的结点
else p2->next=p1;//当前结点不为头结点时,结点成员next指向新开辟的结点 
p2=p1;//将p1赋给p2 ,p2也指向新开辟的结点 

3.查找两链表中有相同学号的结点

定义结构体指针变量和判断标志,统计a链表结点个数。

 struct Student *p1,*p2,*p3; //定义结构体指针p1、p2、P3
 int flag=0;                //定义判断学号相等的标志
 p1=pa_head;               //p1指向a链表表头 
 p2=pb_head;               //p2指向b链表表头
 while(p1!=NULL)           //统计a链表结点个数,当p1为空时结束 
 {   
	n=n+1;                  
	p1=p1->next;
 }

利用双层while循环,每选中a链表中的一个结点,b链表就从头结点开始遍历,比较两个结点中的学号。每找到相同学号的结点,就执行一次删除操作。

 p1=pa_head;            //p1重新指向a链表表头  
 while(p1!=NULL)        //外层a链表循环,当p1为空时结束 
 {
 	p2=pb_head;        //每次内循环开始前,p2重新指向b链表表头
 	while(p2!=NULL)    //内层b链表循环,当p2为空时结束
 	{
 		if(p1->num==p2->num)//当两链表结点成员学号相同 
 		{ 
 		    flag=1;   //判断标志置1 
 		    p3=p1;    //结构体指针p3保存当前结点位置 
 		    p1=p1->next;//指针变量p1指向a链表下一结点位置 
 			pa_head=delet_note(pa_head,p3);//调用删除链表结点的函数,参数为a链表头指针、指向删除结点的指针 
 			p3=NULL;   //执行删除操作后将结构体指针p3置空 
 			break;     //退出内循环 
		}
		else
		p2=p2->next;//p2指向b链表下一结点 
	}
	if(flag==1) flag=0;//判断标志置零,为下一次判断做准备 
	else p1=p1->next; //p1指向a链表下一结点 
  }

4.删除结点

定义结构体指针变量、相关整型变量,查询目标结点的序号(即第几个结点)。

	struct Student *head,*pt;//定义结构体指针head、pt 
	int j,m=0;                 //定义整型变量j、m,j用于循环,m用于判断删除结点的位置 
	pt=head=pa_head;         //head、pt初始化指向a链表表头                    
	while(pa_head!=NULL)     //查询目标结点位置 
	{   
	    m=m+1;              //m自加1 
	    if(pa_head==p) break;//找到目标位置,退出循环 
		else pa_head=pa_head->next;//pa_head指向a链表下一结点 
	}

目标结点为头结点时

head=head->next;//将头指针指向原链表第二个结点
free((void *)pa_head);//释放原来表头结点占用的空间
pa_head=NULL;//将NULL赋给pa_head,防止p成为野指针

目标结点为其它结点时

for(j=1;j<m-1;j++) pt=pa_head=pa_head->next;//利用循环使pt、pa_head指向目标位置的前一个结点。
pt=pt->next;//pt指向目标位置的结点
pa_head->next=pt->next; //目标位置的前一个结点成员next指向目标位置的下一个结点
free((void *)pt);//释放删除结点占用的空间
pt=NULL;//将NULL赋给pt,防止pt成为野指针

5.输出链表

定义结构体指针指向头指针,利用循环依次输出链表结点。

	struct Student *p;//定义结构体指针p
	p=head;//结构体指针p指向头指针
	if(head!=NULL)//如果不是空链表 
	do
	{
	 printf("学号:%d\n",p->num);//输出学生学号、姓名 
	 printf("姓名:");
	 puts(p->name);//输出学生、姓名
	 p=p->next;	//p指向下一结点
	}while(p!=NULL); //当p=NULL输出完成

上述所有程序为部分代码,详情代码有偿,见链接。

https://item.taobao.com/item.htm?id=827901675197icon-default.png?t=N7T8https://item.taobao.com/item.htm?id=827901675197

6.运行结果

从键盘输入a、b链表结点信息(学生学号、姓名)

输出a、b链表 

输出新链表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值