顺序表的介绍
顺序表的特点
元素连续排列,在中间进行插入(删除)时,之后的元素都会后移(前移)->增删比较慢,但是查找比较快。
动态扩容的实现思路:
- 扩容时机:执行insert操作时,如果当前顺序表的长度和容量已经相等——没有剩余的位置供新元素插入,那么就需要进行扩容操作。
- 扩容方法:开辟一块儿更大的空间,把原来的元素拷贝到新空间中,再把原来的空间释放掉,然后把表的指针指向新空间。(在C语言中可以使用
realloc()
)
各个函数的介绍
首先,在定义顺序表时,我们使用了一个结构体来表示它,包括以下几个成员变量:
- data: 一个指向整型数组的指针,用于存储顺序表中的元素
- length: 当前顺序表的长度,即元素的个数
- capacity: 当前分配的内存空间大小,即可以容纳的元素个数
接下来,我们介绍每个函数的作用:
-
InitSeqList(SeqList* list)
: 初始化顺序表- 参数:指向顺序表的指针
- 功能:分配初始内存空间,并将长度、容量初始化为0
-
IsEmpty(SeqList list)
: 判断顺序表是否为空- 参数:顺序表
- 返回值:若顺序表为空,则返回1;否则返回0
-
GetLength(SeqList list)
: 获取顺序表长度- 参数:顺序表
- 返回值:顺序表的长度
-
Insert(SeqList* list, int pos, int value)
: 插入元素到顺序表指定位置- 参数:指向顺序表的指针,要插入的位置,要插入的值
- 返回值:若插入成功,则返回1;否则返回0
- 功能:在指定位置插入元素,并根据需要进行动态扩容
-
Delete(SeqList* list, int pos)
: 删除顺序表指定位置的元素- 参数:指向顺序表的指针,要删除的位置
- 返回值:若删除成功,则返回1;否则返回0
- 功能:删除指定位置的元素,并根据需要进行动态缩容
-
GetElement(SeqList list, int pos)
: 获取顺序表指定位置的元素- 参数:顺序表,要获取元素的位置
- 返回值:指定位置的元素值,若位置不合法则返回-1
-
DestroySeqList(SeqList* list)
: 销毁顺序表,释放内存- 参数:指向顺序表的指针
- 功能:释放顺序表占用的内存空间
-
WriteList(SeqList* list, const char* fileName)
: 将顺序表的数据写入文件- 参数:指向顺序表的指针,文件名
- 返回值:若写入成功,则返回1;否则返回0
- 功能:将顺序表中的每个元素依次写入文件中,用于持久化保存数据
-
ReadList(SeqList* list, const char* fileName)
: 读取顺序表的数据- 参数:指向顺序表的指针,文件名
- 返回值:若读取成功,则返回1;否则返回0
- 功能:从文件中读取数据,并插入到顺序表中,用于加载保存的数据
最后,在main
函数中,我们演示了如何使用这些函数来操作顺序表。首先,我们创建一个顺序表并进行初始化,然后在指定位置插入元素,删除元素,写入文件,读取文件,获取指定位置的元素等。最后,我们销毁顺序表,释放内存。
通过以上介绍,我们可以看到,这个顺序表实现了基本的插入、删除、获取元素等操作,还包括了动态扩容和缩容的功能,以及将数据持久化保存到文件和从文件中加载数据的功能。这样,我们就可以方便地对顺序表进行操作和管理。
实例代码
c语言版:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define INIT_SIZE 10 // 初始分配的内存空间大小
#define INCREMENT 5 // 每次扩容增加的内存空间大小
#define FILE_NAME "text.txt"
typedef struct {
int* data; // 顺序表指针
int length; // 当前长度
int capacity; // 当前分配的内存空间大小
} SeqList;
// 初始化顺序表
void InitSeqList(SeqList* list)
{
list->data = (int*)malloc(INIT_SIZE * sizeof(int)); // 分配初始内存空间
if (!list->data) {
printf("内存分配失败\n");
exit(1);
}
list->length = 0; // 长度初始化为0
list->capacity = INIT_SIZE; // 初始容量
}
// 判断顺序表是否为空
int IsEmpty(SeqList list)
{
return list.length == 0; // 长度为0表示为空
}
// 获取顺序表长度
int GetLength(SeqList list)
{
return list.length;
}
// 插入元素到顺序表指定位置
int Insert(SeqList* list, int pos, int value)
{
if (pos < 1 || pos > list->length + 1) {
// 位置不合法
return 0;
}
if (list->length >= list->capacity) {
// 如果当前内存空间已满,则进行扩容
int* newData = (int*)realloc(list->data, (list->capacity + INCREMENT) * sizeof(int));
if (!newData) {
printf("内存分配失败\n");
return 0;
}
list->data = newData;
list->capacity += INCREMENT; // 更新容量
}
// 将pos及之后的元素向后移动一位
for (int i = list->length; i >= pos; i--) {
list->data[i] = list->data[i - 1];
}
list->data[pos - 1] = value; // 在pos-1位置插入新元素
list->length++; // 长度加1
return 1;
}
// 删除顺序表指定位置的元素
int Delete(SeqList* list, int pos)
{
if (pos < 1 || pos > list->length) {
// 位置不合法
return 0;
}
// 将pos之后的元素向前移动一位
for (int i = pos - 1; i < list->length - 1; i++) {
list->data[i] = list->data[i + 1];
}
list->length--; // 长度减1
if (list->capacity - list->length >= INCREMENT) {
// 如果剩余空间过多,则进行缩容
int* newData = (int*)realloc(list->data, (list->capacity - INCREMENT) * sizeof(int));
if (!newData && list->length > 0) {
printf("内存分配失败\n");
return 0;
}
list->data = newData;
list->capacity -= INCREMENT; // 更新容量
}
return 1;
}
// 获取顺序表指定位置的元素
int GetElement(SeqList list, int pos)
{
if (pos < 1 || pos > list.length) {
// 位置不合法
return -1;
}
return list.data[pos - 1]; // 返回指定位置的元素值
}
// 销毁顺序表,释放内存
void DestroySeqList(SeqList* list)
{
free(list->data);
list->data = NULL;
list->length = 0;
list->capacity = 0;
}
// 将顺序表的数据写入文件
int WriteList(SeqList* list, const char* fileName) {
FILE* fp = fopen(fileName, "wb");
if (!fp) {
printf("文件打开失败\n");
return 0;
}
// 将顺序表中的每个元素依次写入文件中
for (int i = 0; i < list->length; i++) {
if (fwrite(&list->data[i], sizeof(int), 1, fp) != 1) {
fclose(fp);
return 0;
}
}
fclose(fp);
return 1;
}
// 读取顺序表的数据
int ReadList(SeqList* list, const char* fileName) {
FILE* fp = fopen(fileName, "rb");
if (!fp) {
printf("文件打开失败\n");
return 0;
}
// 读取文件中的数据,并插入到顺序表中
int value;
int i = 0;
while (fread(&value, sizeof(int), 1, fp)) {
if (!Insert(list,i++, value)) {
fclose(fp);
return 0;
}
}
fclose(fp);
return 1;
}
int main()
{
SeqList list;
InitSeqList(&list);
const char * filename = FILE_NAME;
// 在第一个位置插入元素10
Insert(&list, 1, 10);
// 在第二个位置插入元素20
Insert(&list, 2, 20);
// 删除第一个位置的元素
Delete(&list, 1);
WriteList(&list, filename);
ReadList(&list, filename);
// 获取第一个位置的元素
int element = GetElement(list, 1);
printf("First element: %d\n", element);
DestroySeqList(&list); // 销毁顺序表,释放内存
return 0;
}