静态链表是利用一维数组实现逻辑上的单链表结构,结点的逻辑上相邻但物理位置上不一定相邻,因为内存分配上是一次性的,故称为静态。

特点:

  • 预先需要一片连续的存储空间;
  • 非随机存取;
  • 无现成的“内存”分配和回收函数,得自己实现;
  • 最多存储MAXSIZE - 1个数据;

核心包含了两个链表:

  • 数据链表(初始化完成后需记住头结点,一般为数组的第1个分量)
  • 备用的空闲链表(数组的第0个分量是备用链表的头结点)
  • 注意逻辑位序和物理位序,实际上并没有利用物理位序的使用操作,牢牢记住它只是一个单链表

这两个链表都需要自己维护。

核心函数 :

  • "内存"申请函数 int Malloc_SL();该函数返回申请的结点下标。
  • "内存"释放函数void Free_SL(int k);释放逻辑位序k。

注意函数:

  • void InitSpace_SL();该函数初始化链表空间,不做其他操作;
  • int InitList_SL(SLinkList *h);该函数初始化数据链表并返回数据链表的头结点,这个头结点h非常重要,书本上没有这个函数的介绍,导致有些人搞不懂对数据链表的操作该如何进;
  1.  

Status.h文件

  1. #ifndef STSTUS_H
  2. #define STSTUS_H
  3.  
  4. #define TRUE 1 //真
  5. #define FALSE 0 //假
  6.  
  7. #define YES 1 //是
  8. #define NO 0 //否
  9.  
  10. #define OK 1 //通过
  11. #define ERROR 0 //错误
  12.  
  13. #define SUCCESS 1 //成功
  14. #define UNSUCCESS 0 //失败
  15. #define INFEASIBLE -1 //不可行
  16.  
  17. #define OVERFLOW -2 //堆栈上溢
  18. #define UNDERFLOW -3 //堆栈下溢
  19.  
  20. typedef int Status;
  21.  
  22. #define PressEnter \
  23. {\
  24. fflush(stdin);\
  25. printf("Press Enter...");\
  26. getchar();\
  27. fflush(stdin);\
  28. }
  29.  
  30. #endif

StaticLinkedList.h文件

  1. #ifndef STATICLINKEDLIST_H_
  2. #define STATICLINKEDLIST_H_
  3.  
  4. #include "Status.h"
  5.  
  6. #define MAXSIZE 30
  7. typedef int ElementType;
  8. typedef int SLinkList;
  9.  
  10. typedef struct
  11. {
  12. ElementType data;
  13. int cur;
  14. }Component[MAXSIZE];
  15.  
  16. //初始化,将一维数组Space中各分量链成一个大的备用空间
  17. void InitSpace_SL();
  18.  
  19. //为插入的输入申请空间,从备用空间取得一个结点,返回分配结点下标
  20. int Malloc_SL();
  21.  
  22. //将下标为k的空闲结点回收
  23. void Free_SL(int k);
  24.  
  25. //初始化静态链表,建立头结点,返回头结点下标
  26. int InitList_SL(SLinkList *h);
  27.  
  28. //置空
  29. Status ClearList_SL(SLinkList h);
  30.  
  31. //销毁
  32. void DestroyList_SL(SLinkList* h);
  33.  
  34. //判空
  35. Status ListEmpty_SL(SLinkList h);
  36.  
  37. //求长
  38. int ListLength_SL(SLinkList h);
  39.  
  40. //取值
  41. //h--头结点,i--逻辑位置(1->maxsize-2),e--返回值
  42. Status GetElem_SL(SLinkList h, int i, ElementType* e);
  43.  
  44. //返回元素e的位序
  45. int LocateElem_SL(SLinkList h, ElementType e);
  46.  
  47. //前驱
  48. //找值为cur_e的结点的前一个结点的值
  49. Status PriorElem_SL(SLinkList h, ElementType cur_e, ElementType* pre_e);
  50.  
  51. //后继
  52. Status NextElem_SL(SLinkList h, ElementType cur_e, ElementType* next_e);
  53.  
  54. //插入
  55. //在逻辑上第i个位置前插入数据,使其成为第i个位置
  56. //i从1开始
  57. Status ListInsert_SL(SLinkList h, int i, ElementType e);
  58.  
  59. //删除
  60. Status ListDelete_SL(SLinkList h, int i, ElementType* e);
  61.  
  62. //遍历
  63. Status ListTraverse_SL(SLinkList h, void(Visit)(ElementType));
  64.  
  65. #endif

