大一C语言自主实验_链表

(一)
程序功能:建立一个单向链表,头指针是list,链表中每个结点包含姓名、基本工资信息,编写一个max_list函数查找链表中最高基本工资的职工信息。要求在主函数中建立单向链表(注:当输入基本工资为0时,表示输入结束。),然后调用max_list函数查找链表中最高基本工资的职工信息,最后输出查找结果。提示:除在指定位置添加语句之外,请不要改动程序中的其他内容。   

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

struct emp_node{                 /*定义职工工资结点*/
       char   name[20];          /*姓名*/
       int    salary;            /*基本工资*/
       struct emp_node *next;    /*结点指针*/
};

int size=sizeof(struct emp_node);/*结点大小*/

int main()
{
       struct emp_node *list,*p1=NULL,*p2=NULL,*p=NULL;
       char name[20];
       int salary,n=0;   /*n: 职工人数计数器*/
       struct emp_node * max_list(struct emp_node *list);   /*函数声明*/

       /*建立新链表list*/
          /**********************************************************************/
       list=NULL;  /*链表初始化为空表*/

       /*输入若于个职工数据*/
       printf("请输入职工姓名和基本工资: \n");
       scanf("%s%d",name,&salary);
       while(salary!=0)
       {
           n++;        /*人数计数*/

           /*申请新结点,并链入链表尾*/
           p1=(struct emp_node *)malloc(size);
           strcpy(p1->name,name);p1->salary=salary;p1->next=NULL;
           if(n==1)list=p1;    else p2->next=p1;
           p2=p1;

           /*输入下一个职工数据*/
           scanf("%s%d",name,&salary);
       }
          /**********************************************************************/

       /*在两条星线间填入相应代码, 调用max_list函数查找链表中最高基本工资结点*/
       /**********************************************************************/
       p=max_list(list);
       /**********************************************************************/
       
       /*输出查找结果*/
       printf("最高基本工资的职工信息:\n");
       printf("姓名:%s   基本工资:%d\n",p->name,p->salary);

       return 0;
}

/*功  能:在list链表中查找最高基本工资结点                       */
/*参  数:list—指针变量,指向实参链表头                         */
/*返回值:返回最高基本工资结点指针                                 */
struct emp_node * max_list(struct emp_node *list)
{
       struct emp_node *max_p;      /*max_p:指向最高基本工资结点
    
       /*在两条星线间填入相应代码, 查找链表中最高基本工资的职工信息*/
       /************************************************************/
       max_p=list;
       while(list!=NULL)
       {
           if(list->salary>max_p->salary)max_p=list;
           list=list->next;
       }
       /************************************************************/
       
       return max_p;    /*返回结果*/
}

(二)
【独立编程】程序功能:建立头指针是list 的职工单向链表,链表结点包含姓名、工资,输出链表中超过平均工资的人数。要求如下:
①定义countList()函数:统计并返回链表中超过平均工资的人数。
②定义main()函数:建立职工单向链表 list(注:工资为 0,结束输入),调用 countLisro 两数统计并返回链表中超过平均工资的人数,输出统计结果
题目要求:
(1)编程实现程序功能,然后以 pro9_2.c 为文件名保存在“第2题” 文件夹。
【提示】阅读并理解第1题的解题思路和程序,思考以下问题。
①本题采用多函数结构,包括countList0两数和main0两数。
②countlist()函数:从链表头开始,遍历链表计数链表中超过平均工资的结点个数,直 到链表结束 ③main()函数:建立职工单向链表 list,调用 countList()函数统计并返回链表中超过平均 工资的人数,输出统计结果。
(2)调试、运行程序,并给出运行结果。

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

/*定义职工工资结点*/
struct emp_node{                 
       char   name[20];          /*姓名*/
	   int    salary;            /*基本工资*/
	   struct emp_node *next;    /*结点指针*/
};

int size=sizeof(struct emp_node);/*结点大小*/

