实验一 线性表基本操作的编程实现
【实验目的】
线性表基本操作的编程实现
要求:
线性表基本操作的编程实现(2学时,验证型),掌握线性表的建立、遍历、插入、删除等基本操作的编程实现,也可以进一步编程实现查找、逆序、排序等操作,存储结构可以在顺序结构或链表结构中任选,可以完成部分主要功能,也可以用菜单进行管理完成大部分功能。还鼓励学生利用基本操作进行一些更实际的应用型程序设计。
【实验性质】
验证性实验(学时数:2H)
【实验内容】
把线性表的顺序存储和链表存储的数据插入、删除运算其中某项进行程序实现。建议实现文件输入数据以实现程序的通用性。为了体现功能的正常性,至少要编制遍历数据的函数。
【注意事项】
1.开发语言:使用C。
2.可以自己增加其他功能。
【实验分析、说明过程】
将学生插入到班级Li_head的第i个位置。 定义指针q和s, 先用while循环寻找第i个位置是否存在,如果不存在则重新输入。 生成新结点,如果申请空间失败返回主调函数。为新结点赋值,输入学生信息。 指针q从头结点开始while循环寻找并指向第i-1个结点,将q->next赋值给s->next,再将q->next指向s。最后链表长度加一,返回。
删除链表Li_head中第i个学生的信息 定义指针p和q, 先用while循环寻找第i个位置是否存在,如果不存在则重新输入。 指针p从头结点开始while循环寻找并指向第i-1个结点,将p->next赋值给q,再将p->next指向q->next。free释放第i个结点,最后链表长度减一,返回。
|
【思考问题】
1.线性表的顺序存储和链表存储的差异?优缺点分析? 底层存储空间不一样,顺序表底层存储空间是连续的,而链表则是不连续的。 顺序表空间利用率高,是因为申请一块连续的内存。链表空间利用率低,因为链表都是一个一个的节点组成的,节点中还有指向下一个节点的指针。而且每个节点都是malloc申请出来的空间,频繁的申请空间会导致空间碎片化,故利用率低。 2. 那些操作引发了数据的移动? 将新的数据结点插入到链表的指定位置当中。 将链表中的指定位置的数据结点删除。 3. 算法的时间效率是如何体现的? 算法的时间效率体现在时间复杂度上。时间复杂度是指算法运行所需的时间与问题规模之间的增长关系。通常用大O符号表示,表示算法的最坏情况下的时间复杂度。 4. 链表的指针是如何后移的?如何加强程序的健壮性? 若当前结点为p,则后移操作为p = p->next。 在插入结点时,需要判断插入位置是否合法,是否越界;在删除结点时,需要判断待删除结点是否存在等。 |
【实验小结】 (总结本次实验的重难点及心得、体会、收获)
重难点在开始敲代码之前对本次实验题目的构思,以及链表的插入删除的逻辑结构,怎样去完成实现这个操作。 在完成实验的过程中,在联系日常软件的使用过程,插入删除等操作应该还要考虑插入删除位置是否合理等,以及如果不合理我们应该怎么去操作,应该多考虑程序的健壮性。 在大一学习敲代码的时候根本没有考虑程序的健壮性这种问题的意识。 这次实验过后我深深体会到了在写程序过程中的考虑不周,逻辑不清晰以及基础知识的掌握不熟练等问题,希望能在之后的学习中得到改善。 |
【附录-实验代码】
基础篇 for(j=Li->length;j>i-1;j--) Li->stu[j+1]=Li->stu[j]; Li->stu[i]=e; Li->length=Li->length+1; for(j=i+1;j<=Li->length;j++) Li->stu[j-1]=Li->stu[j]; Li->length--; 提高篇 #define NULL 0 #include<stdio.h> #include<conio.h> #include<stdlib.h> typedef struct stu { int num; //学生的学号 char name[10]; //学生的姓名 float score; //学生的成绩 }STUDENT; //存放单个学生信息的结构体类型 typedef struct node { STUDENT data; //结点的值 struct node* next; //指向下一个结点的地址 }SNODE; void showmenu() { //显示菜单 printf(" 欢迎使用成绩管理小软件\n"); printf("\t1、创建学生信息\n"); printf("\t2、插入学生信息\n"); printf("\t3、删除学生信息\n"); printf("\t4、显示学生信息\n"); printf("\t5、退出程序\n"); } SNODE* listcreate(SNODE* head, int n) //n为该班级的实际人数 { //建立班级学生信息 int i; SNODE* p = NULL, * q = NULL; p = head; for (i = 1; i <= n; i++) //循环插入n个学生 { printf("\n请输入第%d位学生的信息:\n", i); q = (SNODE*)malloc(sizeof(SNODE)); printf("学号="); scanf("%d", &q->data.num); printf("姓名="); scanf("%s", q->data.name); printf("成绩="); scanf("%f", &q->data.score); q->next = NULL; p->next = q; p = q; head->data.num++; } return head; } SNODE* listinsert(SNODE* head, int i) //将学生插入到班级Li_head的第i个位置。 { STUDENT ix; SNODE * q, * s; int j = 0; while(i<=0||i>head->data.num)//插入位置不合理 ,重新输入插入位置 { printf("插入位置不存在,请重新输入插入位置:"); scanf("%d",&i); } s = (SNODE*)malloc(sizeof(SNODE)); if (s == NULL) return s; s->data = ix; printf("请输入学生信息:\n"); printf("学号="); scanf("%d", &s->data.num); printf("姓名="); scanf("%s", s->data.name); printf("成绩="); scanf("%f", &s->data.score); q = head; while (q->next != NULL && j < i-1) { q = q->next; j++; } s->next = q->next; q->next = s; head->data.num++; return head; } SNODE* listdel(SNODE* head, int i) //删除链表Li_head中第i个学生的信息 { SNODE* p, * q; int j = 0; while(i<=0||i>head->data.num) { printf("删除位置不存在,请重新输入删除位置:"); scanf("%d",&i); } p = head; while (p->next != NULL && j < i-1) { p = p->next; j++; } q = p->next; if (q == NULL)return 0; p->next = q->next; free(q); head->data.num--; return head; } void listdisplay(SNODE* head) { //显示所有学生信息 SNODE* p; p = head->next; printf("班级学生信息如下:\n"); printf(" 学号 姓名 成绩\n"); while (p != NULL) { printf("%10d%10s%10.2f\n", p->data.num, p->data.name, p->data.score); p = p->next; } } int main() { SNODE* head = NULL; int no, stu_count, pos; head = (SNODE*)malloc(sizeof(SNODE));//动态建立第一个结点,作为头结点,head指针指向它, head->data.num = 0; //链表为带头结点的单链表 head->next = NULL; while (1) { showmenu(); printf(" 请输入你的选择:"); scanf("%d", &no); switch (no) { case 1: printf("班级信息初始化,按任意键继续……\n"); getch(); printf("请输入班级学生原始人数:"); scanf("%d", &stu_count); head = listcreate(head, stu_count); system("cls"); showmenu(); listdisplay(head); printf("班级信息初始化已经完成,按任意键继续……\n"); getch(); system("cls"); break; case 2:printf("插入前班级信息:\n"); listdisplay(head); printf("请输入插入位置:"); scanf("%d", &pos); head = listinsert(head, pos); printf("插入后班级信息:\n"); listdisplay(head); printf("插入已经完成,按任意键继续……\n"); getch(); system("cls"); break; case 3: if(head!=NULL) { printf("删除前班级信息:\n"); listdisplay(head); printf("请输入删除位置:"); scanf("%d", &pos); head = listdel(head, pos); printf("删除后班级信息:\n"); listdisplay(head); printf("删除已经完成,按任意键继续……\n"); } else { printf("无可删除学生信息!"); } getch(); system("cls"); break; case 4:listdisplay(head); printf("显示结果如上所示,按任意键继续……\n"); getch(); system("cls"); break; case 5:return 0; } } } |