StaticLinkedList.cpp文件

  1. #include "stdafx.h"
  2. #include <cstdlib>
  3.  
  4. #include "StaticLinkedList.h"
  5.  
  6. //定义静态链表空间
  7. Component Space;
  8.  
  9. void InitSpace_SL()
  10. { //初始化备用空间,形成备用链表
  11.  
  12. for (size_t i = ; i < MAXSIZE - ; ++i) //将0号单元做备用空间的起始结点
  13. {
  14. Space[i].cur = i + ; //各空间结点逻辑上首尾相连
  15. }
  16. Space[MAXSIZE - ].cur = ; //最后一个结点下标指向NULL = 0,相当于链表的尾指针
  17. }
  18.  
  19. int Malloc_SL()
  20. {
  21. int i = Space[].cur;
  22.  
  23. if (Space[].cur)
  24. {
  25. //将申请到的空间从备用链表空间中断开,并为下一个空闲结点做准备,即将下一个空闲结点链接到s[0]下
  26. Space[].cur = Space[i].cur;
  27. return i; //返回申请到的空间下标
  28. }
  29. return ; //申请失败返回0
  30. }
  31.  
  32. void Free_SL(int k)
  33. {
  34. Space[k].cur = Space[].cur; //将k结点的下个结点置为备用链表的第一个结点
  35. Space[].cur = k; //将K结点置为备用空间的第一个结点
  36. }
  37.  
  38. 38 int InitList_SL(SLinkList * h)
  39. 39 {
  40. 40 *h = Malloc_SL(); //创建头结点
  41. 41 if (!(*h))
  42. 42 {
  43. 43 exit(OVERFLOW); //空间已满
  44. 44 }
  45. 45
  46. 46 Space[*h].cur = 0; //头结点游标置为0
  47. 47 return OK;
  48. 48 }
  49.  
  50. Status ClearList_SL(SLinkList h)
  51. {
  52. int p;
  53. if (!h)
  54. {
  55. return ERROR;
  56. }
  57. p = Space[h].cur; //p指向第一个结点
  58. while (p)
  59. {
  60. Space[h].cur = Space[p].cur; //从数据链表首结点开始删除
  61. Free_SL(p);
  62. p = Space[h].cur;
  63. }
  64.  
  65. return OK;
  66. }
  67.  
  68. void DestroyList_SL(SLinkList * h)
  69. {
  70. ClearList_SL(*h);
  71. Free_SL(*h); //释放头结点
  72. *h = ;
  73. }
  74.  
  75. Status ListEmpty_SL(SLinkList h)
  76. {
  77. if (h && !Space[h].cur)
  78. {
  79. return TRUE;
  80. }
  81. return FALSE;
  82. }
  83.  
  84. int ListLength_SL(SLinkList h)
  85. {
  86. if (!h)
  87. {
  88. exit(OVERFLOW);
  89. }
  90.  
  91. int count, p;
  92. count = ;
  93. p = Space[h].cur;
  94. while (p)
  95. {
  96. count++;
  97. p = Space[p].cur;
  98. }
  99. return count;
  100. }
  101.  
  102. Status GetElem_SL(SLinkList h, int i, ElementType * e)
  103. {
  104. //-2 去掉备用头结点和数组溢出两个
  105. if (!h || i < || i > MAXSIZE - )
  106. {
  107. return ERROR;
  108. }
  109.  
  110. int count, p;
  111. count = ;
  112. p = Space[h].cur;
  113. while (p)
  114. {
  115. count++; //先++,从第一个逻辑位置开始,count很重要,寻找操作都需要count计数
  116. if (count == i)
  117. {
  118. *e = Space[p].data;
  119. return OK;
  120. }
  121. p = Space[p].cur;
  122. }
  123. return ERROR;
  124. }
  125.  
  126. int LocateElem_SL(SLinkList h, ElementType e)
  127. {
  128. int k, count;
  129. count = ;
  130. if (h && Space[h].cur) //不为空表
  131. {
  132. k = Space[h].cur;
  133. while (k && Space[k].data != e)
  134. {
  135. count++;
  136. k = Space[k].cur;
  137. }
  138. if (k)
  139. {
  140. return count;
  141. }
  142. }
  143. return ;
  144. }
  145.  
  146. Status PriorElem_SL(SLinkList h, ElementType cur_e, ElementType * pre_e)
  147. {
  148. int p, q;
  149. if (h)
  150. {
  151. p = Space[h].cur;
  152. if (p && Space[p].data != cur_e)
  153. {
  154. q = Space[p].cur;
  155. while (q && Space[q].data != cur_e)
  156. {
  157. p = q; //用p记住前驱
  158. q = Space[q].cur;
  159. }
  160. if (q)
  161. {
  162. *pre_e = Space[q].data;
  163. return OK;
  164. }
  165. }
  166. }
  167. return ERROR;
  168. }
  169.  
  170. Status NextElem_SL(SLinkList h, ElementType cur_e, ElementType * next_e)
  171. {
  172. int p;
  173. if (h)
  174. {
  175. p = Space[h].cur;
  176. if (p && Space[p].data != cur_e)
  177. {
  178. p = Space[p].cur;
  179.  
  180. if (p && Space[p].cur)
  181. {
  182. p = Space[p].cur;
  183. *next_e = Space[p].data;
  184. return OK;
  185. }
  186. }
  187. }
  188. return ERROR;
  189. }
  190.  
  191. Status ListInsert_SL(SLinkList h, int i, ElementType e)
  192. {
  193. if (!h)
  194. {
  195. return ERROR;
  196. }
  197.  
  198. int count, k, p;
  199. if (i > ) //
  200. {
  201. count = ;
  202. k = h;
  203.  
  204. while (k && count < i - ) //找到逻辑插入位置的前一个位置
  205. {
  206. count++;
  207. k = Space[k].cur;
  208. }
  209. if (k) //找到第i-1个元素位置
  210. {
  211. p = Malloc_SL();
  212. if (!p)
  213. {
  214. return ERROR;
  215. }
  216. Space[p].data = e;
  217. Space[p].cur = Space[k].cur;
  218. Space[k].cur = p;
  219.  
  220. return OK;
  221. }
  222. }
  223. return ERROR;
  224. }
  225.  
  226. Status ListDelete_SL(SLinkList h, int i, ElementType * e)
  227. {
  228. if (!h)
  229. {
  230. return ERROR;
  231. }
  232.  
  233. int count, k, p;
  234. if (i > )
  235. {
  236. count = ;
  237. k = h;
  238. while (k && count < i -) //找到删除位置的前一个位置
  239. {
  240. count++;
  241. k = Space[k].cur;
  242. }
  243.  
  244. if (k && Space[k].cur) //找到第i-1个元素却不是尾结点
  245. {
  246. p = Space[k].cur; //p指向第i结点
  247. *e = Space[p].data;
  248. Space[k].cur = Space[p].cur;
  249. Free_SL(p);
  250.  
  251. return OK;
  252. }
  253. }
  254. return ERROR;
  255. }
  256.  
  257. Status ListTraverse_SL(SLinkList h, void(Visit)(ElementType))
  258. {
  259. if (!h)
  260. {
  261. return ERROR;
  262. }
  263.  
  264. int p = Space[h].cur;
  265. while (p)
  266. {
  267. Visit(Space[p].data);
  268. p = Space[p].cur;
  269. }
  270.  
  271. return OK;
  272. }