int main()
{
	struct emp_node *list,*p1=NULL,*p2=NULL,*p=NULL;
	char name[20];
	int salary,n=0,count,sum=0;  /*n:职工人数,count:超过平均基本工资人数,sum:总工资*/
    int count_list(struct emp_node *list,int avg);  /*函数声明*/

	/*建立新链表list*/
   	/*********************************************************/
	list=NULL;	  /*链表初始化为空表*/

	/*输入若干职工数据*/
	printf("请输入职工姓名和基本工资: \n");
	scanf("%s%d",name,&salary);
	while(salary!=0)
	{
		/*累加总人数和总工资*/
		n++;
		sum=sum+salary;  

		/*申请新结点,并添加在链表尾*/
	    p1=(struct emp_node *)malloc(size);
		strcpy(p1->name,name);p1->salary=salary;p1->next=NULL;
		if(n==1)list=p1;else p2->next=p1;
		p2=p1;

		/*输入下个职工数据*/
		scanf("%s%d",name,&salary);
	}
   	/*********************************************************/

	/*调用count_list函数统计链表中超过平均基本工资的人数*/
    count=count_list(list,sum/n);

	/*输出结果*/
	printf("平均基本工资:%d\n",sum/n);
	printf("超过平均基本工资的人数:%d\n",count);

	return 0;
}

/*功  能:在list链表中统计超过平均基本工资的人数				 */
/*参  数:list—指针变量,指向实参链表头;	avg—平均基本工资	 */
/*返回值:返回超过平均基本工资的人数		                     */
int count_list(struct emp_node *list,int avg)
{
	int count;   /*超过平均基本工资人数计数器*/
    
	/*遍历链表list,统计链表中超过平均基本工资的人数*/
	count=0;
	while(list!=NULL)
	{
		if(list->salary>avg)count++;
		list=list->next;
	}
	
	return count;	/*返回结果*/
}

(三)
【独立编程】程序功能:建立头指针是list职工单向链表,链表结点包含姓名、工资,删除链表中指定工资的所有结点,输出删除后的链表信息。要求如下:
①定义delList()函数:删除链表中指定工资的所有结点。
2定义main()函数:建立职工单向链表list(注:工资为0,结束输入),调用delList函数删除链表中指定工资的所有结点,输出删除后的链表信息。
题目要求:
(1)编程实现程序功能,然后以pro9_3.c为文件名保存在“第3题”文件夹。
【提示】阅读并理解第1题的解题思路和程序清单,思考以下问题。
①本题采用多函数结构,包括delList()函数和main()函数。
②delList()函数:从链表头开始,遍历链表删除链表中指定工资的所有结点,直到链表结束。③main()函数:建立职工单向链表list,调用delList()函数删除链表中指定工资的所有结点,输出删除后的链表信息。
(2)调试、运行程序,并给出运行结果。

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

/*定义职工工资结点*/
struct emp_node{                 
       char   name[20];          /*姓名*/
	   int    salary;            /*基本工资*/
	   struct emp_node *next;    /*结点指针*/
};

int size=sizeof(struct emp_node);/*结点大小*/

int main()
{
	struct emp_node *list,*p1,*p2;
	char name[20];
	int salary,n=0;
    struct emp_node * delList(struct emp_node *list,int salary);   /*函数声明*/

	/*建立新链表list*/
   	/*********************************************************/
	list=NULL;	  /*链表初始化为空表*/

	printf("请输入职工姓名和基本工资: \n");
	scanf("%s%d",name,&salary);
	while(salary!=0)
	{
		n++;  /*累加人数*/

		/*申请新结点,并将新结点插入链表尾*/
	    p1=(struct emp_node *)malloc(size);
		strcpy(p1->name,name);p1->salary=salary;p1->next=NULL;
		if(n==1)list=p1;
		else p2->next=p1;
		p2=p1;

		/*输入下一个职工数据*/
		scanf("%s%d",name,&salary);
	}
   	/*********************************************************/

	/*输入要删除的给定基本工资*/
	printf("请输入某给定基本工资: \n");
	scanf("%d",&salary);

	/*调用delList函数,删除链表中等于给定基本工资的所有结点*/
    list=delList(list,salary);

	/*输出删除后的链表信息*/
	printf("删除后的链表信息:\n");
	while(list!=NULL){
		printf("姓名:%s,  基本工资:%d\n",list->name,list->salary);
		list=list->next;
	}

	return 0;
}

