顺序表是线性表的一种,它将元素存储在一段连续的内存空间中,表中的任意元素都可以通过下标快速的获取到,因此,顺序表适合查询操作频繁的场景,而不适合增删操作频繁的场景。

  下面是使用 C语言 编写的顺序表的代码:

  顺序表的头文件SeqList.h中的代码如下:

/**
* 顺序表(线性存储)
* 注意:添加数据时,先判断容量是否存满,存满才扩容,而不是添加元素后判断扩容!
*/
#include <stdio.h>
#include <stdlib.h> // 定义常量
#define SEQLIST_INITIAL_SIZE 5 // 顺序表的初始长度
#define SEQLIST_INCREMENT_SIZE 5 // 顺序表的递增长度 // 类型定义
typedef int seqElemType; // 定义顺序表(线性存储)的数据结构
typedef struct MySeqList {
seqElemType* data; // 存储所有数据的数组
int currentLength; // 当前长度
int totalLength; // 总长度
} MySeqList; // 0.比较两个元素数据是否相等
int isEqual(seqElemType a, seqElemType b) {
return a == b;
} // 1.初始化顺序表L,即进行动态存储空间分配并置L为一个空表
void initSeqList(MySeqList* L, int ms) {
if(ms <= ) {
printf("顺序表的初始长度非法!\n");
exit();
}
L->data = (seqElemType*)malloc(ms * sizeof(seqElemType));
if(L->data != NULL) {
L->currentLength = ;
L->totalLength = ms;
printf("顺序表初始化成功!当前总长度:%d\n", L->totalLength);
} else {
printf("顺序表初始化失败!\n");
exit();
}
} // 2.清除顺序表L中的所有元素,释放动态存储空间,使之成为一个空表
void clearList(MySeqList* L) {
if(L->data == NULL || L->totalLength < ) {
printf("顺序表不存在,清空失败!\n");
exit();
}
free(L->data);
L->data = ;
L->currentLength = L->totalLength = ;
printf("顺序表清空成功!\n");
} // 3.返回顺序表L的长度,若L为空则返回0
int getListSize(MySeqList* L) {
if(L->data == NULL) {
return ;
}
return L->currentLength;
} // 4.判断顺序表L是否为空,若为空则返回1,否则返回0
int isListEmpty(MySeqList* L) {
if(L->data == NULL) {
return ;
}
return L->currentLength == ;
} // 5.返回顺序表L中第pos个元素的值,若pos超出范围,则停止程序运行
seqElemType getElemAtPos(MySeqList* L, int pos) {
if(L->data == NULL) {
printf("顺序表不存在!\n");
exit();
}
if(pos < || pos >= L->currentLength) {
printf("下标无效!\n");
exit();
}
return L->data[pos - ];
} // 6.顺序扫描(即遍历)输出顺序表L中的每个元素
void traverseList(MySeqList* L) {
int i = ;
if(L->data == NULL) {
printf("顺序表不存在!\n");
exit();
}
printf("顺序遍历顺序表:");
for(i = ; i < L->currentLength; i++) {
printf("%-4d", L->data[i]);
}
printf("\n");
} // 7.从顺序表L中查找值与x相等的元素(第一个),若查找成功则返回其位置(下标),否则返回-1
int getPositionOfElem(MySeqList* L, seqElemType x) {
int i = ;
if(L->data == NULL) {
printf("顺序表不存在!\n");
exit();
}
for(i = ; i < L->currentLength; i++) {
if(isEqual(L->data[i], x)) {
break;
}
}
if(i == L->currentLength) {
i = -;
}
return i;
} // 8.把顺序表L中第pos个元素的值修改为x的值,若修改成功返回1,否则返回0
int setElemValue(MySeqList* L, int pos, seqElemType x) {
if(L->data == NULL) {
printf("顺序表不存在!\n");
return ;
}
if(pos < || pos >= L->currentLength) {
printf("下标无效!\n");
return ;
}
L->data[pos] = x;
return ;
} // 9.0.判断顺序表是否需要扩容,如果需要则扩容
void expandWhenShould(MySeqList* L) {
if(L->currentLength == L->totalLength) {
L->data = (seqElemType*)realloc(L->data, (L->totalLength + SEQLIST_INCREMENT_SIZE) * sizeof(seqElemType));
L->totalLength += SEQLIST_INCREMENT_SIZE;
if(L->data == NULL || L->totalLength <= ) {
printf("顺序表重分配空间失败,插入元素失败!\n");
exit();
}
printf("扩容成功,顺序表容量扩大到%d!\n", L->totalLength);
}
} // 9.向顺序表L的表头插入元素x
void insertElemAtStart(MySeqList* L, seqElemType x) {
int i = ;
if(L->data == NULL) {
printf("顺序表不存在!\n");
exit();
}
if(L->totalLength > ) {
expandWhenShould(L);
L->currentLength++;
for(i = L->currentLength; i > ; i--) {
L->data[i] = L->data[i - ];
}
L->data[] = x;
printf("成功将元素%d插入到表头!\n", x);
} else {
printf("顺序表长度不合法,插入元素失败!\n");
exit();
}
} // 10.向顺序表L的表尾插入元素x
void insertElemAtEnd(MySeqList* L, seqElemType x) {
if(L->data == NULL) {
printf("顺序表不存在!\n");
exit();
}
if(L->totalLength > ) {
expandWhenShould(L);
L->data[L->currentLength++] = x;
printf("成功将元素%d插入到表尾!\n", x);
} else {
printf("顺序表长度不合法,插入元素失败!\n");
exit();
}
} // 11.向顺序表L中第pos个元素位置插入元素x,若插入成功返回1,否则返回0
int insertElemAtPos(MySeqList* L, int pos, seqElemType x) {
int i = ;
if(L->data == NULL) {
printf("顺序表不存在!\n");
return ;
}
if(pos < || pos > L->currentLength) {
printf("下标不合法,插入元素失败!\n");
return ;
}
if(L->totalLength > ) {
expandWhenShould(L);
L->currentLength++;
for(i = L->currentLength; i > pos; i--) {
L->data[i] = L->data[i - ];
}
L->data[pos] = x;
printf("成功添加%d到顺序表第%d个位置!\n", x, pos);
} else {
printf("顺序表长度不合法,插入元素失败!\n");
return ;
}
return ;
} // 12.向有序(递增)顺序表L中插入元素x,使得插入后仍然有序
void insertOrderly(MySeqList* L, seqElemType x) {
int i = ;
if(L->data == NULL) {
printf("顺序表不存在!\n");
exit();
}
if(L->totalLength > ) {
expandWhenShould(L);
L->currentLength++;
for(i = L->currentLength; i > ; i--) {
if(x < L->data[i - ]) {
L->data[i] = L->data[i - ];
} else {
L->data[i] = x;
printf("成功将%d插入到顺序表的%d位置!\n", x, i);
break;
}
}
if(i == ) {
L->data[i] = x;
printf("成功将%d插入到顺序表的%d位置!\n", x, i);
}
} else {
printf("顺序表长度不合法,插入元素失败!\n");
exit();
}
} // 13.从顺序表L中删除表头元素并返回它,若删除失败则停止程序运行
seqElemType deleteFirstElem(MySeqList* L) {
int i = ;
int result = -;
if(L->data == NULL) {
printf("顺序表不存在!\n");
exit();
}
result = L->data[];
for(i = ; i < L->currentLength; i++) {
L->data[i - ] = L->data[i];
}
L->currentLength--;
printf("删除表头元素成功,返回表头元素:%d\n", result);
return result;
} // 14.从顺序表L中删除表尾元素并返回它,若删除失败则停止程序运行
seqElemType deleteLastElem(MySeqList* L) {
if(L->data == NULL) {
printf("顺序表不存在!\n");
exit();
}
L->currentLength--;
printf("删除表尾元素成功,返回表尾元素:%d\n", L->data[L->currentLength]);
return L->data[L->currentLength];
} // 15.从顺序表L中删除第pos个元素并返回它,若删除失败则停止程序运行
seqElemType deleteElemAtPos(MySeqList* L, int pos) {
int i = ;
int result = -;
if(L->data == NULL) {
printf("顺序表不存在!\n");
exit();
}
if(pos < || pos >= L->currentLength) {
printf("下标无效,删除元素失败!");
exit();
}
result = L->data[pos];
for(i = pos + ; i < L->currentLength; i++) {
L->data[i - ] = L->data[i];
}
L->currentLength--;
printf("成功将%d从顺序表的%d位置删除!\n", result, pos);
return result;
} // 16.从顺序表L中删除值为x的第一个元素,若删除成功返回1否则返回0
int deleteElemByValue(MySeqList* L, seqElemType x) {
int i = ;
if(L->data == NULL) {
printf("顺序表不存在!\n");
return ;
}
for(i = ; i < L->currentLength; i++) {
if(isEqual(L->data[i], x)) {
deleteElemAtPos(L, i);
printf("成功删除%d在顺序表中出现的第一个数据(%d位置)!\n", x, i);
return ;
}
}
printf("%d没有在顺序表中出现过,删除失败!\n");
return ;
} // 测试方法
void testMySeqList() {
// 声明顺序表变量
MySeqList list;
// 初始化顺序表
initSeqList(&list, SEQLIST_INITIAL_SIZE);
// 清空顺序表
// clearList(&list);
// 获取顺序表的当前长度
printf("顺序表当前长度:%d\n", getListSize(&list));
// 判断顺序表是否为空
printf("顺序表是否为空?%s\n", isListEmpty(&list) ? "是" : "否");
// 向表头插入数据
insertElemAtStart(&list, );
insertElemAtStart(&list, );
insertElemAtStart(&list, );
insertElemAtStart(&list, );
insertElemAtStart(&list, );
insertElemAtStart(&list, );
// 顺序遍历顺序表
traverseList(&list);
// 向表尾插入数据
insertElemAtEnd(&list, );
insertElemAtEnd(&list, );
insertElemAtEnd(&list, );
insertElemAtEnd(&list, );
insertElemAtEnd(&list, );
// 顺序遍历顺序表
traverseList(&list);
// 向顺序表指定位置插入数据
insertElemAtPos(&list, , );
insertElemAtPos(&list, , );
insertElemAtPos(&list, , );
insertElemAtPos(&list, , );
insertElemAtPos(&list, , );
// 顺序遍历顺序表
traverseList(&list);
// 有序表插入元素
insertOrderly(&list, );
insertOrderly(&list, );
// 顺序遍历顺序表
traverseList(&list);
// 删除表头元素
deleteFirstElem(&list);
deleteFirstElem(&list);
deleteFirstElem(&list);
deleteFirstElem(&list);
// 顺序遍历顺序表
traverseList(&list);
// 删除表尾元素
deleteLastElem(&list);
deleteLastElem(&list);
deleteLastElem(&list);
deleteLastElem(&list);
// 顺序遍历顺序表
traverseList(&list);
// 删除指定位置的元素
deleteElemAtPos(&list, );
deleteElemAtPos(&list, );
deleteElemAtPos(&list, );
// 顺序遍历顺序表
traverseList(&list);
// 删除某元素的首次出现
deleteElemByValue(&list, );
deleteElemByValue(&list, );
// 顺序遍历顺序表
traverseList(&list);
}

  主文件main.c中的代码:

