C语言试题——单向链表的创建和使用

题目如下所示

已知学生基本信息由学号(长整型)、姓名(字符数组)、性别(字符型)、年龄(整型)组成。定义如下结构类型:

// 定义结构体:存储学生基本信息
struct STUDENT_NODE {
long int id;
char name[MAX_LEN];
char sex;
int age;
// 指针指向下一个结点,用以形成链表
STUDENT_NODE *next;
};
//定义结构体:存储单向链表
struct STUDENT_LINK{
STUDENT_NODE *top;
};
应用上述结构类型,编程实现:建立一个结点按学号顺序存储学生信息的单向链表,并实现依据学号对链表的添加、修改、删除和检索功能;添加新结点后,应继续保持结点按学号顺序的链接方式。分别定义函数实现链表的初始化、链表的打印输出、以及在链表中添加、修改、删除和检索节点的功能;最后在main()中进行测试输出。

代码如下所示

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 50

// 定义结构体:存储学生基本信息
typedef struct STUDENT_NODE {
	long int id;
	char name[MAX_LEN];
	char sex;
	int  age;
    // 指针指向下一个结点,用以形成链表
	struct STUDENT_NODE *next;
}STUDENT_NODE;

//定义结构体:存储单向链表
typedef struct STUDENT_LINK{
	STUDENT_NODE *top;
}STUDENT_LINK;

void iniStudentLink(STUDENT_LINK * L); //初始化学生链表
void clearStudentLink(STUDENT_LINK * L);//清空学生链表
int isExist(STUDENT_LINK * L, long int id); //判断该学号的学生信息是否存在
int Add(STUDENT_LINK * L,long int id,char name[],char sex, int age); //添加一个新同学的信息
void ShowALL(STUDENT_LINK * L);           // 从头到尾,输出当前所有的同学信息
int Modify(STUDENT_LINK * L, long int id,char name[],char sex, int age);  // 根据学号,修改该同学的信息
int Delete(STUDENT_LINK * L, long int id); // 根据学号,从链表中删除该同学的信息
int Search(STUDENT_LINK * L,long int id);  // 根据学号,输出显示该同学信息

int main(){
	STUDENT_LINK * L;
	long int id;
	char name[MAX_LEN];
	char sex;
	int  age;
	
	iniStudentLink(L);//初始化学生链表
	ShowALL(L);//从头到尾,输出当前所有的同学信息
	
	/*添加一个新同学的信息*/ 
	printf("\n以下尝试添加一个新同学的信息\n");
	
	printf("学号:");
	scanf("%ld", &id);
		
	printf("姓名:");
	scanf("%s", &name);
		
	getchar();
	printf("性别(女为w男为m):");
	scanf("%c", &sex);
		
	printf("年龄:");
	scanf("%d", &age);
	Add(L, id, name, sex, age);
	
	ShowALL(L);//从头到尾,输出当前所有的同学信息
	
	/*修改一个同学的信息 */
	printf("\n以下尝试修改一个同学的信息\n");
	
	printf("学号:");
	scanf("%ld", &id);
		
	printf("姓名:");
	scanf("%s", &name);
		
	getchar();
	printf("性别(女为w男为m):");
	scanf("%c", &sex);
		
	printf("年龄:");
	scanf("%d", &age);
	Modify(L, id, name, sex, age);
	
	ShowALL(L);//从头到尾,输出当前所有的同学信息
	
	/*显示一个同学的信息*/ 
	printf("\n请输入想要显示信息的同学学号:\n");
	scanf("%ld", &id);
	Search(L, id);
	
	/*删除一个同学的信息*/
	printf("\n请输入想要删除信息的同学学号:\n");
	scanf("%ld", &id);
	Delete(L, id);
	
	ShowALL(L);//从头到尾,输出当前所有的同学信息
	
	clearStudentLink(L);//清空学生链表
	return 0; 
}