/*功  能:删除list链表中等于给定基本工资的所有结点				 */
/*参  数:list—指针变量,指向实参链表头;	salary—基本工资	 */
/*返回值:返回链表头指针					                     */
struct emp_node * del_list(struct emp_node *list,int salary)
{
    struct emp_node *p1,*p2;

	if(list==NULL){					/* 链表为空链表 */
		printf("空链表,无删除结点!\n");
		return;
	}

	/* 遍历链表,删除链表中满足条件的表头结点 */
	while(list!=NULL && list->salary==salary){    
		p2=list;
		list=list->next;
		free(p2);
	}

	/* 遍历链表,删除链表中满足要求的非表头结点 */
	p1=list;p2=list->next;		/* 设置p1是p2的前趋结点 */
	while(p2!=NULL)				
	{
		if(p2->salary==salary)	/* p2所指结点符合删除条件 */
		{
			p1->next=p2->next;
			free(p2);
		}
		else p1=p2;      /* p1后移一个结点 */

		p2=p1->next;     /* p2指向p1的后一个结点 */
	}

	return list;		 /* 返回链表头指针 */
}

(四)
【独立编程】程序功能:建立两个按工资升序的职工单向链表list1和list2,链表结点包含姓名、工资,要求将两个链表归并成一个按工资升序排序的新链表,输出新链表信息。要求如下:
①定义mergeList()函数:将两个链表归并成一个按工资升序排序的新链表。
②定义main()函数:建立两个按工资升序的职工单向链表list1和list2(工资为0,结束输入),调用mergeList()函数将两个链表归并成一个按工资升序排序的新链表,输出新链表信息。
题目要求:
(1)编程实现程序功能,然后以pro9_4c为文件名保存在“第4题”文件夹。
【提示】阅读并理解第1题的解题思路和程序清单,思考以下问题。
①本题采用多函数结构,包括mergeList()函数和main()函数。
②mergeList()函数:将两个链表归并成一个按工资升序排序的新链表。
③main()函数:建立两个按工资升序的职工单向链表list1和list2(工资为0,结束输入)调用mergeList0函数将两个链表归并成一个按工资升序排序的新链表,输出新链表信息。

版本一

/*功能:输入若干学生成绩(输入-1为结束标志),建立两个按成绩升序的单向链表list1和list2,要求*/
/*      定义mergeList()函数,实现将两个链表拼成一个按成绩升序的新链表,输出新链表信息。		*/

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


struct score_node{					/*定义学生成绩结点*/             
	   int    mark;					/*成绩*/
	   struct score_node *next;		/*结点指针*/
};

int size=sizeof(struct score_node);	/*结点大小*/