Main函数

  1. void PrintElem(ElementType e)
  2. {
  3. printf("%d ", e);
  4. }
  5.  
  6. int main()
  7. {
  8. SLinkList h; //数据链表头结点,全局
  9. ElementType e;
  10. int i;
  11.  
  12. printf("初始化静态链表的备用空间Space....");
  13. InitSpace_SL();
  14. printf("\n");
  15. PressEnter;
  16.  
  17. printf("初始化静态链表头结点H,申请空间....");
  18. InitList_SL(&h);
  19. printf("\n");
  20. PressEnter;
  21.  
  22. ListEmpty_SL(h) ? printf("h为空!\n") : printf("h不为空!\n");
  23. printf("\n");
  24. PressEnter;
  25.  
  26. for (size_t j = ; j < ; ++j)
  27. {
  28. printf("在h第%d个位置插入%d\n", j, * j);
  29. ListInsert_SL(h, j, * j);
  30. printf("\n");
  31. }
  32. printf("h中的元素为:h=");
  33. ListTraverse_SL(h, PrintElem);
  34. printf("\n");
  35. PressEnter;
  36.  
  37. printf("h的长度为%d\n", ListLength_SL(h));
  38. printf("\n");
  39. PressEnter;
  40.  
  41. ListDelete_SL(h, , &e);
  42. printf("删除h中第 4 个元素 %d,用Free_SL释放空间....", e);
  43. printf("\n");
  44. PressEnter;
  45.  
  46. printf("删除后h中的元素为:h=");
  47. ListTraverse_SL(h, PrintElem);
  48. printf("\n");
  49. PressEnter;
  50.  
  51. printf("元素8在h中的位序为%d\n",LocateElem_SL(h,));
  52. printf("\n");
  53.  
  54. printf("清空h前:");
  55. ListEmpty_SL(h) ? printf("h为空!\n") : printf("h不为空!\n");
  56. ClearList_SL(h);
  57. printf("清空h后:");
  58. ListEmpty_SL(h) ? printf("h为空!\n") : printf("h不为空!\n");
  59. printf("\n");
  60. PressEnter;
  61.  
  62. printf("销毁h前:");
  63. h ? printf("h存在!\n") : printf("h不存在!\n");
  64. DestroyList_SL(&h);
  65. printf("销毁h后:");
  66. h ? printf("h存在!\n") : printf("h不存在!\n");
  67. printf("\n");
  68. PressEnter;
  69. return ;
  70. }