void iniStudentLink(STUDENT_LINK * L){//初始化学生链表
	int n,i;
	printf("请初始化学生数量:");
	scanf("%d", &n);
	
	STUDENT_NODE *head = NULL;//初始化头指针为空 
	for(i=0; i<n; i++){
		//申请一块空间存储当前学生的信息 
		STUDENT_NODE *p = (STUDENT_NODE*)malloc(sizeof(STUDENT_NODE));
		
		printf("请输入第%d个学生信息\n", i+1);
		printf("学号:");
		scanf("%ld", &p->id);
		
		printf("姓名:");
		scanf("%s", &p->name);
		
		getchar();
		printf("性别(女为w男为m):");
		scanf("%c", &p->sex);
		
		printf("年龄:");
		scanf("%d", &p->age);
		
		p->next = NULL;
		STUDENT_NODE *last = head;//使末指针初始化等同于头指针 
		if(last){//如果末指针不为空 
			while(last->next){//找到链表末尾 
				last = last->next;
			}
			last->next = p;//将新结点链在末尾处 
		}
		else{//如果末指针为空 
			head = p;//使头指针指向当前空间
		}
	}
	
	//下面对该链表按学号由小到大排序 
	STUDENT_NODE *pre, *a;
	
    pre = head;//一开始指向头部 
    while (pre->next != NULL)
    {
        a = pre->next;//a指向pre的下一个节点 
        while (a != NULL)
        {
            if (pre->id > a->id)//如果本轮最前端的学号大于于此节点中的学号
            {
            	//互换他们的学号和各项信息 
                int n = pre->id;       
                char na[MAX_LEN];
                strcpy(na, pre->name);
				char se = pre->sex;
				int  ag = pre->age;
                
                pre->id = a->id;
				strcpy(pre->name, a->name);
                pre->sex = a->sex;
                pre->age = a->age;
                
                a->id = n;
                strcpy(a->name, na);
                a->sex = se;
                a->age = ag;
            }
            a = a->next;//使a指向下一个节点 
        }
        pre = pre->next;//使pre指向下一个节点 
    }
	
	L->top = head;
}

void clearStudentLink(STUDENT_LINK * L){//清空学生链表
	STUDENT_NODE *p, *q;

	for(p=L->top; p; p=q){//遍历整个链表 
		q = p->next;
		free(p);//释放当前结点 
	}
}

int isExist(STUDENT_LINK * L, long int id){//判断该学号的学生信息是否存在
	
	STUDENT_NODE *p, *q;
	int flag = 0;
	
	for(p=L->top; p; p=q){//遍历整个链表 
		q = p->next;
		if(p->id == id){
			flag = 1;
			break;
		}
	}
	
	return flag;
} 

int Add(STUDENT_LINK * L,long int id,char name[],char sex, int age){//添加一个新同学的信息

	if(isExist(L, id)){
		printf("已有该同学的信息!\n"); 
	}
	else{
		//申请一块新的空间,把该同学的各项信息存进去 
		STUDENT_NODE *p = (STUDENT_NODE*)malloc(sizeof(STUDENT_NODE));
		p->id = id;
		p->sex = sex;
		p->age = age;
		strcpy(p->name, name);
		
		STUDENT_NODE *r, *q;
		int flag = 0;
		
		for(r=L->top; r; r=q){//遍历整个链表 
			q = r->next;
			if(r == L->top){//如果当前为链表头部 
				if(r->id > p->id){
					L->top = p;
					p->next = r;
					break;
				} 
			}
			if(q != NULL){//如果没到链表末尾 
				if(q->id > p->id){//如果下一位同学的学号大于新同学的学号 
					r->next = p;//将新同学结点链在当前同学后 
					p->next = q;
					break;
				}
			}
			else{
				r->next = p;
				p->next = NULL; 
			}	
		}
		printf("成功添加学生信息!\n");
	}
}

void ShowALL(STUDENT_LINK * L){//从头到尾,输出当前所有的同学信息
	STUDENT_NODE *p, *q;
	printf("\n所有同学的各项信息如下:\n");
	for(p=L->top; p; p=q){//遍历整个链表 
		q = p->next;
		printf("学号:%ld 姓名:%s 性别:%c 年龄:%d\n",p->id,p->name,p->sex,p->age);
	}
}

int Modify(STUDENT_LINK * L, long int id,char name[],char sex, int age){//根据学号,修改该同学的信息
	STUDENT_NODE *p, *q;

	for(p=L->top; p; p=q){//遍历整个链表 
		q = p->next;
		if(p->id == id){
			strcpy(p->name, name);
			p->sex = sex;
			p->age = age;
			printf("\n修改成功!\n");
				
			return 1;
		}
	}
	printf("没有该同学的信息!\n");
	
	return 0;
}

int Delete(STUDENT_LINK * L, long int id){ // 根据学号,从链表中删除该同学的信息
	STUDENT_NODE *p, *q, *r;

	for(p=L->top; p; r=p, p=q){//遍历整个链表 
		q = p->next;
		if(p == L->top){//如果当前为链表头部 
			if(p->id == id){
				L->top = q;
				free(p);
				printf("删除成功!\n");
				return 1;
			}
		}
		else{
			if(p->id == id){
				r->next = q;
				free(p);
				printf("删除成功!\n"); 
				return 1;
			}
		}
		;
	}
	
	printf("没有该同学的信息!\n");
	return 0;
} 

int Search(STUDENT_LINK * L,long int id){// 根据学号,输出显示该同学信息
	STUDENT_NODE *p, *q;

	for(p=L->top; p; q=p->next, p=q){//遍历整个链表 
		if(p->id == id){
			printf("\n输出该同学的信息如下所示\n");
			printf("学号:%ld 姓名:%s 性别:%c 年龄:%d\n",p->id,p->name,p->sex,p->age);
			return 1;			
		}
	}
	
	printf("没有该同学的信息!\n"); 
	return 0;
}
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值