目录
前言
在数据结构中,顺序表是一种基础的数据存储形式。
这篇博客主要介绍顺序表的静态分配存储表示,包括其定义、初始化、插入、删除和遍历等操作。
顺序表的表示和实现
1. 顺序表的静态存储过程
顺序表的静态存储使用固定大小的数组来存储数据元素。我们先定义一个静态顺序表:
// 线性表的静态分配顺序存储结构
#define MaxSize 100
typedef int ElementType;
typedef int Status;
typedef struct {
ElementType data[MaxSize]; // 存储空间基址
int length; // 当前长度
} StaticSqList;
1.1 初始化
初始化时,将表长设置为0。
Status initStaticSqList(StaticSqList *sqList) {
sqList->length = 0;
return 1;
}
1.2 销毁
静态顺序表不需要显式销毁,因为它使用的是固定大小的数组,生命周期由变量作用域决定。
1.3 清空
清空表时,将表长设置为0。
void clearSqList(StaticSqList *sqList) {
sqList->length = 0;
}
1.4 获取表长
获取当前顺序表的长度。
int staticSqListLength(StaticSqList *sqList) {
return sqList->length;
}
1.5 获取数据元素
获取指定位置的数据元素。
Status getElementForStaticSqList(StaticSqList *sqList, int pos, ElementType *element) {
if (pos < 1 || pos > sqList->length) {
return 0;
}
*element = sqList->data[pos - 1];
return 1;
}
1.6 获取直接前驱
获取指定数据元素的直接前驱。
Status priorStaticSqListElement(StaticSqList *sqList, ElementType element, ElementType *priorElement) {
for (int i = 0; i < sqList->length; i++) {
if (sqList->data[i] == element) {
if (i >= 1) {
*priorElement = sqList->data[i - 1];
return 1;
}
}
}
return 0;
}
1.7 获取直接后继
获取指定数据元素的直接后继。
Status nextStaticSqListElement(StaticSqList *sqList, ElementType element, ElementType *nextElement) {
for (int i = 0; i < sqList->length; i++) {
if (sqList->data[i] == element) {
if (i + 1 <= sqList->length - 1) {
*nextElement = sqList->data[i + 1];
return 1;
}
}
}
return 0;
}
1.8 插入
在指定位置插入数据元素。
Status insertStaticSqList(StaticSqList *sqList, int pos, ElementType element) {
if (pos < 1 || pos > sqList->length + 1 || sqList->length == MaxSize) {
return 0;
}
for (int i = sqList->length; i > pos - 1; i--) {
sqList->data[i] = sqList->data[i - 1];
}
sqList->data[pos - 1] = element;
sqList->length++;
return 1;
}
1.9 删除
删除指定位置的数据元素。
Status deleteSqList(StaticSqList *sqList, int pos, ElementType *element) {
if (pos < 1 || pos > sqList->length) {
return 0;
}
*element = sqList->data[pos - 1];
for (int i = pos - 1; i < sqList->length - 1; i++) {
sqList->data[i] = sqList->data[i + 1];
}
sqList->length--;
return 1;
}
1.10 遍历
遍历顺序表中的所有数据元素。
void traverseStaticSqList(StaticSqList *sqList) {
for (int i = 0; i < sqList->length; i++) {
printf("%d\t", sqList->data[i]);
}
printf("\n");
}
1.11 测试代码
以下是测试静态顺序表各种操作的代码:
void testStaticSqList(void) {
StaticSqList sqList;
printf("**********\t顺序表的静态存储表示测试\t**********\n");
if (initStaticSqList(&sqList)) {
printf("顺序表初始化成功\n");
}
printf("**********\t判断顺序表是否为空\t**********\n");
if (staticSqListEmpty(&sqList)) {
printf("顺序表为空,顺序的长度: %d\n", staticSqListLength(&sqList));
}
printf("**********\t顺序表插入测试\t**********\n");
for (int i = 1; i <= 10; i++) {
appendElement(&sqList, i);
}
printf("插入之前的数组:\n");
traverseStaticSqList(&sqList);
printf("顺序表的长度: %d\n", staticSqListLength(&sqList));
if (insertStaticSqList(&sqList, 5, 11)) {
printf("数据元素插入成功\n");
} else {
printf("插入失败\n");
}
printf("插入之后的数组:\n");
traverseStaticSqList(&sqList);
printf("顺序表的长度: %d\n", staticSqListLength(&sqList));
printf("**********\t顺序表删除测试\t**********\n");
int deleteElement;
if (deleteSqList(&sqList, 5, &deleteElement)) {
printf("数据元素 %d 删除成功\n", deleteElement);
} else {
printf("删除失败\n");
}
printf("删除之后的顺序表:\n");
traverseStaticSqList(&sqList);
printf("**********\t获取顺序表中的数据元素\t**********\n");
for (int i = 1; i <= 11; i++) {
ElementType element;
if (getElementForStaticSqList(&sqList, i, &element)) {
printf("数据元素获取成功,第 %d 个数据元素为: %d\n", i, element);
} else {
printf("第 %d 个数据元素获取失败\n", i);
}
}
printf("**********\t获取顺序表中某个数据元素的直接前驱\t**********\n");
ElementType priorElem;
if (priorStaticSqListElement(&sqList, 2, &priorElem)) {
printf("数据元素直接前驱获取成功,前驱数据元素为: %d\n", priorElem);
} else {
printf("数据元素直接前驱获取失败\n");
}
printf("**********\t获取顺序表中某个数据元素的直接后继\t**********\n");
ElementType nextElem;
if (nextStaticSqListElement(&sqList, 8, &nextElem)) {
printf("数据元素直接后继获取成功,后继数据元素为: %d\n", nextElem);
} else {
printf("数据元素直接后继获取失败\n");
}
}