单链表实现学生信息的存储与排序

数据结构

一.简介

偶然的机会,我看到了一道面试题,题目是这样规定的,写一个程序,用来存储学生的学号和成绩,并按分数从低到高排序,请用链表来实现。没有骗大家,这就是一道面试的笔试题,今天就给大家写一下,这道题挺好的,既考察了数据结构内容,又考察了排序算法

二.准备

  • 我这边是用C语言来写的
  • 编译的环境是在 VsCode之上
  • 我写在了一个.c文件里面了

三.程序

/*
   C语言编程
   简单的实现学生学号,号成绩的存储,这里才用链表的形式
   并将分数从低到高排序
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//定义枚举 用于成功和失败的判断,当然也可以直接用 0,和 1表示
enum judge
{
	ERROR = -1,
	OK,
};

//定义一个结构体来保存学生信息
struct students
{
   int num;
   float grade;
};
//类型的简化
typedef struct students ST;

//用一个结构体来表示链表的结点
struct list
{
   ST data;
   struct list *pNext;
};
typedef struct list LIST;

//创建链表的一个结点
LIST* creation();

//添加学生信息
int inputData(LIST* pList);

//查看学生的信息
int show(LIST* pList);

//学生信息排序
int sortList(LIST* pList, int n);

//销毁链表结点
void destory ( LIST* pList );

/* ==================== main =====================*/
int main()
{
  //定义一个指针变量
   LIST * pList = NULL; 
   pList = creation(); //得到链表的首地址
   if(NULL != pList)
   {
      printf("list creation OK\n");
   }

   // n 为需要添加学生的数量
   int n, i;
   printf("请输入添加学生的数量\n");
   scanf("%d",&n);
   for(i = 0; i < n; i++)
   {
      inputData(pList);
   }
   printf("%d 个学生信息添加已完成\n", n);
   show(pList);

   //排序
   sortList(pList,n);
   printf("********成绩由小到大排序******\n");
   show(pList);

   //销毁数据
   destory (pList);

   return 0;
}


/* ======================函数实现===================*/

//创建链表的一个结点
LIST* creation()
{
   //定义一个指针变量
   LIST *pList = NULL;
   pList = (LIST *) malloc(sizeof(LIST));
   //判断 初始化
   if(NULL == pList)
   {
      printf("malloc error\n");
      return NULL;
   }
   //申请内存成功 全部初始化为 0
   memset(pList, 0, sizeof(LIST));
   return pList;
}

//添加学生信息
int inputData(LIST* pList)
{
   //判断链表是否存在
   if( NULL == pList)
   {
      return ERROR;
   }
   //先创建一个新节点
   LIST* p = creation();
   if( NULL == p)
   {
      return ERROR;
   }
   //赋值
   printf("==请输入学生学号==\n");
	scanf("%d", &p->data.num);

	printf("==请输入学生成绩==\r\n");
	scanf("%f", &p->data.grade);

   //头插法插入节点
   p->pNext = pList->pNext;
   pList->pNext = p;
   printf("num=%d grade=%f 信息添加成功\n", p->data.num, p->data.grade);
   return OK;
}

//查看学生的信息
int show(LIST* pList)
{
   //判断链表是否存在,是否为空
	if ( NULL == pList 
	||   NULL == pList->pNext )
	{
		printf ("您还没有添加学生信息\n");
		return ERROR;
	}
   LIST *p = pList->pNext;
   while(NULL != p)
   {
      printf ( "学号:%d  成绩:%f\n", p->data.num, p->data.grade);
      //更新结点
      p = p->pNext;
   }
   return OK;
}

/*学生信息排序 这里采用冒泡排序的办法(我们只需要改变结点上的数据就可以了)
  按照成绩从低到高排序
*/
int sortList(LIST* pList, int n)
{
   //判断链表是否存在,是否为空
	if ( NULL == pList 
	||   NULL == pList->pNext )
	{
		printf ("您还没有添加学生信息\n");
		return ERROR;
	}
   LIST *p = pList->pNext;
   //排序
   int i,j;
   for(i = 0; i < n-1; i++)
   {
   	  //第一轮排完之后,让指针重新指向头结点
      p =  pList->pNext;
      for(j = 0; j < n-1-i; j++)
      {
         if(p->data.grade > p->pNext->data.grade)
         {
            //成绩
            float tmp1 = p->data.grade;
            p->data.grade =  p->pNext->data.grade;
            p->pNext->data.grade = tmp1;

            //学号
            int tmp2 = p->data.num;
            p->data.num =  p->pNext->data.num;
            p->pNext->data.num = tmp2;
         }
         p = p->pNext;
      }
   }
   return OK;
}

//销毁链表结点
void destory ( LIST* pList )
{
   if ( NULL == pList 
	||   NULL == pList->pNext )
	{
		free ( pList );
		pList = NULL;
		printf ( "您已经需销毁,无需重复操作!\n" );
		return ;
	}
   LIST *p = NULL;
	while ( NULL != pList->pNext )
	{
      //相当于头删
		p = pList->pNext;
		pList->pNext = p->pNext;
		//释放p
		free ( p );	
		p = NULL;
	}
	free ( pList );
	pList = NULL;
    printf ("学生信息已经全部销毁\n");
	return;
}

运行结果
在这里插入图片描述
主要看这里信息
在这里插入图片描述

四.总结

这里只是通过链表对数据的简单操作,包括数据的存储,和数据的排序,以及数据的读取

注意
这里的排序,第一次我想错了,想到交换每一个结点的连接顺序,通过改变链表的连接顺序来,实现data的有序输出,这样也是可以实现的,需要用到指针来保存地址,不过感觉太麻烦了。我们之间改变每一个结点上的数据域的值就可以,非常方便

在一个,这里只是一个对数据的简单的操作,我们都知道基本的操作包括数据的增删查改,但是当我们程序运行结束以后,重新打开终端,我们的数据是不存在的,这里给大家分享一下,我在linux 系统下写的,在程序结束时将我们的数据写到文件中,等再次进入,数据依然存在

商品信息管理系统

  • 9
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值