C 语言静态链表实现

C  语言静态链表实现

可运行源代码 staticlink.h


#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define MAX_SIZE 100

typedef int Status;
typedef int ElementType;

typedef struct StaticLinkList
{
ElementType data;
int cur;
}component,SLinkList[MAX_SIZE];

int Malloc(SLinkList space);
void Free(SLinkList space,int k);
void initList(SLinkList l);
void ClearList(SLinkList l);
Status GetElement(SLinkList l,int i,ElementType *e);
int LocateElement(SLinkList l,ElementType e);
Status PriorElement(SLinkList l,ElementType cur_e,ElementType *pre_e);
Status NextElement(SLinkList l,ElementType cur_e,ElementType *next_e);
Status ListInsert(SLinkList l,int i,ElementType e);
Status ListDelete(SLinkList l,int i,ElementType *e);
void ListTraverse(SLinkList l, void (*visit)(ElementType));
void print1(ElementType e);

staticlink.c


#include <stdio.h>
#include "staticlink.h"
//备用链表不为空返回分配的结点下标
int Malloc(SLinkList space)
{
int i = space[0].cur;
if(i)
space[0].cur = space[i].cur;//备用链表的头结点指向原备用链表的第二个空闲结点
return i;
}

//将下标为k的结点回收到备用链表中
void Free(SLinkList space,int k)
{
space[k].cur = space[0].cur;//回收结点游标指向备用链表的第一个结点
space[0].cur = k;//备用链表的头结点指向新回收的结点
}

/*构造一个空的链表l,表头为l,最后一个单元l[MAX_SIZE - 1],其他单元链成一个备用
链表,表头为l的第一个单元l[0],"0" 表示空指针
*/
void initList(SLinkList l)
{
int i;
l[MAX_SIZE - 1].cur = 0;//最后一个单元为空链表的表头
//其他单元链接成以l[0]为表头的备用链表
for(i = 0; i < MAX_SIZE - 2;i++)
{
l[i].cur = i+1;

}

}

//清空链表
void ClearList(SLinkList l)
{
int j,k,i=l[MAX_SIZE-1].cur;//i指向链表的第一个结点
l[MAX_SIZE-1].cur=0;//第一个结点为头结点表示链表为空
k=l[0].cur;//备用链表第一个结点的位置即第一个空闲结点的位置
l[0].cur = i;
while(i){
j = i;
i=l[i].cur;
}
l[j].cur = k;

}

Status ListEmpty(SLinkList l)
{
if(l[MAX_SIZE-1].cur == 0)
return TRUE;
else
return FALSE;
}

int ListLength(SLinkList l)
{
int j = 0,i=l[MAX_SIZE -1].cur;
while(i)
{
i = l[i].cur;
j++;

}

return j;
}

Status GetElement(SLinkList l,int i,ElementType *e)
{
int m,k=MAX_SIZE-1;
if(i<1||i>ListLength(l))
return ERROR;
for(m=1;m<=i;m++)
k=l[k].cur;
*e = l[k].data;
return OK;
}

int LocateElement(SLinkList l,ElementType e){
int i = l[MAX_SIZE-1].cur;
while(i && l[i].data !=e)
i = l[i].cur;
return i;

}

Status PriorElement(SLinkList l,ElementType cur_e,ElementType *pre_e){
int j,i=l[MAX_SIZE -1].cur;
do{
j = i;
i = l[i].cur;

}while(i && cur_e!=l[i].data);
if(i)
{
*pre_e=l[j].data;
return OK;

}else
return ERROR;

}

Status NextElement(SLinkList l,ElementType cur_e,ElementType *next_e){
int j,i=LocateElement(l,cur_e);
if(i)
{
j=l[i].cur;
if(j)
{
*next_e=l[j].data;
return OK;

}

}
return ERROR;

}

Status ListInsert(SLinkList l,int i,ElementType e){
int m,j,k=MAX_SIZE-1;
if(i < 1 || i > ListLength(l) + 1 )
return ERROR;
j=Malloc(l);
if(j)
{
l[j].data = e;
for(m =1;m<i;m++)
k=l[k].cur;
l[j].cur=l[k].cur;
l[k].cur = j;
return OK;

}
return ERROR;
}

Status ListDelete(SLinkList l,int i,ElementType *e){
int j,k=MAX_SIZE-1;
if(i < 1||i> ListLength(l))
return ERROR;
for(j =1;j<i;j++)
k=l[k].cur;
j=l[k].cur;
l[k].cur=l[j].cur;
*e=l[j].data;
Free(l,j);
return OK;
}