#include <SeqList.h>

//主函数
int main() {
testMySeqList(); // 顺序表(顺序存储)顺序结构的测试
return ;
}

  运行结果如下:

顺序表初始化成功!当前总长度:5
顺序表当前长度:0
顺序表是否为空?是
成功将元素6插入到表头!
成功将元素5插入到表头!
成功将元素4插入到表头!
成功将元素3插入到表头!
成功将元素2插入到表头!
扩容成功,顺序表容量扩大到10!
成功将元素1插入到表头!
顺序遍历顺序表:1 2 3 4 5 6
成功将元素6插入到表尾!
成功将元素7插入到表尾!
成功将元素7插入到表尾!
成功将元素7插入到表尾!
扩容成功,顺序表容量扩大到15!
成功将元素8插入到表尾!
顺序遍历顺序表:1 2 3 4 5 6 6 7 7 7 8
成功添加7到顺序表第9个位置!
成功添加7到顺序表第9个位置!
成功添加7到顺序表第9个位置!
成功添加7到顺序表第9个位置!
扩容成功,顺序表容量扩大到20!
成功添加7到顺序表第9个位置!
顺序遍历顺序表:1 2 3 4 5 6 6 7 7 7 7 7 7 7 7 8
成功将7插入到顺序表的15位置!
成功将0插入到顺序表的0位置!
顺序遍历顺序表:0 1 2 3 4 5 6 6 7 7 7 7 7 7 7 7 7 8
删除表头元素成功,返回表头元素:0
删除表头元素成功,返回表头元素:1
删除表头元素成功,返回表头元素:2
删除表头元素成功,返回表头元素:3
顺序遍历顺序表:4 5 6 6 7 7 7 7 7 7 7 7 7 8
删除表尾元素成功,返回表尾元素:8
删除表尾元素成功,返回表尾元素:7
删除表尾元素成功,返回表尾元素:7
删除表尾元素成功,返回表尾元素:7
顺序遍历顺序表:4 5 6 6 7 7 7 7 7 7
成功将6从顺序表的3位置删除!
成功将7从顺序表的3位置删除!
成功将7从顺序表的3位置删除!
顺序遍历顺序表:4 5 6 7 7 7 7
成功将7从顺序表的3位置删除!
成功删除7在顺序表中出现的第一个数据(3位置)!
10没有在顺序表中出现过,删除失败!
顺序遍历顺序表:4 5 6 7 7 7 Process returned 0 (0x0) execution time : 0.172 s
Press any key to continue.

