编写一道程序,实现以下操作1.定义一链表类型,并定义带有头结点的单链表。 2.将教材中链表的建立、初始化、插入、删除等函数实现。 3.链表能够存储10名学生的基本信息(包括姓名、学号和成绩)。 4.由主函数按照用户要求对各个链表操作访问。 5.每次操作之前要有明确的说明,操作后要输出操作结果。 6.分析顺序表链表的插入、删除、查找的时间和空间复杂度
时间: 2024-02-13 15:07:12 浏览: 215
以下是实现单链表的程序,能够存储10名学生的基本信息(包括姓名、学号和成绩),并且实现了建立、初始化、插入、删除等函数。主函数能够按照用户要求对各个链表操作访问。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 10 // 定义链表的最大长度为10
typedef struct Student {
char name[20]; // 学生姓名
int num; // 学号
int score; // 成绩
struct Student *next; // 指向下一个结点的指针
} Student, *LinkList;
// 创建链表
LinkList CreateList() {
LinkList head = (LinkList)malloc(sizeof(Student)); // 创建头结点
head->next = NULL;
return head;
}
// 初始化链表,将链表中的所有结点都删除
void ClearList(LinkList head) {
LinkList p, q;
p = head->next;
while (p) {
q = p->next;
free(p);
p = q;
}
head->next = NULL;
}
// 判断链表是否为空
int IsEmpty(LinkList head) {
return head->next == NULL;
}
// 获取链表的长度
int ListLength(LinkList head) {
int length = 0;
LinkList p = head->next;
while (p) {
length++;
p = p->next;
}
return length;
}
// 在链表的第i个位置插入元素
int ListInsert(LinkList head, int i, char name[], int num, int score) {
if (i < 1 || i > ListLength(head) + 1) {
printf("插入位置不合法!\n");
return 0;
}
if (ListLength(head) == MAXSIZE) {
printf("链表已满,无法插入元素!\n");
return 0;
}
LinkList p = head;
for (int j = 1; j < i; j++) {
p = p->next;
}
LinkList node = (LinkList)malloc(sizeof(Student));
strcpy(node->name, name);
node->num = num;
node->score = score;
node->next = p->next;
p->next = node;
return 1;
}
// 删除链表的第i个位置上的元素
int ListDelete(LinkList head, int i) {
if (i < 1 || i > ListLength(head)) {
printf("删除位置不合法!\n");
return 0;
}
LinkList p = head;
for (int j = 1; j < i; j++) {
p = p->next;
}
LinkList q = p->next;
p->next = q->next;
free(q);
return 1;
}
// 打印链表中的所有元素
void PrintList(LinkList head) {
LinkList p = head->next;
while (p) {
printf("姓名:%s,学号:%d,成绩:%d\n", p->name, p->num, p->score);
p = p->next;
}
}
int main() {
LinkList head = CreateList(); // 创建链表
int choice;
char name[20];
int num, score, pos;
while (1) {
printf("请选择操作:\n");
printf("1. 插入元素\n");
printf("2. 删除元素\n");
printf("3. 打印链表\n");
printf("4. 清空链表\n");
printf("5. 退出程序\n");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("请输入插入的位置(1~%d):", ListLength(head) + 1);
scanf("%d", &pos);
printf("请输入学生姓名:");
scanf("%s", name);
printf("请输入学生学号:");
scanf("%d", &num);
printf("请输入学生成绩:");
scanf("%d", &score);
if (ListInsert(head, pos, name, num, score)) {
printf("插入成功!\n");
}
break;
case 2:
printf("请输入删除的位置(1~%d):", ListLength(head));
scanf("%d", &pos);
if (ListDelete(head, pos)) {
printf("删除成功!\n");
}
break;
case 3:
PrintList(head);
break;
case 4:
ClearList(head);
printf("链表已清空!\n");
break;
case 5:
exit(0);
break;
default:
printf("请输入正确的操作数!\n");
break;
}
}
return 0;
}
```
顺序表和链表的插入、删除、查找的时间和空间复杂度如下:
| 操作 | 顺序表 | 单链表 |
| --- | --- | --- |
| 查找 | O(1) | O(n) |
| 插入(平均) | O(n) | O(n) |
| 插入(最好) | O(1) | O(1) |
| 插入(最坏) | O(n) | O(n) |
| 删除(平均) | O(n) | O(n) |
| 删除(最好) | O(1) | O(1) |
| 删除(最坏) | O(n) | O(n) |
总体来说,顺序表适合查找操作频繁、插入、删除操作较少的情况;而链表适合插入、删除操作频繁、查找操作较少的情况。
阅读全文