void print1(ElementType e){
printf("%3d",e);
}

void ListTraverse(SLinkList l, void (*visit)(ElementType)){
int i = l[MAX_SIZE -1].cur;
while(i){
visit(l[i].data);
i=l[i].cur;
}
printf("\n");

}

staticlinkmain.c


#include <stdio.h>
#include "staticlink.h"

int main(void){
SLinkList l;
int i,k,j;
ElementType e0,e1,e;
initList(l);
for(i=1;i<=5;i++)
ListInsert(l,i,i);
k=ListEmpty(l);
printf("表为空?k=%d(1:是0:否)",k);
printf("\n");
ListTraverse(l,print1);
printf("链表的长度%d",ListLength(l));
printf("\n");
printf("清空链表\n");
ClearList(l);
printf("清空后");
ListTraverse(l,print1);
printf("再次判断是否为空\n");
k=ListEmpty(l);
printf("表为空?k=%d(1:是0:否)",k);
printf("\n");
printf("再次插入元素\n");
for(i=1;i<=10;i++)
ListInsert(l,i,i);
ListTraverse(l,print1);
printf("链表的长度%d",ListLength(l));
printf("\n");

printf("前驱判断\n");
for(i=1;i<=10;i++){
GetElement(l,i,&e0);
k=PriorElement(l,e0,&e1);
if(k==ERROR)
printf("元素%d无前驱\n",e0);
else
printf("元素%d的前驱是%d\n",e0,e1);

}

printf("\n");
printf("\n");

printf("后继判断\n");

for(i=1;i<=10;i++)
{ GetElement(l,i,&e0);//把L中的第i个元素的值赋给e0
k=NextElement(l,e0,&e1);//求e0的前驱,成功的话赋给e1
if(k==ERROR)
printf("元素%d无后继\n",e0);
else
printf("元素%d的后继%d\n",e0,e1);
}

printf("\n删除元素\n");
k=ListLength(l);
for(j=k+1;j>0;j--)
{ i=ListDelete(l,j,&e);//删除第j个元素
if(i==ERROR)
printf("删除第%d个元素失败\n",j);
else
printf("删除第%d个元素成功,其值为%d\n",j,e);
}

return 0;
}

编译运行

gcc staticlink.h staticlink.c staticlinkmain.c -o staticlinkmain

运行结果

表为空?k=0(1:是0:否)
1 2 3 4
5
链表的长度5
清空链表
清空后
再次判断是否为空
表为空?k=1(1:是0:否)
再次插入元素
1 2 3
4 5 6 7 8 9
10
链表的长度10
前驱判断
元素1无前驱
元素2的前驱是1
元素3的前驱是2
元素4的前驱是3
元素5的前驱是4
元素6的前驱是5
元素7的前驱是6
元素8的前驱是7
元素9的前驱是8
元素10的前驱是9

后继判断
元素1的后继2
元素2的后继3
元素3的后继4
元素4的后继5
元素5的后继6
元素6的后继7
元素7的后继8
元素8的后继9
元素9的后继10
元素10无后继

删除元素
删除第11个元素失败
删除第10个元素成功,其值为10
删除第9个元素成功,其值为9
删除第8个元素成功,其值为8
删除第7个元素成功,其值为7
删除第6个元素成功,其值为6
删除第5个元素成功,其值为5
删除第4个元素成功,其值为4
删除第3个元素成功,其值为3
删除第2个元素成功,其值为2
删除第1个元素成功,其值为1

C 语言静态链表实现

时间: 2024-12-29 07:18:28

C 语言静态链表实现的相关文章

使用C语言描述静态链表和动态链表

静态链表和动态链表是线性表链式存储结构的两种不同的表示方式. 静态链表的初始长度一般是固定的,在做插入和删除操作时不需要移动元素,仅需修改指针,故仍具有链式存储结构的主要优点. 动态链表是相对于静态链表而言的,一般地,在描述线性表的链式存储结构时如果没有特别说明即默认描述的是动态链表. 下面给出它们的简单实现,关于线性表更为详尽的C语言的实现,可以参考 http://www.cnblogs.com/choon/p/3876606.html 静态链表 #define _CRT_SECURE_NO_

静态链表的实现与操作(C语言实现)