【数据结构】之顺序表(C语言描述)的更多相关文章

  1. 数据结构与算法之顺序表C语言实现

    顺序表等相关概念请自行查阅资料,这里主要是实现. 注: 1.顺序表C语言实现: 2.按较简单的方式实现,主要帮助理解,可在此基础上修改,更加完善: 3.提供几个简单函数,可自行添加功能: 4.可用C+ ...

  2. 《数据结构与算法分析:C语言描述》读书笔记

    我们数据结构的课用了这本英文教材,作者是Mark Allen Weiss.总体来说比<算法导论>简单很多,但内容上交集非常大.其实是因为去掉了大多数证明和数学,对于没有耐心看符号和公式的人 ...

  3. 数据结构与算法分析:C语言描述(原书第2版 简体中文版!!!) PDF+源代码+习题答案

    转自:http://www.linuxidc.com/Linux/2014-04/99735.htm 数据结构与算法分析:C语言描述(原书第2版中文版!!!) PDF+源代码+习题答案 数据结构与算法 ...

  4. hrbustoj 1545:基础数据结构——顺序表(2)(数据结构,顺序表的实现及基本操作,入门题)

    基础数据结构——顺序表(2) Time Limit: 1000 MS    Memory Limit: 10240 K Total Submit: 355(143 users) Total Accep ...

  5. [Python] 数据结构--实现顺序表、链表、栈和队列

    说明: 本文主要展示Python实现的几种常用数据结构:顺序表.链表.栈和队列. 附有实现代码. 来源主要参考网络文章. 一.顺序表 1.顺序表的结构 一个顺序表的完整信息包括两部分,一部分是表中元素 ...

  6. 数据结构4:顺序表(线性表的顺序存储结构)及C语言实现

    逻辑结构上呈线性分布的数据元素在实际的物理存储结构中也同样相互之间紧挨着,这种存储结构称为线性表的顺序存储结构. 也就是说,逻辑上具有线性关系的数据按照前后的次序全部存储在一整块连续的内存空间中,之间 ...

  7. [数据结构]C#顺序表的实现

    在数据结构的学习当中,想必C++可能是大家接触最多的入门语言了 但是C#的数据结构却很少看到,今天我写了一个C#顺序表的顺序存储结构 顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是 ...

  8. C++的标准模板库STL中实现的数据结构之顺序表vector的分析与使用

    摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解.即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第一篇,主要针对线性表中的顺序表(动 ...

  9. 【PHP数据结构】顺序表(数组)的相关逻辑操作

    在定义好了物理结构,也就是存储结构之后,我们就需要对这个存储结构进行一系列的逻辑操作.在这里,我们就从顺序表入手,因为这个结构非常简单,就是我们最常用的数组.那么针对数组,我们通常都会有哪些操作呢? ...

  10. 顺序表-Go语言实现

    简单理解就是数组: 优缺点及使用场景 优点: 随机访问,在O(1)时间内找到第i个元素: 数据表中的数据是连续存放的,因此只要知道数据表中第一个元素的地址,那么后面的数据元素的地址就可以马上算出来. ...

随机推荐

  1. (JavaScript) base64 字符串 和 ArrayBuffer 之间转换

    base64 --> ArrayBuffer function base64ToUint8Array(base64String) { const padding = '='.repeat((4 ...

  2. 解决靶机Bee-Box 键盘乱序问题

    Bee-Box介绍 Bee-box官方称呼BWAPP,buggy web Application 这是一个集成了各种常见漏洞和最新漏洞的开源Web应用程序,目的是帮助网络安全爱好者.开发人员和学生发现 ...

  3. python变量和运算

    本文收录在Python从入门到精通系列文章系列 1. 指令和程序 计算机的硬件系统通常由五大部件构成,包括:运算器.控制器.存储器.输入设备和输出设备. 其中,运算器和控制器放在一起就是我们通常所说的 ...

  4. [考试反思]1001csp-s模拟测试(b):逃离

    如你所见,b组题,除了NC乱入直奔T2抢了我一个首杀以外A层学过FFT的人都没有参加. 竞争压力很小,题又简单,所以就造就了6个AK. 然而并不计入总分,我仍然稳在第二机房. T1lyl16分钟切掉我 ...

  5. CSPS模拟 91

    T1 sz最多根号种 T2 没计算内存,水过了..CSPS这样的话要爆零的qaq T3 感谢miku带我重学ST表%%%%%

  6. Centos7下安装nexus3.x 安装

    1.官网下载unix版本 2.上传到linux系统的/usr/目录下 [root@lmll70op-ne ~]# cd /usr/ [root@lmll70op-ne usr]# ll 3.解压,并重 ...

  7. 使用Typescript重构axios(十九)——请求取消功能:实现第二种使用方式

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  8. p1594(巨坑题!!!)

    护卫车队在一条单行的街道前排成一队,前面河上是一座单行的桥.因为街道是一条单行道,所以任何车辆都不能超车.桥能承受一个给定的最大承载量.为了控制桥上的交通,桥两边各站一个指挥员.护卫车队被分成几个组, ...

  9. mysql connect refuse解决方法

    mysql connect refuse解决方法 1 因为连接数太多my.cnf配置文件 下面2个改大一点就好了 <pre>max_user_connectionmax_connectio ...

  10. 使用VSCode调试Egret项目中的ts代码

    发布一次Android项目后,会在代码里,生成对应的.map文件.这样就可以在编辑器里或是Chrome里面对相应的TS文件进行断点调试了. 实际只要在tsconfig.json里面配置一下," ...