静态链表(图一乐)c语言具体实现

特点

基于数组实现,不依赖指针

具体实现

定义
  • 使用游标cur(表示下一个元素数组下标)代替next指针
#define MAXSIZE 1000                    //链表最大长度 

typedef struct{
	int data;
	int cur;
}Component,StackLinkList[MAXSIZE];      //直接定义数组 
初始化
  • 数组首位存储第一个空闲位置下标(备用链表头结点),备用于分配
  • 数组末位存储第一个元素(按静态链表顺序)下标,类似头结点
  • 数组每个位置默认指向下一位(默认顺序排列)
  • 数组末位设为0,用以表示链表结尾(链表此时为空,数组末位同时表示开头及结尾),类似单链表中最后一个节点指向NULL)
int InitList(StackLinkList space){
	int i = 0;
	for(int i = 0;i < MAXSIZE-1;i++){
		space[i].cur = i+1;             //默认指向数组下一位 
	}
	space[MAXSIZE-1].cur = 0;         //初始时,设置链表尾端为0
} 

分配节点

单链表操作中通过动态分配空间,创造节点。
malloc在堆区通过扫描空闲链表,找到足够大小的内存块,并分配存储空间
类似的,通过数组首位找到当前空闲结点(即未使用数组位置),实现分配节点
同时,将数组首位更新指向下一个可用地址

int Malloc(StackLinkList space){
	int i = space[0].cur;	           //返回一个备用的空闲下标
	if(space[i].cur)                    //不为0
		space[0].cur = space[i].cur;    //指向下一个空闲节点 
	return i; 
}
插入元素
  • 通过数组末位(“头结点”),遍历链表,找到第i-1个元素,在其后插入(类似单链表操作)
void ListInsert(StackLinkList space,int i,int e){
	int j,k,l;
	k = MAXSIZE - 1;
	if(i < 1 || i > ListLength(space) + 1)  //可以在最后一个元素后插入 
		return;
	j = Malloc(space);                      //分配存储位置 
	if(j){
		space[j].data = e;
		for(l = 1;l <= i-1;l++){
			k = space[k].cur; 				//类似从头结点向后扫描 
		}
		space[j].cur = space[k].cur;
		space[k].cur = j; 
	}
}
释放节点

删除操作的最后需要使用free函数回收存储空间,类似地,可写出静态链表下的free函数

  • 将释放位置放回空闲存储"链表"中,实现回收位置
void Free(StackLinkList space,int i){
	space[i].data = 0; 
	space[i].cur = space[0].cur;        //即将该位置插入到空闲的链中
	space[0].cur = i;
}
删除

更改链表第i-1个元素cur值,指向第i+1个元素
若删除链表最后一个元素,则将第i-1个元素cur值改为0,表示链表末尾

void ListDelete(StackLinkList space,int i){
	int j,k,l;
	if(i < 1 || i > ListLength(space) + 1)
		return;
	k = MAXSIZE -1;
	for(l = 1;l <= i-1;l++){             //找到第i-1个元素 
		k = space[k].cur; 			
	}
	j = space[k].cur;                    //找到第i个元素 
	space[k].cur = space[j].cur;
	Free(space,j);
}

链表长度

通过数组末位(“头结点”),遍历链表,至cur值为0的元素(末尾)

int ListLength(StackLinkList space){
	int len = 0;
	int i = space[MAXSIZE-1].cur;   //i为链表第一个元素下标
	while(i){
		i = space[i].cur;
		len++;
	}
	return len;
}
创建链表(前插法)

可参考单链表前插法操作
每次在数组末位(头结点)与第一个元素间插入

void CreateList_H(StackLinkList space,int len){
	int j;
	int k = MAXSIZE-1;
	int cnt = 0;
	while(cnt < len){
		j = Malloc(space);
		space[j].data = cnt;
		space[j].cur = space[k].cur;
		space[k].cur = j;
		cnt++;
	} 
}
打印链表

还是从数组末位开始遍历

void show(StackLinkList space){
	int k = space[MAXSIZE-1].cur;
	while(k){
		printf("%d ",space[k].data);
		k = space[k].cur;
	}
	printf("%c",'\n');
}

最后再check一下

int main(){
	StackLinkList L;
	InitList(L);
	//前插法创建 
	printf("前插法创建:\n"); 
	CreateList_H(L,8);
	printf("长度:%d\n",ListLength(L));
	show(L);
	//插入 
	printf("插入:\n");
	ListInsert(L,1,80);
	show(L);
	ListInsert(L,10,-1);
	show(L);
	ListInsert(L,2,70);
	show(L);
	//删除
	printf("删除:\n");
	ListDelete(L,2);
	show(L);
	ListDelete(L,1);
	show(L);
	ListDelete(L,9);
	show(L);
}

结果:

前插法创建:
长度:8
7 6 5 4 3 2 1 0
插入:
80 7 6 5 4 3 2 1 0
80 7 6 5 4 3 2 1 0 -1
80 70 7 6 5 4 3 2 1 0 -1
删除:
80 7 6 5 4 3 2 1 0 -1
7 6 5 4 3 2 1 0 -1
7 6 5 4 3 2 1 0

上述代码参考自《大话数据结构》,可作为单链表相关实现逻辑的一种改写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值