线性表之静态链表

静态链表节点的定义

#include<bits/stdc++.h>
using namespace std;
#define MAX 11
typedef char elemtype[8];
int k2;
//定义静态链表中的每一个节点
typedef struct
{
	elemtype data;
	int cur;
 }Nodetype;
//无结构体类型只有结构体变量的定义方法的缺点是只能定义一次结构体变量

静态链表的节点数组(结构体数组)

Nodetype space[MAX];

静态链表的初始化(将静态链表初始化为一个备用链表的状态)

void InitSpace()
 {
	memset(space,0,sizeof(space));
	for(int i=0;i<=9;i++)
	space[i].cur=i+1;
	space[MAX-1].cur=0; 
  }

  • 最后一个节点的cur有的设为-1,有的设置为0

为初始化后的静态链表加上已用链表的头节点

space[0].cur=space[1].cur;
space[1].cur=0;/*为已用静态链表加上头节点*/ 
  • space[1].cur=0;中0表示的是这个节点后没有其他节点了(已用链表)

静态链表之—从备用链表中挑选出一个节点使用

int fenpei()
  {
  	int i=space[0].cur;
  	if(space[0].cur)
  	space[0].cur=space[space[0].cur].cur;
  	return i;
  }
  • 返回的是抽出节点的下标

静态链表的插入操作

void insert(elemtype e,int d)/*d为已用链表中的第几个节点--不算头节点*/
  {
  	int k=1;
  	int m=fenpei();
  	for(int j=1;j<d;++j)
  	k=space[k].cur;//找到前一个节点的下标k
  	space[m].cur=space[k].cur;
	space[k].cur=m;
	strcpy(space[m].data,e);
  }
  • d表示在第几个节点前插入

静态链表的节点的回收,节点的删除,节点的查找,链表状态的显示

void free(int k1)
  {
	space[k1].cur=space[0].cur;
	space[0].cur=k1;
  }
  void del(int a) 
  {
  	int k=1;
  	for(int j=1;j<a;++j)
  	k=space[k].cur;
  	k2=space[k].cur;
  	space[k].cur=space[space[k].cur].cur;
  	free(k2);
  } 
  int search(elemtype e)//e指的是要查找的东西在第几个节点
  {
  	int k=space[1].cur;
  	while(strcmp(space[k].data,e))
  	k=space[k].cur;
  	return k;
  }
  
  void show()
  {
  	for(int i=0;i<=10;++i)
  	printf("%-8s%2d\n",space[i].data,space[i].cur);
  	printf("********************\n");
  }

练习😋😋😋

问题描述

静态链表是使用顺序存储结构来实现的链表。严蔚敏《数据结构(C语言版)》在介绍静态链表时使用的是一个姓氏列表。
图1是静态链表示例,图(a)是初始化后插入了8个姓氏的链表,图(b)是在第5个元素前插入了“SHI”而删除了“ZHENG”的结果。
在这里插入图片描述
(a)修改前的状态;(b)修改后的状态
现在,我们就来实现一下这个静态链表。实际上静态链表与一般含有指针的链表没有太大的差别,只是静态链表的结点存放的空间不是在使用时临时分配的,而是在一开始就分配了固定的一些,一般是用数组。同时一般的链表使用指针来指向下一个结点而在静态链表中则使用数组下标了。大家如果看严蔚敏的书会发现书上的算法还是有些问题的。下面我就直接给大家展示一种静态链表的实现算法。
输入形式

静态链表的存储空间(图2中的space)始终只有11个节点,起始为空表。insert a e代表在第a个姓氏前插入姓氏e;delete a代表删除第a个姓氏;search e代表查找姓氏e的位置;show代表输出静态链表存储空间的状态。输入保证操作都合法。

输出形式

只遇到search和show时才输出。当遇到search时输出姓氏e在space中的位置;当遇到show时输出这11个结点的状态。姓氏占8个字符而数字占2个字符,姓氏左对齐。每个指令输出后面跟着含有20个星号的行。

样例输入

show
insert 1 ZHAO
show
insert 2 QIAN
show
insert 3 SUN
show
insert 4 LI
insert 5 ZHOU
insert 6 WU
insert 7 ZHENG
insert 8 WANG
show
insert 1 ZHANG
show
search LI
show

【样例输出】
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

提示

  • 怎样将字符串类型定义为ElemType呢?形如typedef int num一样,数组或者指针可以放在定义的类型名后面,例如将具有8个字符的姓氏定义为ElemType可以这样定义:typedef char ElemType[8]。

  • 题目和书中给的算法描述还缺少静态链表的插入、删除以及显示,都需要自己写。

  • 要求每个指令输出后跟一个空行,别忘了。

  • 姓氏占8个字符,数字占2个字符,姓氏左对齐,可以这样输出printf(“%-8s%2d”);对于指令search也要输出占2个字符的数字。

  • 静态链表初始化时将所有内存设为空,可以在InitSpace_SL中使用下面的方法:memset(space, 0 ,sizeof(space));

总结

静态链表与一般链表极为相似:使用数组来模拟内存,使用数组下标来模拟内存中的地址。

#include<bits/stdc++.h>
using namespace std;
#define MAX 11
typedef char elemtype[8];
int k2;
typedef struct
{
	elemtype data;
	int cur;
 }Nodetype;
Nodetype space[MAX];
 void InitSpace()
 {
	memset(space,0,sizeof(space));
	for(int i=0;i<=9;i++)
	space[i].cur=i+1;
	space[MAX-1].cur=0; 
  } 
  int fenpei()
  {
  	int i=space[0].cur;
  	if(space[0].cur)
  	space[0].cur=space[space[0].cur].cur;
  	return i;
  }
  void insert(elemtype e,int d)/*d为已用链表中的第几个元素*/
  {
  	int k=1;
  	int m=fenpei();
  	for(int j=1;j<d;++j)
  	k=space[k].cur;
  	space[m].cur=space[k].cur;
	space[k].cur=m;
	strcpy(space[m].data,e);
  }
  void free(int k1)
  {
	space[k1].cur=space[0].cur;
	space[0].cur=k1;
  }
  void del(int a)
  {
  	int k=1;
  	for(int j=1;j<a;++j)
  	k=space[k].cur;
  	k2=space[k].cur;
  	space[k].cur=space[space[k].cur].cur;
  	free(k2);
  } 
  int search(elemtype e)
  {
  	int k=space[1].cur;
  	while(strcmp(space[k].data,e))
  	k=space[k].cur;
  	return k;
  }
  
  void show()
  {
  	for(int i=0;i<=10;++i)
  	printf("%-8s%2d\n",space[i].data,space[i].cur);
  	printf("********************\n");
  }
int main()
{
	elemtype e,s;
	int d,a;
	InitSpace();
	space[0].cur=space[1].cur;  space[1].cur=0;/*为已用静态链表加上头节点*/ 
	while(scanf("%s",s)!=EOF) 
	{
		if(!strcmp("show",s))
		show();
		else if(!strcmp("insert",s))
		{
			scanf("%d%s",&d,e);
			insert(e,d);
		}
		else if(!strcmp("search",s))
		{
			scanf("%s",s);
			int k=search(s);
			printf("%2d\n",k);
			printf("********************\n");			
		}
		else if(!strcmp("delete",s))
		{
			scanf("%d",&a);
			del(a);
		}
	}
	return 0;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值