#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define NofsNumber 10 //学号设置最长为10个字符
#define NofName 10 //名字设置最长为10个字符
typedef int score_type; //分数的类型默认设置为unsigned char类型[0 , 255]
//线性表中每个节点的struct,包含 : 学号、名字、3科成绩加上一个平均成绩
typedef struct ElemType
{
char sNumber[NofsNumber];
char name[NofName];
score_type scores[4];
}ElemType;
//线性表struct
typedef struct List {
ElemType *list; /*存线性表元素的动态存储空间的指针*/
int len; /*保存线性表当前长度*/
int MaxSize; /*能存储的线性表的最大长度*/
}List;
//下面的各个函数不一一注释了,直接翻阅PPT对照即可
void InitList( List *L, int max_size);
void ClearList(List *L);
int SizeList(List *);
void GetElem(List *, int pos);
void TraverseList(List *);//输出表中所有的值
int FindList(List *, ElemType *);
int InsertPosList(List*,int,ElemType);//在pos位置插入一个节点
void printInfo();
void printNode(ElemType *);//打印输出节点的值
void InsertNode(List *);//插入一个节点
void getNode(ElemType *);//输入节点的信息
void SortList(List *);//线性表的排序,很重要
void InsertInitialNodes(List *);//插入初始的信息,5个同学
void printGua(List *);//输出至少挂了一科的同学
void printBigerThanX(List *);//输出平均成绩大于x的同学
int isSmaller(ElemType *p1 , ElemType *p2);
int main()
{
//定义一个线性表
ElemType node;
List mylist;
mylist.len = 0;
mylist.MaxSize = 0;
mylist.list = NULL;
InitList( &mylist, 4);
printInfo();
int p;
while(1)
{
printf("请输入指令 : ");
char select;
select = getchar();
switch(select)
{
case 'c'://清空
ClearList(&mylist);
printf("线性表已经清空!\n");
break;
case 's':
printf("线性表的长度是%d,容量是%d\n", mylist.len, mylist.MaxSize);
break;
case 'q'://退出
if(mylist.list != NULL)
{
free(mylist.list);
mylist.list = NULL;
}
printf("成功退出!\n");
return 0;
case 'g'://获取指定位置的元素
printf("\n请输入元素的位置:\n");
int pos;
scanf("%d", &pos);
GetElem(&mylist, pos);
break;
case 'i'://节点的插入
InsertNode(&mylist);
SortList(&mylist);
break;
case 't'://打印
TraverseList(&mylist);
break;
case 'f'://元素查找
getNode(&node);
p = FindList(&mylist, &node);
if(p == -1)
printf("未找到!\n");
else
printf("找到了,位置在%d\n",p);
break;
case 'x'://第3题的运行结果
printGua(&mylist);
break;
case 'y'://第4题的运行结果
printBigerThanX(&mylist);
break;
}
}
return 0;
}
void InitList( List *L, int max_size)
{
//线性表初始化函数
/*检查max_size是否有效,若无效则退出运行*/
if(max_size<=0) {printf(" max_size值非法!\n"); exit(1);}
/*置线性表空间大小为max_size*/
L->MaxSize=max_size;
/*动态存储空间分配,分配成功返回该内存地址,失败则返回NULL*/
L->list=(ElemType*)malloc(max_size*sizeof(ElemType));
if(!L->list) {
printf("动态存储分配失败!\n");
exit(1); /*执行此函数则中止程序运行,此函数在stdlib.h中有定义*/
}
/*初始置线性表为空*/
L->len=0;
InsertInitialNodes(L);
}
void InsertInitialNodes(List *L)
{
//插入默认的节点
ElemType *pNode = L->list;
//第一位同学
strcpy( pNode->name, "刘子祥"); strcpy(pNode->sNumber, "09");
pNode->scores[0] = 80;pNode->scores[1] = 85; pNode->scores[2] = 87; pNode->scores[3] = (80+85+87)/3;
//第二位同学
pNode = L->list + 1;
strcpy( pNode->name, "孟祥欣"); strcpy(pNode->sNumber, "05");
pNode->scores[0] = 81;pNode->scores[1] = 67; pNode->scores[2] = 74; pNode->scores[3] = (81+67+74)/3;
//第三位同学
pNode = L->list + 2;
strcpy( pNode->name, "谷红翠"); strcpy(pNode->sNumber, "03");
pNode->scores[0] = 70;pNode->scores[1] = 68; pNode->scores[2] = 57; pNode->scores[3] = (70+68+57)/3;
//第四位同学
pNode = L->list + 3;
strcpy( pNode->name, "王甜甜"); strcpy(pNode->sNumber, "01");
pNode->scores[0] = 52;pNode->scores[1] = 61; pNode->scores[2] = 52; pNode->scores[3] = (52+61+52)/3;
L->len = 4;
}
void ClearList(List *L)
{
//清空表,直接调用free函数
if(L->list != NULL)
{
free(L->list);
}
L->list = NULL;//防止二次释放
L->len = L->MaxSize = 0;
}
void GetElem(List *L, int pos)
{
if(L->list == NULL)
{
printf("表中无元素,请插入之后再访问!");
return;
}
//获取pos位置的元素
if(pos>=0 && pos < L->len)
{
ElemType *p = L->list + pos;
printf("第%d位置的信息为:\n", pos);
printNode(p);
}
else if(pos<=-1 && pos >= -L->len)//从后向前访问
{
ElemType *p = L->list + pos + L->len;
printf("第%d位置的信息为:\n", pos + L->len);
printNode(p);
}
else//无效
{
printf("索引无效!");
}
}
void getNode(ElemType *p)
{
//获取用户输入的节点信息,以空格分开,但是不用输入平均成绩
scanf("%s %s %d %d %d",p->sNumber, p->name, &p->scores[0], &p->scores[1], &p->scores[2]);
int sum = 0, i;
for(i = 0;i<3;++i)
sum += p->scores[i];
p->scores[3] = sum/3;
}
void reallocate(List *L, int new_size)
{
//重新分配内存
ElemType *p = (ElemType*)malloc(new_size*sizeof(ElemType));
if(p == NULL)
{
printf("动态存储分配失败!\n");
exit(1); /*执行此函数则中止程序运行,此函数在stdlib.h中有定义*/
}
//逐个复制到新的地方
int i;
for(i = 0;i< new_size ;++i)
{
p[i] = L->list[i];
}
free(L->list);
L->list = p;
L->MaxSize = new_size;
}
void copybackwward(List *L, int pos)
{
//从后向前挪,[pos, L->len)的元素向后挪一个
int i;
for(i = L->len-1; i>=pos;--i)
{
L->list[i+1] = L->list[i];
}
}
void InsertNode(List *L)
{
//节点的插入
//内存不够的话重新分配内存
//防止出现清空的情况
if(L->len == 0 && L->MaxSize == 0)
InitList(L, 100);
if(L->len == L->MaxSize)
reallocate(L, 2*L->MaxSize);
int pos;
printf("请输出插入节点的位置:\n");
scanf("%d", &pos);
//获取pos位置的元素
ElemType node;
if(pos>=0 && pos < L->len)
{
//向后拷贝,为新插入的节点挪挪地方
printf("请输入节点信息,从左往右依次为学号、姓名、3科成绩,以空格隔开:\n");
getNode(&node);
copybackwward(L, pos);
L->list[pos]= node;
printf("节点插入成功!\n");
L->len += 1;
}
else if(pos<=-1 && pos >= -L->len)//从后向前访问
{
//ElemType *p = L->list + pos + L->len;
printf("请输入节点信息,从左往右依次为学号、姓名、3科成绩,以空格隔开:\n");
getNode(&node);
copybackwward(L, pos + L->len);
L->list[pos + L->len] = node;
L->len += 1;
printf("节点插入成功!\n");
}
else if(pos==0 && pos == L->len)
{
//插入空表首部
printf("请输入节点信息,从左往右依次为学号、姓名、3科成绩,以空格隔开:\n");
getNode(&node);
//printf("插入空表\n");
L->list[0] = node;
L->len += 1;
printf("节点插入成功!\n");
//printNode(&node);
}
else if(pos== L->len)
{
//尾部
printf("请输入节点信息,从左往右依次为学号、姓名、3科成绩,以空格隔开:\n");
getNode(&node);
//printf("插入空表\n");
L->list[pos] = node;
L->len += 1;
printf("节点插入成功!\n");
//printNode(&node);
}
else//无效
{
printf("索引无效,插入失败!\n");
}
}
void printInfo()
{
printf("***********************欢迎来到线性表演示系统***********************\n");
printf(" 操作指南:插入--i ; 清空--c; 获取长度--s; 获得第pos位置的元素 -- g \n");
printf(" 遍历打印--t ; 查找--f; 退出 -- q; 第3题 -- x; 第4题 -- y \n");
printf("*****************************************************************\n");
}
void printNode(ElemType *p)
{
//打印节点的信息
printf("学号:%s, 姓名 :%s, 线性代数:%d, 大学物理:%d, 数据结构:%d, 平均分:%d\n",
p->sNumber, p->name, p->scores[0], p->scores[1],p->scores[2],p->scores[3]);
}
void TraverseList(List *L)
{
if(L->len ==0 || L->list == NULL)
{
printf("空表,请勿打印!\n");
return;
}
int i;
for(i = 0;i<L->len;++i)
printNode(L->list + i);
}
int isequal(ElemType *p1, ElemType *pNode)
{
//判断两个元素是否相等
if(strcmp(p1->name, pNode->name) == 0 && strcmp(p1->sNumber, pNode->sNumber) == 0
&& p1->scores[0] == pNode->scores[0] && p1->scores[1] == pNode->scores[1]
&& p1->scores[2] == pNode->scores[2])//每个元素都要相等
return 1;
return 0;
}
int FindList(List *L, ElemType *pNode)
{
//查找节点
if(L->len ==0 || L->list == NULL)
{
printf("空表!\n");
return -1;
}
int pos = -1;
int i;
for(i = 0;i<L->len;++i)
{
ElemType *p1 = L->list + i;
printNode(pNode);
if (isequal(p1, pNode))
{
pos = i;
break;
}
}
return pos;
}
void SortList(List *L)
{
//这个函数用于线性表的排序,由于本身默认的线性表大致有序,故在此采用
if(L->len ==0 || L->list == NULL)
{
printf("空表!\n");
return;
}
//插入排序
int i;
for(i = 1;i< L->len;++i)
{
int p = i-1;
ElemType tmp = L->list[i];
while(p >=0 && isSmaller(L->list + p , &tmp))
{
L->list[p+1] = L->list[p];
p--;
}
L->list[p+1] = tmp;
}
TraverseList(L);
}
int isSmaller(ElemType *p1 , ElemType *p2)
{
//该函数用来判断 *p1 是否小于 *p2
int sum1 = 0, sum2 =0;
int i;
for(i = 0;i< 3;++i)
{
sum1 += p1->scores[i];
sum2 += p2->scores[i];
}
return sum1 < sum2;
}
void printGua(List *L)
{
//输出至少挂了一科的同学
char *subjects[3] = {"线性代数", "大学物理", "数据结构"};
int i;
for(i = 0;i<L->len;++i)
{
int j;
for(j = 0;j<3;++j)
{
if((L->list[i]).scores[j] < 60)
break;
}
if(j == 3)
continue;
printf("%s ",(L->list[i]).name);
for(j = 0;j<3;++j)
{
if((L->list[i]).scores[j] < 60)
{
printf("%s--%d ",subjects[j], (L->list[i]).scores[j]);
}
}
printf("\n");
}
}
void printBigerThanX(List *L)
{
//实验报告第四题
printf("请输入x:\n");
int x;
scanf("%d", &x);
if(x <= 0 || x >= 100)
{
printf("x的值不符合要求!\n");
return;
}
int count = 0,i;
for(i = 0;i<L->len;++i)
{
if((L->list[i]).scores[3] > x)
{
printf("%s %d\n", (L->list[i]).name, (L->list[i]).scores[3]);
count++;
}
}
if(count == 0)
printf("输入的x太大了,没有符合条件的,换一个小点儿的\n");
}
C语言中的线性表演示代码
最新推荐文章于 2024-04-03 16:16:19 发布