线性表3——静态链表

零、说明

  1. 产生原因:在不使用指针的情况下实现链表功能
  2. 结构说明:
    (1)静态链表实际上是数组,只不过数组元素是一个结构体而不是int。
    (2)静态链表可以看成两条单独的链表组合在一起。
    第一条叫已用链表,顾名思义,就是已经存储元素的地方组合成一条链表。这条链表的头节点是整个数组最后一个元素。这个元素还存储目前数据数量。
    第二条叫备用链表,头节点是数组第一个元素,指向此时备用链表第一个元素(也就是第一个还没使用的地方)。
    所以,数组的第0个元素和最后一个元素不存数
    3.理解起来确实困难,画个图能更好地帮助理解

一、数据类型

#include<stdio.h>
#define MAXSIZE 1002//存1000个数,剩下两个作为两条链表的头节点
#define TYPE int
typedef struct Node
{
	TYPE data;
	int cur;//指向下一个节点的"指针"
}Node,staticList[MAXSIZE];

二、初始化

开始时,全是备用链表,所以备用链表头节点(就是数组第0个元素)的指针(就是cur),指向第一个元素,而第一个元素的cur指向第二个元素(像普通链表一样串起来了)。备用链表指针的最后一个随意
同时,已用链表的最后一个元素的指针应当为0,此时就是头节点(就是数组最后一个元素)。它的cur为0

void initial(staticList l)
{
	for(int i=0;i<MAXSIZE-2;i++)
	{
		l[i].cur=i+1;
	}
	l[MAXSIZE-1].data=0;
	l[MAXSIZE-1].cur=0;
}

三、插入与删除

  1. 插入:
    修改三个节点:备用链表的头节点——因为备用链表第一个存数的节点此时用来插入,新增节点——注意cur要为0已用链表尾部,上一个节点——指针由0(代表末尾)换成新增节点的位置
    插入到尾部和插入到中间区别只有end(就是上述的上一个节点)的寻找

①插入到尾部
“上一个节点”就是倒数第二个节点,用while找到末尾就行

void insert(staticList l,int data)
{
	if(l[MAXSIZE-1].data<MAXSIZE-2)
	{
		l[MAXSIZE-1].data++; 
		int end=MAXSIZE-1;
		int newNodePosition=l[0].cur;//存储新节点的位置
		while(l[end].cur!=0)
		{
			end=l[end].cur;
		}
		l[0].cur=l[newNodePosition].cur;
		l[newNodePosition].data=data;
		l[newNodePosition].cur=0;
		l[end].cur=newNodePosition;
	}
	else
	{
		printf("Insert %d failed.\n",data);
	}
}

②插入中间
"上一个节点”要定位,for直接到指定位置

void insert(staticList l,int position,int data)
{
	if(l[MAXSIZE-1].data<MAXSIZE-2&&position>=1&&position<=l[MAXSIZE-1].data+1)
	{
		l[MAXSIZE-1].data++;
		int end=MAXSIZE-1;
		int newNodePosition=l[0].cur;
		for(int i=1;i<position;i++)
		{
			end=l[end].cur;
		}
		l[0].cur=l[newNodePosition].cur;
		l[newNodePosition].data=data;
		l[newNodePosition].cur=l[end].cur;		
		l[end].cur=newNodePosition;
	}
	else
	{
		printf("Insert %d failed.\n",data);
	}
}
  1. 删除
    先存储待删除节点的位置,再改变上一个节点的指针为0,再改变待删除节点的指针让它作为备用链表的一部分,最后修改备用链表头指针,让待删除节点加入备用链表
void remove(staticList l,int position)
{
	if(position>=1&&position<=l[MAXSIZE-1].data)
	{
		l[MAXSIZE-1].data--;
		int end=MAXSIZE-1;
		int newEmptyNodePosition;
		for(int i=1;i<position;i++)
		{
			end=l[end].cur;
		}
		newEmptyNodePosition=l[end].cur;//第一个步骤
		l[end].cur=l[newEmptyNodePosition].cur;//第二个步骤
		l[newEmptyNodePosition].cur=l[0].cur;//第三个步骤
		l[0].cur=newEmptyNodePosition;//第四个步骤
	}
	else
	{
		printf("Remove data in %d failed.\n",position);
	}
}

四、搜索,遍历

搜索就是从已用链表第一个开始,从头到尾遍历。找不到就返回0

int search(staticList l,int data)
{
	int position=l[MAXSIZE-1].cur;
	while(position!=0)
	{
		if(l[position].data==data)
		{
			return position;
		}
		position=l[position].cur;
	}
	return 0;
}

遍历就是一个一个输出。如果为空,输出一个换行了事

void traverse(staticList l)
{
	int current=l[MAXSIZE-1].cur;
	while(current!=0)
	{
		printf("%d ",l[current].data);
		current=l[current].cur;
	}
	printf("\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值