顺序表的定义及其特点
顺序表的定义
顺序表可以通过结构体来定义,通常包含以下两个主要成员:
- 数据数组:存储数据元素的数组,每个数组元素都存储一个数据项。
- 长度属性:表示顺序表当前包含的元素数量。
#define MaxSize 1000 //先定义最大长度便于修改
typedef struct SeqList { //使用typedef重命名结构体便于使用
DataType data[MaxSize]; // 数据元素数组
int length; // 顺序表的当前长度
} SeqList;
顺序表的特点
-
连续存储: 顺序表中的元素在内存中以连续的方式存储,这使得随机访问变得高效,可以通过索引快速访问任何元素。
-
固定容量: 顺序表的容量在创建时通常是固定的,即最大容量是预先定义好的。当顺序表达到最大容量时,无法再插入新元素,除非进行扩容操作。
-
动态长度:顺序表的长度可以随着元素的插入和删除而动态变化。
-
适合元素较少情况: 顺序表适用于元素数量不太多的情况。当元素数量较大时,可能需要频繁的扩容操作,影响性能。
-
适合随机访问: 由于元素的连续存储,顺序表非常适合随机访问,方便快速查找和拥有高效的查找速度
顺序表的运算
顺序表支持多种常见的运算,包括:
-
初始化: 创建一个空的顺序表,设置长度为零。
-
插入元素: 在指定位置插入一个新元素,需要考虑位置的合法性和容量限制。
-
删除元素: 删除指定位置的元素,同样需要考虑位置的合法性。
-
查找元素: 根据元素值或位置查找元素。
-
判断是否为空: 检查顺序表是否为空。
-
判断是否已满: 检查顺序表是否已满。
-
获取长度: 获取顺序表中元素的数量。
-
遍历顺序表: 遍历顺序表中的所有元素。
-
扩容: 当顺序表达到最大容量时,可以进行扩容操作,以容纳更多元素。
-
销毁: 释放顺序表占用的内存,销毁顺序表。
-
其他操作: 根据具体需求,顺序表还可以支持其他操作,如排序、合并等。
顺序表的实现
创建结构体
#define MaxSize 1000 // 先定义最大长度便于修改
#define InitialSize 10 // 初始顺序表大小
#define IncreaseSize 10 // 每次扩容的增量
typedef int DataType; // 为了语义化,将int数据类型重命名
typedef struct SeqList // 使用typedef重命名结构体便于使用
{
DataType *data;
int length;
int maxsize;
} SeqList;
初始化顺序表
// 初始化顺序表
void initSeqList(SeqList *L)
{
L->data = (DataType *)malloc(sizeof(DataType) * InitialSize);
L->length = 0;
L->maxsize = InitialSize;
}
插入元素
// 插入元素
bool insertElement(SeqList *L, int position, DataType value)
{
if (position < 1 || position > L->length + 1) // 检查插入位置是否合法
{
return false; // 插入位置无效
}
if (L->length >= L->maxsize) // 如果顺序表已满,扩容
{
DataType *newData = (DataType *)malloc(sizeof(DataType) * (L->maxsize + IncreaseSize));
if (newData == NULL)
{
return false; // 内存分配失败
}
for (int i = 0; i < L->length; i++)
{
newData[i] = L->data[i];
}
free(L->data); // 释放旧的内存
L->data = newData; // 更新数据指针
L->maxsize += IncreaseSize; // 更新最大容量
}
// 将指定位置后的元素向后移动一个位置
for (int i = L->length; i >= position; i--)
{
L->data[i] = L->data[i - 1];
}
// 插入新元素
L->data[position - 1] = value;
L->length++;
return true;
}
删除元素
// 删除元素
bool deleteElement(SeqList *L, int position, DataType *deletedValue)
{
if (position < 1 || position > L->length)
{
return false; // 删除位置无效
}
// 保存被删除元素的值
*deletedValue = L->data[position - 1];
// 将指定位置后的元素向前移动一个位置
for (int i = position; i < L->length; i++)
{
L->data[i - 1] = L->data[i];
}
L->length--;
return true;
}
判断顺序表是否为空
// 判断顺序表是否为空
bool isEmpty(SeqList *L)
{
return L->length == 0;
}
判断顺序表是否满了
// 判断顺序表是否满
bool isFull(SeqList *L)
{
return L->length == L->maxsize;
}
输出顺序表
// 输出顺序表
void printSeqList(SeqList *L)
{
if (isEmpty(L))
{
printf("顺序表没有元素.\n");
}
else
{
printf("顺序表内容为: ");
for (int i = 0; i < L->length; i++)
{
printf("%d ", L->data[i]);
}
printf("\n");
}
}
查找元素
// 查找元素
int find(SeqList *L, DataType value)
{
for (int i = 0; i < L->length; i++)
{
if (L->data[i] == value)
{
return i + 1; // 找到了,返回位置
}
}
return -1; // 未找到
}
顺序表demo
详细的实现代码如下
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define MaxSize 1000 // 先定义最大长度便于修改
#define InitialSize 10 // 初始顺序表大小
#define IncreaseSize 10 // 每次扩容的增量
typedef int DataType; // 为了语义化,将int数据类型重命名
typedef struct SeqList // 使用typedef重命名结构体便于使用
{
DataType *data;
int length;
int maxsize;
} SeqList;
char welcome[] = "Welcome to my application";
// 初始化顺序表
void initSeqList(SeqList *L)
{
L->data = (DataType *)malloc(sizeof(DataType) * InitialSize);
L->length = 0;
L->maxsize = InitialSize;
}
// 插入元素
bool insertElement(SeqList *L, int position, DataType value)
{
if (position < 1 || position > L->length + 1) // 检查插入位置是否合法
{
return false; // 插入位置无效
}
if (L->length >= L->maxsize) // 如果顺序表已满,扩容
{
DataType *newData = (DataType *)malloc(sizeof(DataType) * (L->maxsize + IncreaseSize));
if (newData == NULL)
{
return false; // 内存分配失败
}
for (int i = 0; i < L->length; i++)
{
newData[i] = L->data[i];
}
free(L->data); // 释放旧的内存
L->data = newData; // 更新数据指针
L->maxsize += IncreaseSize; // 更新最大容量
}
// 将指定位置后的元素向后移动一个位置
for (int i = L->length; i >= position; i--)
{
L->data[i] = L->data[i - 1];
}
// 插入新元素
L->data[position - 1] = value;
L->length++;
return true;
}
// 删除元素
bool deleteElement(SeqList *L, int position, DataType *deletedValue)
{
if (position < 1 || position > L->length)
{
return false; // 删除位置无效
}
// 保存被删除元素的值
*deletedValue = L->data[position - 1];
// 将指定位置后的元素向前移动一个位置
for (int i = position; i < L->length; i++)
{
L->data[i - 1] = L->data[i];
}
L->length--;
return true;
}
// 判断顺序表是否为空
bool isEmpty(SeqList *L)
{
return L->length == 0;
}
// 判断顺序表是否满
bool isFull(SeqList *L)
{
return L->length == L->maxsize;
}
// 输出顺序表
void printSeqList(SeqList *L)
{
if (isEmpty(L))
{
printf("顺序表没有元素.\n");
}
else
{
printf("顺序表内容为: ");
for (int i = 0; i < L->length; i++)
{
printf("%d ", L->data[i]);
}
printf("\n");
}
}
// 查找元素
int find(SeqList *L, DataType value)
{
for (int i = 0; i < L->length; i++)
{
if (L->data[i] == value)
{
return i + 1; // 找到了,返回位置
}
}
return -1; // 未找到
}
int main()
{
SeqList myList;
initSeqList(&myList);
int command;
DataType value;
int position;
DataType deletedValue;
int i, m, n;
for (i = 0; i < strlen(welcome); i++)
{
printf("%c", welcome[i]);
for (m = 0; m < 10000; m++)
for (n = 0; n < 10000; n++)
{
;
}
}
printf("\n\n\n");
printf("顺序表演示程序\n");
printf("1. 顺序表初始化\n");
printf("2. 插入元素\n");
printf("3. 删除元素\n");
printf("4. 检查顺序表是否为空\n");
printf("5. 检查顺序表是否已满\n");
printf("6. 输出顺序表\n");
printf("7. 查找元素\n");
printf("10. 帮助\n");
printf("0. 退出\n");
while (1)
{
printf("输入指令: ");
scanf("%d", &command);
switch (command)
{
case 1:
initSeqList(&myList);
printf("顺序表初始化完成\n");
break;
case 2:
printf("输入插入的位置和值,使用空格分开:");
scanf("%d %d", &position, &value);
if (insertElement(&myList, position, value))
{
printf("元素插入成功\n");
}
else
{
printf("插入失败!!!\n");
}
break;
case 3:
printf("输入需要删除的元素的位置: ");
scanf("%d", &position);
if (deleteElement(&myList, position, &deletedValue))
{
printf("已删除元素的值: %d\n", deletedValue);
}
else
{
printf("删除失败.\n");
}
break;
case 4:
if (isEmpty(&myList))
{
printf("顺序表是空的\n");
}
else
{
printf("顺序表不是空的\n");
}
break;
case 5:
if (isFull(&myList))
{
printf("顺序表已经满了\n");
}
else
{
printf("顺序表还未满.\n");
}
break;
case 6:
printSeqList(&myList);
break;
case 7:
printf("输入需要查找的元素的值: ");
scanf("%d", &value);
position = find(&myList, value);
if (position != -1)
{
printf("元素 %d 位于位置 %d\n", value, position);
}
else
{
printf("未找到元素 %d\n", value);
}
break;
case 10:
printf("本程序由陈勇豪制作\n");
break;
case 0:
free(myList.data); // 释放动态分配的内存
printf("退出程序.\n");
return 0;
default:
printf("无效指令,请重新输入.\n");
break;
}
}
return 0;
}
以下是运行结果截图
小结
这个C语言程序是一个简单的数字列表管理工具,用户可以初始化列表、添加、删除、查找、查看、判断是否为空或已满,以及自动扩容。程序的界面友好,通过输入数字指令即可执行各种操作,而动态内存分配确保了列表可以随需要自动扩展或收缩。这个程序可以帮助理解顺序表数据结构和内存管理的基本原理,为进一步学习和开发更复杂的应用奠定了基础。
参考文献:《数据结构(C语言版)》李刚、刘万辉主编,高等教育出版社。OpenAI