静态链表的C实现(基于数据结构 严蔚敏)
静态链表是利用一维数组实现逻辑上的单链表结构,结点的逻辑上相邻但物理位置上不一定相邻,因为内存分配上是一次性的,故称为静态。
特点:
- 预先需要一片连续的存储空间;
- 非随机存取;
- 无现成的“内存”分配和回收函数,得自己实现;
- 最多存储MAXSIZE - 1个数据;
核心包含了两个链表:
- 数据链表(初始化完成后需记住头结点,一般为数组的第1个分量)
- 备用的空闲链表(数组的第0个分量是备用链表的头结点)
- 注意逻辑位序和物理位序,实际上并没有利用物理位序的使用操作,牢牢记住它只是一个单链表
这两个链表都需要自己维护。

核心函数 :
- "内存"申请函数 int Malloc_SL();该函数返回申请的结点下标。
- "内存"释放函数void Free_SL(int k);释放逻辑位序k。
注意函数:
- void InitSpace_SL();该函数初始化链表空间,不做其他操作;
- int InitList_SL(SLinkList *h);该函数初始化数据链表并返回数据链表的头结点,这个头结点h非常重要,书本上没有这个函数的介绍,导致有些人搞不懂对数据链表的操作该如何进;
Status.h文件
#ifndef STSTUS_H
#define STSTUS_H #define TRUE 1 //真
#define FALSE 0 //假 #define YES 1 //是
#define NO 0 //否 #define OK 1 //通过
#define ERROR 0 //错误 #define SUCCESS 1 //成功
#define UNSUCCESS 0 //失败
#define INFEASIBLE -1 //不可行 #define OVERFLOW -2 //堆栈上溢
#define UNDERFLOW -3 //堆栈下溢 typedef int Status; #define PressEnter \
{\
fflush(stdin);\
printf("Press Enter...");\
getchar();\
fflush(stdin);\
} #endif
StaticLinkedList.h文件
#ifndef STATICLINKEDLIST_H_
#define STATICLINKEDLIST_H_ #include "Status.h" #define MAXSIZE 30
typedef int ElementType;
typedef int SLinkList; typedef struct
{
ElementType data;
int cur;
}Component[MAXSIZE]; //初始化,将一维数组Space中各分量链成一个大的备用空间
void InitSpace_SL(); //为插入的输入申请空间,从备用空间取得一个结点,返回分配结点下标
int Malloc_SL(); //将下标为k的空闲结点回收
void Free_SL(int k); //初始化静态链表,建立头结点,返回头结点下标
int InitList_SL(SLinkList *h); //置空
Status ClearList_SL(SLinkList h); //销毁
void DestroyList_SL(SLinkList* h); //判空
Status ListEmpty_SL(SLinkList h); //求长
int ListLength_SL(SLinkList h); //取值
//h--头结点,i--逻辑位置(1->maxsize-2),e--返回值
Status GetElem_SL(SLinkList h, int i, ElementType* e); //返回元素e的位序
int LocateElem_SL(SLinkList h, ElementType e); //前驱
//找值为cur_e的结点的前一个结点的值
Status PriorElem_SL(SLinkList h, ElementType cur_e, ElementType* pre_e); //后继
Status NextElem_SL(SLinkList h, ElementType cur_e, ElementType* next_e); //插入
//在逻辑上第i个位置前插入数据,使其成为第i个位置
//i从1开始
Status ListInsert_SL(SLinkList h, int i, ElementType e); //删除
Status ListDelete_SL(SLinkList h, int i, ElementType* e); //遍历
Status ListTraverse_SL(SLinkList h, void(Visit)(ElementType)); #endif
StaticLinkedList.cpp文件
#include "stdafx.h"
#include <cstdlib> #include "StaticLinkedList.h" //定义静态链表空间
Component Space; void InitSpace_SL()
{ //初始化备用空间,形成备用链表 for (size_t i = ; i < MAXSIZE - ; ++i) //将0号单元做备用空间的起始结点
{
Space[i].cur = i + ; //各空间结点逻辑上首尾相连
}
Space[MAXSIZE - ].cur = ; //最后一个结点下标指向NULL = 0,相当于链表的尾指针
} int Malloc_SL()
{
int i = Space[].cur; if (Space[].cur)
{
//将申请到的空间从备用链表空间中断开,并为下一个空闲结点做准备,即将下一个空闲结点链接到s[0]下
Space[].cur = Space[i].cur;
return i; //返回申请到的空间下标
}
return ; //申请失败返回0
} void Free_SL(int k)
{
Space[k].cur = Space[].cur; //将k结点的下个结点置为备用链表的第一个结点
Space[].cur = k; //将K结点置为备用空间的第一个结点
} 38 int InitList_SL(SLinkList * h)
39 {
40 *h = Malloc_SL(); //创建头结点
41 if (!(*h))
42 {
43 exit(OVERFLOW); //空间已满
44 }
45
46 Space[*h].cur = 0; //头结点游标置为0
47 return OK;
48 } Status ClearList_SL(SLinkList h)
{
int p;
if (!h)
{
return ERROR;
}
p = Space[h].cur; //p指向第一个结点
while (p)
{
Space[h].cur = Space[p].cur; //从数据链表首结点开始删除
Free_SL(p);
p = Space[h].cur;
} return OK;
} void DestroyList_SL(SLinkList * h)
{
ClearList_SL(*h);
Free_SL(*h); //释放头结点
*h = ;
} Status ListEmpty_SL(SLinkList h)
{
if (h && !Space[h].cur)
{
return TRUE;
}
return FALSE;
} int ListLength_SL(SLinkList h)
{
if (!h)
{
exit(OVERFLOW);
} int count, p;
count = ;
p = Space[h].cur;
while (p)
{
count++;
p = Space[p].cur;
}
return count;
} Status GetElem_SL(SLinkList h, int i, ElementType * e)
{
//-2 去掉备用头结点和数组溢出两个
if (!h || i < || i > MAXSIZE - )
{
return ERROR;
} int count, p;
count = ;
p = Space[h].cur;
while (p)
{
count++; //先++,从第一个逻辑位置开始,count很重要,寻找操作都需要count计数
if (count == i)
{
*e = Space[p].data;
return OK;
}
p = Space[p].cur;
}
return ERROR;
} int LocateElem_SL(SLinkList h, ElementType e)
{
int k, count;
count = ;
if (h && Space[h].cur) //不为空表
{
k = Space[h].cur;
while (k && Space[k].data != e)
{
count++;
k = Space[k].cur;
}
if (k)
{
return count;
}
}
return ;
} Status PriorElem_SL(SLinkList h, ElementType cur_e, ElementType * pre_e)
{
int p, q;
if (h)
{
p = Space[h].cur;
if (p && Space[p].data != cur_e)
{
q = Space[p].cur;
while (q && Space[q].data != cur_e)
{
p = q; //用p记住前驱
q = Space[q].cur;
}
if (q)
{
*pre_e = Space[q].data;
return OK;
}
}
}
return ERROR;
} Status NextElem_SL(SLinkList h, ElementType cur_e, ElementType * next_e)
{
int p;
if (h)
{
p = Space[h].cur;
if (p && Space[p].data != cur_e)
{
p = Space[p].cur; if (p && Space[p].cur)
{
p = Space[p].cur;
*next_e = Space[p].data;
return OK;
}
}
}
return ERROR;
} Status ListInsert_SL(SLinkList h, int i, ElementType e)
{
if (!h)
{
return ERROR;
} int count, k, p;
if (i > ) //
{
count = ;
k = h; while (k && count < i - ) //找到逻辑插入位置的前一个位置
{
count++;
k = Space[k].cur;
}
if (k) //找到第i-1个元素位置
{
p = Malloc_SL();
if (!p)
{
return ERROR;
}
Space[p].data = e;
Space[p].cur = Space[k].cur;
Space[k].cur = p; return OK;
}
}
return ERROR;
} Status ListDelete_SL(SLinkList h, int i, ElementType * e)
{
if (!h)
{
return ERROR;
} int count, k, p;
if (i > )
{
count = ;
k = h;
while (k && count < i -) //找到删除位置的前一个位置
{
count++;
k = Space[k].cur;
} if (k && Space[k].cur) //找到第i-1个元素却不是尾结点
{
p = Space[k].cur; //p指向第i结点
*e = Space[p].data;
Space[k].cur = Space[p].cur;
Free_SL(p); return OK;
}
}
return ERROR;
} Status ListTraverse_SL(SLinkList h, void(Visit)(ElementType))
{
if (!h)
{
return ERROR;
} int p = Space[h].cur;
while (p)
{
Visit(Space[p].data);
p = Space[p].cur;
} return OK;
}
Main函数
void PrintElem(ElementType e)
{
printf("%d ", e);
} int main()
{
SLinkList h; //数据链表头结点,全局
ElementType e;
int i; printf("初始化静态链表的备用空间Space....");
InitSpace_SL();
printf("\n");
PressEnter; printf("初始化静态链表头结点H,申请空间....");
InitList_SL(&h);
printf("\n");
PressEnter; ListEmpty_SL(h) ? printf("h为空!\n") : printf("h不为空!\n");
printf("\n");
PressEnter; for (size_t j = ; j < ; ++j)
{
printf("在h第%d个位置插入%d\n", j, * j);
ListInsert_SL(h, j, * j);
printf("\n");
}
printf("h中的元素为:h=");
ListTraverse_SL(h, PrintElem);
printf("\n");
PressEnter; printf("h的长度为%d\n", ListLength_SL(h));
printf("\n");
PressEnter; ListDelete_SL(h, , &e);
printf("删除h中第 4 个元素 %d,用Free_SL释放空间....", e);
printf("\n");
PressEnter; printf("删除后h中的元素为:h=");
ListTraverse_SL(h, PrintElem);
printf("\n");
PressEnter; printf("元素8在h中的位序为%d\n",LocateElem_SL(h,));
printf("\n"); printf("清空h前:");
ListEmpty_SL(h) ? printf("h为空!\n") : printf("h不为空!\n");
ClearList_SL(h);
printf("清空h后:");
ListEmpty_SL(h) ? printf("h为空!\n") : printf("h不为空!\n");
printf("\n");
PressEnter; printf("销毁h前:");
h ? printf("h存在!\n") : printf("h不存在!\n");
DestroyList_SL(&h);
printf("销毁h后:");
h ? printf("h存在!\n") : printf("h不存在!\n");
printf("\n");
PressEnter;
return ;
}
静态链表的C实现(基于数据结构 严蔚敏)的更多相关文章
- [数据结构]严蔚敏版(C数据结构)配套实现程序111例
以下为根据严蔚敏版数据结构的示例和概念实现的程序 目录 一.严蔚敏版(C数据结构)配套实现程序111例 1.数组与字符串 2.栈与队列 3.链表LinkList 4.树与二叉树 5.排序相关算法 6. ...
- 基于c语言数据结构+严蔚敏——线性表章节源码,利用Codeblocks编译通过
白天没屌事,那我们就来玩玩线性表的实现吧,快要失业了,没饭吃了咋整哦 题目描述假设利用两个线性表LA和LB分别表示两个集合A和B(即:线性表中的数据元素即为集合中的成员),现要求一个新的集合A=A∪B ...
- 【Java】 大话数据结构(3) 线性表之静态链表
本文根据<大话数据结构>一书,实现了Java版的静态链表. 用数组描述的链表,称为静态链表. 数组元素由两个数据域data和cur组成:data存放数据元素:cur相当于单链表中的next ...
- 【数据结构】单链表&&静态链表详解和代码实例
喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 单链表(Singly Linked List ) 1.1 什么是单链表? 单链表是一种链式存储的结构.它动态的为节点分配存 ...
- Java数据结构-线性表之静态链表
静态链表的定义: 节点由一个一维数组和一个指针域组成,数组用来存放数据元素,而指针域里面的指针(又称游标)用来指向下一个节点的数组下标. 这种链表称之为静态链表. 链表中的数组第一个和最后一个位置须要 ...
- java与数据结构(2)---java实现静态链表
结点类 1 //结点类 2 class Node<T> { 3 private T data; 4 private int cursor; 5 6 Node(T data, int cur ...
- 静态链表C语言数据结构
静态链表就是将数组实现单链表: int Malloc_SLL(StaticLinkList space) { int i = space[0].cur;//取得第一个头节点的下标 if( space[ ...
- 数据结构6: 静态链表及C语言实现
本节继续介绍线性表的另外一种链式表示——静态链表.(前面介绍的链表称为 动态链表 ). 逻辑结构上相邻的数据元素,存储在指定的一块内存空间中,数据元素只允许在这块内存空间中随机存放,这样的存储结构生成 ...
- 基于C++的STL的vector实现静态链表,要求包含插入,删除,和查找功能
//main.cpp部分 #include"List.cpp" int main() { StaticList<int> SL; SL.Insert(,); SL.In ...
随机推荐
- Java微服务对UTC时间格式的处理
一.背景 先说一下为什么要使用UTC时间.开发一个全球化的系统,服务端(Java微服务)集中部署在同一个地方,用户在全球通过浏览器.手机客户端访问.不同地区的时区是不一样的,同一个时间戳,不同的用户看 ...
- 反射、Attribute
1.发射是对类或者对象,查看其类内部的构造. 2.类的组成:属性(PropertyInfo).方法(MethodInfo).字段(FiedInfo).构造函数(ConstructorInfo).事件( ...
- 团体程序设计天梯赛 L1-034.点赞
描述 微博上有个"点赞"功能,你可以为你喜欢的博文点个赞表示支持.每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性.本题就要求你写个程序,通过统计一个人 ...
- Django admin 组件 原理分析与扩展使用 之 sites.py (一)
一 . 前言 Django 提供了admin 组件 为项目提供基本的管理后台功能(对数据表的增删改查). 本篇文章通过 admin源码 简单分析admin 内部原理 ,扩展使用方式,为以后进行定制和自 ...
- Java对于特殊字符做间隔读入的处理(1.3.4)
先读进字符串,然后再用split分割,注意当默认间隔符有其他意义时,要用\转义字符转义 这道题是pat的一道题,主要读入方法看前面就行了 import java.util.Scanner; publi ...
- Linux shell 脚本(一)
一.初识脚本 shell:一类介于系统内核与用户之间的解释程序.脚本:一类使用特定语言,按预设顺序执行的文件批处理.宏.解释型程序创建shell脚本:理清任务过程--整理执行语句--完善文件结构1.任 ...
- Unity3D打包 将发布的exe文件打包成一个Windows安装文件(自解压文件)
Unity打包Standalone时 会出现一个exe文件和一个data文件夹 可是我们平常见过的软件 基本没有这种像这种结构的 一般都是一个安装文件,然后点击安装,选择路径,生成快捷方式- 本篇博客 ...
- 用disabled属性修饰a标签,a标签仍然能点击
1.不知道各位同学有没有遇到跟我相同的问题,就是用jQuery操作a标签disabled的,来控制重复提交表单 做过开发的都知道,表单验证重复提交,包含前端和后端,两方面的控制.前端控制使我们常用的手 ...
- [模拟赛] T3 Exploit
Description 4X概念体系,是指在PC战略游戏中一种相当普及和成熟的系统概念,得名自4个同样以"EX"为开头的英语单词. eXplore(探索) eXpand(拓张与发展 ...
- [机器学习Lesson 1 Introduction] 机器学习的动机与应用
1. Machine Learning definition(机器学习定义) Arthur Samuel(1959年)将机器学习非正式定义为:在不直接针对问题进行编程的情况下,赋予计算机学习能力的一个 ...