我们知道要实现单链表,必须要有指针,那么像Java这样没有指针的的语言就略显蛋疼了. 没关系,我们有静态链表,其本质就是用采用数组的方式实现单链表的功能. 头文件: #ifndef _StaticLinkList_H_ #define _StaticLinkList_H_ typedef void StaticLinkList; typedef void StaticLinkListNode; StaticLinkList * StaticLinkList_Create(int capacity

c语言:建立简单的静态链表,它由3个学生数据的结点组成,要求输出各结点的数据

建立简单的静态链表,它由3个学生数据的结点组成,要求输出各结点的数据. 解:将第1个结点的起始地址赋给头指针head,将第2个结点的起始地址赋给第1个结点的next成员,将第3个结点的起始地址赋给第2个结点的next成员.第3个结点的next成员赋予NULL,这就形成了链表.为了建立链表,使head指向a结点,a.next指向b结点,b.next指向c结点,c.next=NULL的作用是使c.next不指向任何有用的存储单元. 程序: #include<stdio.h> struct Stud

静态链表用C语言实现

静态链表便于在不设指针类型的高级语言使用链表结构,静态链表用数组描述,数组的一个分量表示一个结点,同时用游标(指示器cur)代替指针来表示结点在数组中的相对位置. 另外我们对数组第一个和最后一个元素作为特殊元素处理,不存数据.数组的第一个元素,即下标为0的元素的cur存放备用链表的第一个结点的下标,而数组 最后一个cur则存放第一个有效数值的下标,相当于单链表中有结点的作用. /* 2016年10月11日10:47:23 静态链表 */ #include<stdio.h> #define MA

静态链表----数据结构(C语言版) 算法2.17 心得

今天学习了数据结构中的静态链表,刚开始有些语句不能理解,研究了大半天终于想通了.记录于此留待以后查看,同时,对于同样对静态链表有些许不理解的人一点启发.文章中难免有理解上的问题,请指正.下面进入正文. 一.静态链表结构 静态链表可以在不设"指针"类型的高级程序设计语言中使用链表结构.静态链表如下所示:   首先,了解一下静态链表.静态链表中跟单链表类似,包含有很多结点,第i个结点中有包括数据space[i].data,和游标cur,游标space[i].cur的值为下一个结点的数组下标

静态链表 C语言描述

静态链表1.下标为0的游标存放最后存放数据节点的游标,即是第一个没有存放元素(备用链表)的下标2.最后一个的节点存放第一个由数值得下标3.第一个和最后一个都不存放数据 即是备用链表的第一个的下标 4.最后一个存储数据的节点的游标为0 静态链表主要是根据游标来遍历,以前没有指针用的思想 假如我要删除一个元素 图不多描述,自己画画就明白,然后代码部分.都有注释, 1 #include <stdio.h> 2 #define ElemType int 3 #define Status int 4 #

静态链表C语言数据结构

静态链表就是将数组实现单链表: 首先是获得空闲分量的下标: int Malloc_SLL(StaticLinkList space) { int i = space[0].cur; if( space[0].cur ) space[0].cur = space[i].cur; // 把它的下一个分量用来作为备用. return i; } /* 在静态链表L中第i个元素之前插入新的数据元素e */ Status ListInsert( StaticLinkList L, int i, ElemTy

【c++版数据结构】之用c语言实现静态链表

静态链表要解决的问题是:如何静态模拟动态链表关于存储空间申请和释放,动态链表可以借助malloc和free两个函数实现.在静态链表中,由于操作的是数组,不存在像动态链表的节点申请和释放问题,因此我们得自己完成两个函数来模拟这两个动作. 解决办法: 将静态链表划分为"有效链表,备用链表",通过两者模拟节点的申请和释放 静态链表: 1)有效链表(已经使用的数组元素按游标cur链接而成) 2)备用链表(未使用的数组元素按游标cur链接而成) Malloc_SL(申请节点):从备用链表中取得一

静态链表-C语言实现

1.静态链表是在没有指针的编程语言里对链表的一种实现2.主要是用数组模拟指针3.在这里,使用结构体使数组的每一个空间可以存储一个数据元素(date)和一个游标(cur),游标的作用相当于链表的指针域,用于记录下一元素的下标是多少4.在没有结构体(typedef)的语言中,也可以使用两个并行数组实现此功能 此种结构在编程中不一定能用得到,但是这种思想非常巧妙,非常值得我们学习,不多说,直接上代码,亲测可行,有详细注释 #include<stdio.h> #define MAXSIZE 1000