int main()
{
	int n,mark;
	struct score_node *list1,*list2,*list,*p1,*p2;
	struct score_node * mergeList(struct score_node * list1,struct score_node * list2);	/* 函数声明 */
	
	/*建立新链表list1*/
   	/*********************************************************/
	list1=NULL;	  /*链表初始化为空表*/
	n=1;
	printf("请输入一班学生成绩: \n");
	scanf("%d",&mark);
	while(mark!=-1)
	{
		/*申请新结点并插入到链表尾*/
	    p1=(struct score_node *)malloc(size);
		p1->mark=mark;p1->next=NULL;
		if(n==1)list1=p1;
		else p2->next=p1;
		p2=p1;
		n++;

		/*输入下一个学生数据*/
		scanf("%d",&mark);
	}
   	/*********************************************************/

	/*建立新链表list2*/
   	/*********************************************************/
	list2=NULL;	  /*链表初始化为空表*/
	n=1;
	printf("请输入二班学生成绩: \n");
	scanf("%d",&mark);
	while(mark!=-1)
	{
		/*申请新结点并插入到链表尾*/
	    p1=(struct score_node *)malloc(size);
		p1->mark=mark;p1->next=NULL;
		if(n==1)list2=p1;
		else p2->next=p1;
		p2=p1;
		n++;

		/*输入下一个学生数据*/
		scanf("%d",&mark);
	}
   	/*********************************************************/

	list=mergeList(list1,list2);   /* 调用函数mergeList()拼接链表list1和list2 */
 
	/* 输出拼接后的新链表list */
	if(list==NULL) printf("\n拼接后的新链表是空链表!\n");
	else{
		printf("\n拼接后的新链表信息: \n");
		while(list!=NULL){
			printf("%d\n",list->mark);
			list=list->next;
		}
	}

	return 0;
}

/*功  能:拼接链表list1和list2,产生升序排列的新链表list		                */
/*参  数:list1、list2—指针变量,指向两个实参链表头			                */
/*返回值:返回新链表头指针					                                    */
struct score_node * mergeList(struct score_node * list1,struct score_node * list2)
{
	int n;
	struct score_node *list,*p1,*p2,*p,*q,*r;

	/*拼接链表list1和list2,产生升序排列的新链表list*/
	list=NULL;				/* 新链表list初值为NULL */
	p1=list1;p2=list2;n=0;	/* 初始化p1和p2         */

	while((p1!=NULL)&&(p2!=NULL))	/* 两链表都非空 */
	{
	    p=(struct score_node *)malloc(size);	/* 申请新结点p */

		if(p1->mark<p2->mark){                  /* 复制p1结点  */
			p->mark=p1->mark;
			p1=p1->next;
		}
		else{
			p->mark=p2->mark;                   /* 复制p2结点  */
			p2=p2->next;
		}

		/* 链入新结点p */
		if(n==0)list=p;
		else q->next=p;

		q=p;									/* 指针q指向尾结点 */
		n++;									/* 结点个数加1 */
	}
 
	/* 拼接未拼接完的list1或list2 */
	if(p1!=NULL)r=p1;
	else r=p2;
	while(r!=NULL)
	{
	    p=(struct score_node *)malloc(size);
		p->mark=r->mark;p->next=NULL;
		if(n==1)list=p;
		else q->next=p;
		q=p;
		n++;
		r=r->next;
	}

	return list;	/* 返回新链表头指针list */
}


版本二

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct student
{
	char name[20];	/* 我增加的语句 */
	int score;
	struct student *next;
};

struct student *input()
{
	struct student *head=NULL,*p1,*p2=NULL;
	char name[20];
	int score,n=0;
	printf("输入学生的姓名和成绩(成绩为-1表示输入结束):\n");
	scanf("%s%d",name,&score);
	while(score!=-1)
	{
		n++;
		if((p1=( struct student *)malloc(sizeof(struct student)))==NULL)
		{
			printf("无法分配储存空间.\n");
			exit(0);
		}
		strcpy(p1->name,name);
		p1->score=score;
		p1->next=NULL;

		if(n==1) head=p1; 
		else p2->next=p1;
		p2=p1;
		scanf("%s%d",name,&score);
	}
	
	return head;
}

struct student *merge(struct student *x, struct student *y)
{
	struct student* ret=NULL,*tail=NULL,*temp=NULL;//ret始终指队头,tail始终指队尾,temp存储个体

	while(x!=NULL&&y!=NULL)
	{
		if(x->score<y->score)
		{
			temp=x->next;
			if(ret==NULL)
			{
				ret=tail=x;
				ret->next=NULL;
			}
			else {

				tail->next=x;
				tail=tail->next;
				tail->next=NULL;
			}
			x=temp;
		}
		else{	
			temp=y->next;
			if(ret==NULL)
			{
				ret=tail=y;
				ret->next=NULL;
			}
			else {
				tail->next=y;
				tail=tail->next;
				tail->next=NULL;
			}
			y=temp;
		}
	}

