题目:
已知选修《数据结构与算法》的学生花名册如附件 dsa-2022.txt,编程,用c语言完成以下的
操作:
1 定义一个顺序存储的线性表,将花名册的内容读入该线性表并输出该线性表;
2 若你的数据在上述线性表的第 i 个位置,试从线性表中删除你的数据并输出该线性表;
3 在删除了你的数据的线性表的第 i 个位置前插入你的数据并输出该线性表。
#include <stdio.h>//printf、scanf
#include <stdlib.h>//malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、srand()、exit()和一些宏
#include <string.h>//strlen、strcmp、strcpy、宏定义用到
#define MAXSIZE 55 //最大长度
#define LIST_INCREMENT 5 //增加的存储长度
#define OVERFLOW -2
#define OK 1
#define ERROR -1
#define N 52 //原始表长&数据长度
typedef int Status;
typedef struct /*定义数据读取结构*/
{
char id[20]; //生成一个存储字符串的数组(开大一点保证能全部存储)
char name[20];
}stu;
typedef struct /*定义数据链表*/
{
stu *elem; //指向stu类型的指针
int length; //顺序表长度
int listsize; //顺序表存储空间
}SqList;
void InitList (SqList *L) /*初始化顺序表*/
{
L->elem = (stu *)malloc(MAXSIZE*sizeof(stu)); //生成一个动态内存
if(!L->elem) //分配不成功,退出
exit(OVERFLOW);
L->length = 0; //初始化表长为0
L->listsize = MAXSIZE; //最大存储空间定义为55
}
Status READ(SqList *p) /*读取文件数据*/
{
stu *q; //生成一个stu类型指针
q=p->elem; //把顺序表中存储数据部分的基地址赋值给未定向的指针q
FILE *fp; //生成一个指向文件的指针
int i;
fp=fopen("DS_lab2.txt","r"); //fp指向文件位置,fopen格式为:fopen("文件路径","操作方式");
if(fp == NULL ) //判断指针是否成功指向文件,否则返回空
{
puts("Fail to open file!"); //否则打印“错误”并退出
exit(0);
}
for(i=0; i<N; i++,q++) //从已经指定数据类型的文件中读取数据
{
fscanf(fp, "%s %s\n", q->id, q->name); //fscanf格式为:fscanf(文件指针,“数据类型”,数据存放的地址),此处读取进stu类型指针q中
p->length++; //表长加一
}
fclose(fp); //操作完成记得关闭文件
return OK;
}
Status ListInsert(SqList *L,int i,stu e) /*插入算法*/
{
stu *newbase,*q,*p;
if(i<1||i>L->length) //i值不合法
return ERROR;
if(L->length >= L->listsize) //当前储存空间已满,分配新空间
{
newbase = (stu *)realloc(L->elem, (L->listsize + LIST_INCREMENT) * sizeof(stu)); //newbase指针指向新生成内存的基地址
if(!newbase)
exit(OVERFLOW); //分配失败退出
L->elem = newbase; //指向新地址
L->listsize += LIST_INCREMENT; //增加存储空间
}
q = L->elem+i-1; //q指向插入元素的位置
for(p = L->elem + L->length-1; p >= q; --p) //插入元素以及之后的元素后移
*(p+1) = *p; //将下一元素的值赋给前一个元素直到p=q
*q = e; //将新增元素的值赋给q的位置
L->length++;
return OK;
}
Status ListDelete_Sq(SqList *L,int i,stu *e) /*删除算法*/
{
stu *q,*p;
if(i<1||i>L->length) //i不合法
return ERROR;
p=L->elem+i-1; //p指向被删除元素的位置
*e=*p; //把p位置的值拿出来,赋值给e
q=L->elem+L->length-1; //表尾元素位置
for(++p;p<=q;++p)
*(p-1)=*p; //元素前移
L->length--;
return OK;
}
void print(SqList *p) /*打印顺序表*/
{
int i;
for(i=0; i<p->length; i++)
{
printf("%s %s\n",p->elem[i].id, p->elem[i].name); //注意双重结构体的取值方式,p->elem因为p是指针,elem[i].id是elem[i]作为值,否则是elem->id
}
printf("now, the length is:%d\n",p->length);
printf("\n");
}
int main()
{
SqList p;
stu a={"12345678910","newdata"};
InitList(&p);
READ(&p);
print(&p);
ListInsert(&p,50,a);
print(&p);
ListDelete_Sq(&p,50,&a);
print(&p);
}