静态链表的C实现(基于数据结构 严蔚敏)的更多相关文章

  1. [数据结构]严蔚敏版(C数据结构)配套实现程序111例

    以下为根据严蔚敏版数据结构的示例和概念实现的程序 目录 一.严蔚敏版(C数据结构)配套实现程序111例 1.数组与字符串 2.栈与队列 3.链表LinkList 4.树与二叉树 5.排序相关算法 6. ...

  2. 基于c语言数据结构+严蔚敏——线性表章节源码,利用Codeblocks编译通过

    白天没屌事,那我们就来玩玩线性表的实现吧,快要失业了,没饭吃了咋整哦 题目描述假设利用两个线性表LA和LB分别表示两个集合A和B(即:线性表中的数据元素即为集合中的成员),现要求一个新的集合A=A∪B ...

  3. 【Java】 大话数据结构(3) 线性表之静态链表

    本文根据<大话数据结构>一书,实现了Java版的静态链表. 用数组描述的链表,称为静态链表. 数组元素由两个数据域data和cur组成:data存放数据元素:cur相当于单链表中的next ...

  4. 【数据结构】单链表&&静态链表详解和代码实例

    喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 单链表(Singly Linked List ) 1.1 什么是单链表? 单链表是一种链式存储的结构.它动态的为节点分配存 ...

  5. Java数据结构-线性表之静态链表

    静态链表的定义: 节点由一个一维数组和一个指针域组成,数组用来存放数据元素,而指针域里面的指针(又称游标)用来指向下一个节点的数组下标. 这种链表称之为静态链表. 链表中的数组第一个和最后一个位置须要 ...

  6. java与数据结构(2)---java实现静态链表

    结点类 1 //结点类 2 class Node<T> { 3 private T data; 4 private int cursor; 5 6 Node(T data, int cur ...

  7. 静态链表C语言数据结构

    静态链表就是将数组实现单链表: int Malloc_SLL(StaticLinkList space) { int i = space[0].cur;//取得第一个头节点的下标 if( space[ ...

  8. 数据结构6: 静态链表及C语言实现

    本节继续介绍线性表的另外一种链式表示——静态链表.(前面介绍的链表称为 动态链表 ). 逻辑结构上相邻的数据元素,存储在指定的一块内存空间中,数据元素只允许在这块内存空间中随机存放,这样的存储结构生成 ...

  9. 基于C++的STL的vector实现静态链表,要求包含插入,删除,和查找功能

    //main.cpp部分 #include"List.cpp" int main() { StaticList<int> SL; SL.Insert(,); SL.In ...

随机推荐

  1. JavaScript的作用域

    JavaScript的作用域主要是指函数的作用域,在进行结果判断的时候十分重要,如果不清楚作用域,便很有可能导致拿不到预期的结果,也就无法顺利的进行程序的编写,在经历了一系列的学习和了解之后,对相关知 ...

  2. c# 图解泛型List<T>, HashTable和Dictionary<TKey,TValue>

    前辈在代码中使用了HashTable,由于我用的比较少,不能理解,为什么不用Dictionary?看了源码以及查阅资料,总结如下: 首先看看它们的继承体系: 我把list<T>的继承体系也 ...

  3. TypeScript入门知识三(函数新特性)

    一,Rest and Spread操作符: 用来声明任意数量的方法参数也就是"..."操作符 输出结果: 18 jajj 89 function test (a, b, c) { ...

  4. Linux shell 脚本(二)

    转载请标明出处:  http://blog.csdn.net/zwto1/article/details/45078837:  本文出自:[明月的博客] 五.字符串处理 1.子串截取操作: 路径分割: ...

  5. Javascript 基础知识2017-03-17

    JavaScript语法 1.单行注释:// 多行注释:*/ 2.基本数据类型:            int 整数型   (不等于四舍五入,把小数舍去)            string 字符型  ...

  6. java--计时器

    计时器 一.窗口化 public class Pro extends JFrame{ private JTextField textField = new JTextField(45);//系统时间文 ...

  7. java 三种工厂模式

    一.简单工厂模式 一个栗子: 我喜欢吃面条,抽象一个面条基类,(接口也可以),这是产品的抽象类. public abstract class INoodles { /** * 描述每种面条啥样的 */ ...

  8. [Bzoj 2547] [Ctsc2002] 玩具兵

    2547: [Ctsc2002]玩具兵 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 317  Solved: 152[Submit][Status] ...

  9. Eclipse安卓开发环境搭建

    前提,Java SDK和Eclipse搭建完毕 下载android SDK并安装 (官网:http://sdk.android-studio.org/ ) 找到安装目录,运行“SDK Manager. ...

  10. 大数据 --> 淘宝异构数据源数据交换工具 DataX

    淘宝异构数据源数据交换工具 DataX DataX是什么? DataX是一个在异构的数据库/文件系统之间高速交换数据的工具,实现了在任意的数据处理系统(RDBMS/Hdfs/Local filesys ...