数据结构
一.简介
偶然的机会,我看到了一道面试题,题目是这样规定的,写一个程序,用来存储学生的学号和成绩,并按分数从低到高排序,请用链表来实现。没有骗大家,这就是一道面试的笔试题,今天就给大家写一下,这道题挺好的,既考察了数据结构内容,又考察了排序算法
二.准备
- 我这边是用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 系统下写的,在程序结束时将我们的数据写到文件中,等再次进入,数据依然存在