实验任务
(1) 掌握顺序表结构及其 C 语言实现;
(2) 掌握插入、删除等基本算法;
(3) 掌握顺序表的基本应用(将两个有序线性表合并为一个有序表)。
实验内容
- 使用 C 语言实现顺序表的类型定义与算法函数;
- 编写 main()函数,合理调用函数实现以下功能:
- 创建 3 个顺序表 L1、L2 和 L3;
- L1 数据内定(斐波拉契序列前 2-11 项):1、2、3、5…、55、89;
- L2 数据随机产生,共 10 个,满足:
- 第 1 个数为 4,其后每个数字比其前趋随机增加1~9
- 分别显示 L1 和 L2 的内容;
- 有序合并 L1 和 L2 到 L3 中;
- 显示 L3 的内容;
- 随机删除 L3 中第 1~10 个元素,显示 L3 的内容;
- 随机产生 1 个[1, 100]之间的数字插入到 L3 中并保持有序,显示L3的内容。
实验源码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXSIZE 100
#define ERROR 0
#define OK 1
typedef int ElemType;
typedef struct {
ElemType *elem;
int length;
} SqList;
int InitList(SqList *list); // 顺序表的初始化
void Fibonacci(SqList *list, int length); // 斐波那契序列
void RandomNumber(SqList *list, int num); // 1-9随机数前趋叠加
void Combine(SqList *list1, SqList *list2, SqList *list3, SqList *temp); // 合并2个顺序表到1个
int DelSqList(SqList *list, int randNum); // 随机删除元素 1~10
int Insert(SqList *list, ElemType randNum, SqList *temp); // 插入某个元素,并且按顺序排序
int PrintSqList(SqList *list); // 输出顺序表
void BubbleSort(SqList *list); // 冒泡排序 好写,但效率不高
// 归并算法:空间换时间 稳定
void mergeSort(SqList *list, int left, int right, SqList *temp); // 归并排序:归分
void merge(SqList *list, int left, int mid, int right, SqList *temp); // 归并排序:分治
int InitList(SqList *list) {
list->elem = (ElemType *) malloc(sizeof(SqList) * MAXSIZE);
if (list->elem == NULL) {
exit(ERROR);
}
list->length = 0;
return OK;
}
void Fibonacci(SqList *list, int length) {
int num1 = 0;
int num2 = 1;
// for (int i = 0; i < length; i++) {
// if ((i + 1) % 2 != 0) { // 代码冗余了,直接一次循环赋值两次即可
// num1 += num2;
// list->elem[i] = num1;
// } else {
// num2 += num1;
// list->elem[i] = num2;
// }
// }
for (int i = 0; i < length;) {
num1 += num2;
list->elem[i++] = num1;
num2 += num1;
list->elem[i++] = num2;
}
list->length = length;
}
void RandomNumber(SqList *list, int num) {
list->elem[0] = 4;
srand(time(NULL));
for (int i = 1; i < num; i++) {
list->elem[i] = list->elem[i - 1] + rand() % 9 + 1; // max-min+1 ~ min
}
list->length = num;
}
void Combine(SqList *list1, SqList *list2, SqList *list3, SqList *temp) {
int i = 0;
for (; i < list1->length; i++) {
list3->elem[i] = list1->elem[i];
}
for (int j = 0; j < list2->length; j++, i++) {
list3->elem[i] = list2->elem[j];
}
list3->length = list1->length + list2->length;
// 这里需要用到一个排序算法
temp->length = list3->length;
mergeSort(list3, 0, list3->length - 1, temp);
}
int DelSqList(SqList *list, int randNum) {
if (randNum < 1 || randNum > 10 || list->length == 0) {
exit(ERROR);
}
for (; randNum < list->length; randNum++) {
list->elem[randNum - 1] = list->elem[randNum];
}
list->elem[--randNum] = 0; // 这里有一个BUG,由于申请了100个空间,所有没有用到的空间也有值且为0
list->length--;
return OK;
}
int Insert(SqList *list, ElemType randNum, SqList *temp) {
if (randNum < 1 || randNum > 100 || list->length == 0) {
exit(ERROR);
}
list->elem[list->length] = randNum;
list->length++;
// 这里需要用到一个排序算法
temp->length = list->length;
mergeSort(list, 0, list->length - 1, temp);
return OK;
}
int PrintSqList(SqList *list) {
if (list->length == 0) {
exit(ERROR);
}
for (int i = 0; i < list->length; i++) {
printf("%2d", list->elem[i]);
if ((i + 1) % 10 == 0 && i != list->length - 1) {
printf("\n ");
}
if (i != list->length - 1) {
printf(" -> ");
}
}
printf("\n");
return OK;
}
//void BubbleSort(SqList *list) { // 冒泡排序,弃用
// ElemType temp;
// for (int i = 0; i < list->length - 1; i++) {
// int count = -1;
// for (int j = 0; j < list->length - 1 - i; j++) {
// if (list->elem[j] > list->elem[j + 1]) {
// temp = list->elem[j];
// list->elem[j] = list->elem[j + 1];
// list->elem[j + 1] = temp;
// count++;
// }
// }
// if (count == -1) {
// break;
// }
// }
//}
void mergeSort(SqList *list, int left, int right, SqList *temp) {
if (left < right) {
int mid = (left + right) / 2;
// 左
mergeSort(list, left, mid, temp);
// 右
mergeSort(list, mid + 1, right, temp);
// 合并
merge(list, left, mid, right, temp);
}
}
void merge(SqList *list, int left, int mid, int right, SqList *temp) {
int i = left;
int j = mid + 1;
int t = 0;
while (i <= mid && j <= right) {
if (list->elem[i] <= list->elem[j]) { // 左
temp->elem[t++] = list->elem[i++];
} else { // 右
temp->elem[t++] = list->elem[j++];
}
}
// 多余元素情况
while (i <= mid) {
temp->elem[t++] = list->elem[i++];
}
while (j <= right) {
temp->elem[t++] = list->elem[j++];
}
// 拷贝元素到原数组
t = 0;
int tempLeft = left;
while (tempLeft <= right) { // 有几个元素拷贝几个原则
list->elem[tempLeft++] = temp->elem[t++];
}
}
/**
* <h2>顺序表实验</h2>
* @return 0
*/
int main() {
SqList L1, L2, L3, tempSL;
if (InitList(&tempSL) != 1) {
printf("tempSL初始化失败!!!\n");
}
printf("=========================== 顺序表编程实践 ===========================\n");
if (InitList(&L1) == 1) {
int length = 10;
Fibonacci(&L1, length);
printf("【顺序表L1已生成】\n");
printf("L1: ");
PrintSqList(&L1);
} else {
printf("L1初始化失败!!!\n");
}
if (InitList(&L2) == 1) {
int randNum = 10;
RandomNumber(&L2, randNum);
printf("【顺序表L2已生成】\n");
printf("L2: ");
PrintSqList(&L2);
} else {
printf("L2初始化失败!!!\n");
}
if (InitList(&L3) == 1) {
Combine(&L1, &L2, &L3, &tempSL);
printf("【L1和L2有序合并到L3】\n");
printf("L3: ");
PrintSqList(&L3);
} else {
printf("L3初始化失败!!!\n");
}
srand(time(NULL));
int randNum1_10 = rand() % 10 + 1;
printf("【随机删除L3中第%d个元素】\n", randNum1_10);
DelSqList(&L3, randNum1_10);
printf("L3: ");
PrintSqList(&L3);
ElemType randNum1_100 = rand() % 100 + 1;
printf("【随机产生数字%d插入到L3】\n", randNum1_100);
Insert(&L3, randNum1_100, &tempSL);
printf("L3: ");
PrintSqList(&L3);
return 0;
}