	if(x!=NULL){
		tail->next=x;
	}
	else{
		tail->next=y;
	}

	return ret;

}

void  output( struct student *p)
{
	for(;p!=NULL;p=p->next)
	{
		printf("%s     %d\n",p->name,p->score);
	}

}

void  freelink( struct student *p)	/* 释放链表空间 */
{
	struct student *temp;
	for(;p!=NULL;)
	{
		temp=p;
		p=p->next;
		free(temp);			/* 释放temp结点 */
	}
}

int main()
{
	struct student *list1=NULL,*list2=NULL,*list=NULL;
	struct student *input();
	void  output( struct student *p);
	struct student *merge( struct student *x, struct student *y);

	printf("输入俩个升序排序的链表,以成绩为-1为结束标志");
	list1=input();			//得到俩个链表的队头list1和list2
	list2=input();

	list=merge(list1,list2);//俩个链表用归并排序合成一个升序链表并返回队头

	output(list);			//输出链表

	freelink(list);			//释放链表空间

	return 0;
}

版本三

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct student
{
	char *name;
	int score;
	struct student *next;
};

struct student *input()
{
	struct student *head=NULL,*p1,*p2=NULL;
	char name[20];
	int score,n=0;
	printf("输入学生的姓名和成绩(成绩为-1表示输入结束):\n");
	scanf("%s%d",name,&score);
	while(score!=-1)
	{
		n++;
		if((p1=( struct student *)malloc(sizeof(struct student)))==NULL)
		{
			printf("无法分配储存空间.\n");
			exit(0);
		}
		p1->name=(char *)malloc(sizeof(name));
		strcpy(p1->name,name);
		p1->score=score;
		p1->next=NULL;

		if(n==1) head=p1; 
		else p2->next=p1;
		p2=p1;
		scanf("%s%d",name,&score);
	}
	
	return head;
}

struct student *merge(struct student *x, struct student *y)
{
	struct student* ret=NULL,*tail=NULL,*temp=NULL;//ret始终指队头,tail始终指队尾,temp存储个体

	while(x!=NULL&&y!=NULL)
	{
		if(x->score<y->score)
		{
			temp=x->next;
			if(ret==NULL)
			{
				ret=tail=x;
				ret->next=NULL;
			}
			else {

				tail->next=x;
				tail=tail->next;
				tail->next=NULL;
			}
			x=temp;
		}
		else{	
			temp=y->next;
			if(ret==NULL)
			{
				ret=tail=y;
				ret->next=NULL;
			}
			else {
				tail->next=y;
				tail=tail->next;
				tail->next=NULL;
			}
			y=temp;
		}
	}

	if(x!=NULL){
		tail->next=x;
	}
	else{
		tail->next=y;
	}

	return ret;

}

void  freelink( struct student *p)	/* 释放链表空间 */
{
	struct student *temp;
	for(;p!=NULL;)
	{
		temp=p;
		p=p->next;
		free(temp->name);	/* 释放name指向的动态空间 */
		free(temp);			/* 释放temp结点 */
	}
}

void  output( struct student *p)
{
	for(;p!=NULL;p=p->next)
	{
		printf("%s     %d\n",p->name,p->score);
	}

}

int main()
{
	struct student *list1=NULL,*list2=NULL,*list=NULL;
	struct student *input();
	void  output( struct student *p);
	void  freelink( struct student *p);
	struct student *merge( struct student *x, struct student *y);

	printf("输入俩个升序排序的链表,以成绩为-1为结束标志");
	list1=input();//得到俩个链表的队头list1和list2
	list2=input();

	list=merge(list1,list2);//俩个链表用归并排序合成一个升序链表并返回队头

	output(list);//输出链表

	freelink(list);

	return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值