数据结构笔记:3.5 静态链表/游标实现法
2020-07-15 05:30
162 查看
1、概念
首先让数组的元素都是由两个数据域组成,data和cursor。也就是说,数组的每个下标都对应一个data和一个cursor。数据与data,用来存放数据元素,也就是需要处理的数据;而cursor相当于单链表中的next指针,存放该元素的后继在数组中的下标,通常把cursor叫做游标。
用数组描述的链表叫做静态链表,又叫做游标实现法。
2、具体实现代码
(1)静态链表的数据存储结构
typedef struct StaticLinkedList {/*静态链表的数据存储*/ /*StaticLinkedListArray[0]相当于备用链表的头结点(将为静态链表中未储存数据的部分视为备份链表),不用于存储需要使用的数据,cursor存储静态链表的备用空表的第一个结点的下标(即第一个没有存储数据的结点的下标),当cursor=0时,表示该静态链表已满*/ /*StaticLinkedListArray[MAXSIZE-1]也不存放数据,相当于该静态链表的头结点(存储数据部分),data存储静态链接表的长度(不包括第一个结点),cursor存放数组中第一个数据所在位置的下标(不是头结点),若cursor=0则表示该链表为空*/ /*数组的最后一个结点StaticLinkedListArray[MAXSIZE-1]也不存放数据,该结点的cursor存放数组中第一个数组所在的结点的下标(不是头结点)* /*静态链表中最后一个数据所在的位置的cursor=0,即指向备用链表的头结点*/ ElemType data; int cursor;/*存放下一个数据的下标*/ }StaticLinkedList, StaticLinkedListArray[MAXSIZE];
(2)初始化静态链表
void Initialization(StaticLinkedListArray L) {/*初始化静态链表*/ int i = 1; while (i < MAXSIZE) L[i-1].cursor = i++; L[MAXSIZE - 1].data = 0;/*初始化静态链表的数据个数*/ L[MAXSIZE - 1].cursor = 0;/*初始化静态链表的头结点的指向*/ }
(3)分配空间
int AllocateSpace(StaticLinkedListArray L) {/*分配空间,返回下标*/ if (L[MAXSIZE-1].data >=MAXSIZE-2) return ERROR;/*当静态链表已满时,返回错误*/ int j = L[0].cursor;/*获取备用链表的第一个下标*/ L[0].cursor = L[j].cursor;/*备用链表头结点存放的下标后移一位*/ return j; }
(4)输出静态链表
void Display(StaticLinkedListArray L) {/*输出静态链表的长度及数据*/ if (L[MAXSIZE - 1].data == 0) printf("静态链表为空!\n"); else { int i = L[MAXSIZE-1].cursor;/*获取第一个数据的下标*/ printf("静态链表的长度为:%d\n静态链表中的数据为:", L[MAXSIZE - 1].data); while (i != 0) {/*当输出到最后一个数据,即cursor==0后,退出循环*/ printf("%3d", L[i].data); i = L[i].cursor;/*获取下一个数据的下标*/ } putchar('\n'); } }
(5)分配空间
int AllocateSpace(StaticLinkedListArray L) {/*分配空间,返回下标*/ if (L[MAXSIZE-1].data >=MAXSIZE-2) return ERROR;/*当静态链表已满时,返回错误*/ int j = L[0].cursor;/*获取备用链表的第一个下标*/ L[0].cursor = L[j].cursor;/*备用链表头结点存放的下标后移一位*/ return j; }
(6)初始化静态链表数据
void InitializationData(StaticLinkedListArray L) {/*输入初始化静态链表的数据*/ int i=1; L[MAXSIZE - 1].cursor = 1; printf("请输入初始化创建数据的数目:"); scanf_s("%d", &L[MAXSIZE-1].data); while (i <= L[MAXSIZE - 1].data) { printf("请输入第%d个数据:", i ); scanf_s("%d", &L[i].data); i++; } L[i - 1].cursor = 0; L[0].cursor = i; }
(7)插入数据:单个数据插入
int Interposition(StaticLinkedListArray L,int i,ElemType e) {/*插入单个数据:i为需要插入的位置,e为需要插入的数据*/ if ((i > L[MAXSIZE - 1].data + 1) || (L[MAXSIZE - 1].data >= MAXSIZE - 2)) return ERROR;/*若果插入位置超出静态链表长度或者超出静态链表的空间,则返回错误*/ int k,j=1; k = MAXSIZE - 1;/*获取头结点的下标*/ ++L[MAXSIZE - 1].data;/*静态链表长度加1*/ while (j < i)/*查询第i-1位置上的数据的下标*/ { k = L[k].cursor; j++; } j = AllocateSpace(L);/*获取空位置的下标*/ L[j].data = e; L[j].cursor = L[k].cursor; L[k].cursor = j; return OK; }
(8)插入数据:批量插入数据
int InterpositionS(StaticLinkedListArray L) {/*批量插入数据*/ int number,k,i=0,e;/*number 输入数据的数目;k 插入的位置;e 插入的数据*/ printf("请输入需要插入数据的数目:"); scanf_s("%d", &number); if ((L[MAXSIZE].data + number) > MAXSIZE - 2) return ERROR;/*当所剩空间不够时,返回错误*/ printf("请输入需要插入的位置:"); scanf_s("%d", &k); while (i < number) { printf("请输入需要插入的第%d个数据:", i+1); scanf_s("%d", &e); Interposition(L, k + i, e); i++; } return OK; }
(9)释放空间
int FreeSpace(StaticLinkedListArray L,int k) {/*释放空间*/ if (k > L[MAXSIZE].data) return ERROR; L[k].cursor = L[0].cursor; L[0].cursor = k; return OK; }
(10)删除数据:按数据删除
int DeleteData(StaticLinkedListArray L, ElemType e) {/*删除数据:按数据删除*/ int k = MAXSIZE-1,kk; while (L[L[k].cursor].data != e && L[L[k].cursor].cursor != 0) k = L[k].cursor; if (L[L[k].cursor].data == e) { --L[MAXSIZE-1].data; kk = L[k].cursor; L[k].cursor = L[kk].cursor; FreeSpace(L, kk); return OK; } return ERROR; }
(11)删除数据:按位置删除
int DeleteAddress(StaticLinkedListArray L, int k) {/*删除数据:按位置删除*/ if (k > L[MAXSIZE - 1].data) return ERROR; int i = 1,t,tt; --L[MAXSIZE - 1].data;/*链表长度减1*/ t = MAXSIZE - 1;/*获取头结点的下标*/ while (i < k)/*寻找需要删除的位置之前的那一个位置*/ { t = L[t].cursor; i++; } tt = L[t].cursor;/*获取删除位置的下标*/ L[t].cursor = L[tt].cursor; FreeSpace(L,tt); return OK; }
(12)查询数据:按值查询
int ReferData(StaticLinkedListArray L, ElemType e) {/*查询数据:按值查询*/ int i = L[MAXSIZE - 1].cursor; while (L[i].data != e && L[i].cursor != 0) i = L[i].cursor; if (L[i].data == e) { printf("%d的下标为:%d\n", e, i); return L[i].data; } printf("不存在该数据!\n"); return ERROR; }
(13)查询数据:按位置查询
int ReferAddress(StaticLinkedListArray L, int k) {/*查询数据:按位置查询*/ if (k > L[MAXSIZE - 1].data) { printf("不存在该位置!\n"); return ERROR; } int i = 1,j; j = L[MAXSIZE - 1].cursor; while (i++ < k) j = L[j].cursor; printf("静态链表第%d个位置的下标为:%d\t数据为:%d\n",k,j, L[j].data); return L[j].data; }
(14)测试代码(编译环境:Visual Studio 2017)
#include<stdio.h> #define OK 1 #define ERROR 0 #define MAXSIZE 27 typedef int ElemType; typedef struct StaticLinkedList {/*静态链表的数据存储*/ /*StaticLinkedListArray[0]相当于备用链表的头结点(将为静态链表中未储存数据的部分视为备份链表),不用于存储需要使用的数据,cursor存储静态链表的备用空表的第一个结点的下标(即第一个没有存储数据的结点的下标),当cursor=0时,表示该静态链表已满*/ /*StaticLinkedListArray[MAXSIZE-1]也不存放数据,相当于该静态链表的头结点(存储数据部分),data存储静态链接表的长度(不包括第一个结点),cursor存放数组中第一个数据所在位置的下标(不是头结点),若cursor=0则表示该链表为空*/ /*数组的最后一个结点StaticLinkedListArray[MAXSIZE-1]也不存放数据,该结点的cursor存放数组中第一个数组所在的结点的下标(不是头结点)* /*静态链表中最后一个数据所在的位置的cursor=0,即指向备用链表的头结点*/ ElemType data; int cursor;/*存放下一个数据的下标*/ }StaticLinkedList, StaticLinkedListArray[MAXSIZE]; void Initialization(StaticLinkedListArray L) {/*初始化静态链表*/ int i = 1; while (i < MAXSIZE) L[i-1].cursor = i++; L[MAXSIZE - 1].data = 0;/*初始化静态链表的数据个数*/ L[MAXSIZE - 1].cursor = 0;/*初始化静态链表的头结点的指向*/ } void Display(StaticLinkedListArray L) {/*输出静态链表的长度及数据*/ if (L[MAXSIZE - 1].data == 0) printf("静态链表为空!\n"); else { int i = L[MAXSIZE-1].cursor;/*获取第一个数据的下标*/ printf("静态链表的长度为:%d\n静态链表中的数据为:", L[MAXSIZE - 1].data); while (i != 0) {/*当输出到最后一个数据,即cursor==0后,退出循环*/ printf("%3d", L[i].data); i = L[i].cursor;/*获取下一个数据的下标*/ } putchar('\n'); } } int AllocateSpace(StaticLinkedListArray L) {/*分配空间,返回下标*/ if (L[MAXSIZE-1].data >=MAXSIZE-2) return ERROR;/*当静态链表已满时,返回错误*/ int j = L[0].cursor;/*获取备用链表的第一个下标*/ L[0].cursor = L[j].cursor;/*备用链表头结点存放的下标后移一位*/ return j; }void InitializationData(StaticLinkedListArray L) {/*输入初始化静态链表的数据*/ int i=1; L[MAXSIZE - 1].cursor = 1; printf("请输入初始化创建数据的数目:"); scanf_s("%d", &L[MAXSIZE-1].data); while (i <= L[MAXSIZE - 1].data) { printf("请输入第%d个数据:", i ); scanf_s("%d", &L[i].data); i++; } L[i - 1].cursor = 0; L[0].cursor = i; } int Interposition(StaticLinkedListArray L,int i,ElemType e) {/*插入单个数据:i为需要插入的位置,e为需要插入的数据*/ if ((i > L[MAXSIZE - 1].data + 1) || (L[MAXSIZE - 1].data >= MAXSIZE - 2)) return ERROR;/*若果插入位置超出静态链表长度或者超出静态链表的空间,则返回错误*/ int k,j=1; k = MAXSIZE - 1;/*获取头结点的下标*/ ++L[MAXSIZE - 1].data;/*静态链表长度加1*/ while (j < i)/*查询第i-1位置上的数据的下标*/ { k = L[k].cursor; j++; } j = AllocateSpace(L);/*获取空位置的下标*/ L[j].data = e; L[j].cursor = L[k].cursor; L[k].cursor = j; return OK; } int InterpositionS(StaticLinkedListArray L) {/*批量插入数据*/ int number,k,i=0,e;/*number 输入数据的数目;k 插入的位置;e 插入的数据*/ printf("请输入需要插入数据的数目:"); scanf_s("%d", &number); if ((L[MAXSIZE].data + number) > MAXSIZE - 2) return ERROR;/*当所剩空间不够时,返回错误*/ printf("请输入需要插入的位置:"); scanf_s("%d", &k); while (i < number) { printf("请输入需要插入的第%d个数据:", i+1); scanf_s("%d", &e); Interposition(L, k + i, e); i++; } return OK; } int FreeSpace(StaticLinkedListArray L,int k) {/*释放空间*/ if (k > L[MAXSIZE].data) return ERROR; L[k].cursor = L[0].cursor; L[0].cursor = k; return OK; } int DeleteData(StaticLinkedListArray L, ElemType e) {/*删除数据:按数据删除*/ int k = MAXSIZE-1,kk; while (L[L[k].cursor].data != e && L[L[k].cursor].cursor != 0) k = L[k].cursor; if (L[L[k].cursor].data == e) { --L[MAXSIZE-1].data; kk = L[k].cursor; L[k].cursor = L[kk].cursor; FreeSpace(L, kk); return OK; } return ERROR; } int DeleteAddress(StaticLinkedListArray L, int k) {/*删除数据:按位置删除*/ if (k > L[MAXSIZE - 1].data) return ERROR; int i = 1,t,tt; --L[MAXSIZE - 1].data;/*链表长度减1*/ t = MAXSIZE - 1;/*获取头结点的下标*/ while (i < k)/*寻找需要删除的位置之前的那一个位置*/ { t = L[t].cursor; i++; } tt = L[t].cursor;/*获取删除位置的下标*/ L[t].cursor = L[tt].cursor; FreeSpace(L,tt); return OK; } int ReferData(StaticLinkedListArray L, ElemType e) {/*查询数据:按值查询*/ int i = L[MAXSIZE - 1].cursor; while (L[i].data != e && L[i].cursor != 0) i = L[i].cursor; if (L[i].data == e) { printf("%d的下标为:%d\n", e, i); return L[i].data; } printf("不存在该数据!\n"); return ERROR; } int ReferAddress(StaticLinkedListArray L, int k) {/*查询数据:按位置查询*/ if (k > L[MAXSIZE - 1].data) { printf("不存在该位置!\n"); return ERROR; } int i = 1,j; j = L[MAXSIZE - 1].cursor; while (i++ < k) j = L[j].cursor; printf("静态链表第%d个位置的下标为:%d\t数据为:%d\n",k,j, L[j].data); return L[j].data; } void Menu() { printf("程序功能菜单:\n0:菜单\n1:初始化静态链表及输入初始化数据\n2:插入数据\n3:输出数据\n4:删除数据:按数据删除\n" "5:删除数据:按位置删除\n6:查询数据:按数据查询\n7:查询数据:按位置查询\n8:退出程序\n"); } int main(void) { int i = 0,e; StaticLinkedListArray L; while (i != 8) { switch (i) { case 0: Menu(); break; case 1: Initialization(L); printf("初始化成功!\n"); InitializationData(L); Display(L); break; case 2: InterpositionS(L); Display(L); break; case 3: Display(L); break; case 4: printf("请输入需要删除的数据:"); scanf_s("%d", &e); DeleteData(L, e); Display(L); break; case 5: printf("请输入需要删除的位置:"); scanf_s("%d", &e); DeleteAddress(L, e); Display(L); break; case 6: printf("请输入需要查询的数据:"); scanf_s("%d", &e); ReferData(L, e); break; case 7: printf("请输入需要查询的位置:"); scanf_s("%d", &e); ReferAddress(L, e); break; default: printf("不存在该功能选项!\n"); break; } printf("请输入需要执行的功能选项:"); scanf_s("%d", &i); } printf("感谢您的使用!\n"); return 0; }
运行结果
相关文章推荐
- 【数据结构与算法】静态链表的游标实现
- 数据结构 学习笔记之:静态链表--史上最简单的C语言实现——只为掌握概念——不清楚静态链表的鸟鸟们有福了!
- 数据结构与算法笔记 —— 排序算法及代码实现
- 3、数据结构笔记之三线性表单项链表实现
- 【数据结构与算法学习笔记】PART2 向量(接口与实现,可扩充向量,无序向量,有序向量)
- C++学习笔记-数据结构-单链表的实现
- 数据结构之线性表代码实现顺序存储,链式存储,静态链表(选自大话数据结构)
- 33. 数据结构笔记之三十三广义表实现二
- 9、数据结构笔记之九栈的应用之行编辑实现
- 17、数据结构笔记之十七链表实现多项式
- 数据结构笔记(一)线性表的顺序表示和基本操作及其顺序表实现的集合运算(A-B)U(B-A)实例
- 32. 数据结构笔记之三十二广义表实现一
- 6、数据结构笔记之六链队列实现
- 数据结构与算法学习笔记——链表部分实现(数组形式)
- 10、数据结构笔记之十栈的应用之迷宫求解实现
- 19、数据结构笔记之十九链表实现等价类寻找
- 40. 数据结构笔记之四十图的邻接多重链表表示实现
- 数据结构——静态链表模板类实现
- 数据结构笔记及Java实现 (排序)
- 笔记:分别用Python、Perl实现对远程服务的访问,并对返回的JSON结构的数据进行处理