大话数据结构——第三章线性表(3)

#####仅作为笔记
单链表结构和顺序存储结构优缺点
(1)存储分配方式
顺序存储结构用一段连续的存储单元依次存储线性表的数据元素
单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素
(2)时间性能
查找:
顺序存储结构O(1),单链表O(n)
插入与删除:
顺序存储结构需要平均移动表长一半的元素,时间为O(n)
单链表在线出某位置的指针后,插入和删除时间为O(1)
(3)空间性能
顺序存储结构需要预分配存储空间,分大了,浪费,分小了易发生上溢
单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制

静态链表
用数组代替指针,描述单链表
让数组元素有两个数据域,data和cur。也就是说,数组每一个下标都对应着一个data和一个cur。数据域data存放数据元素,而cur用于相当于单链表的next指针,存放后继元素的下标。
我们把用数组描述的链表叫做静态链表。

/*线性表的静态链表存储结构*/
#define MAXSIZE 1000                   /*假设链表的最大长度是1000*/
typedef struct
{
	ElemType data;
	int cur;                           /*游标(Cursor),为0时表示无指向*/
} Component, StaticLinkList[MAXSIZE];

对数组的第一个和最后一个元素作为特殊元素处理,不存数据。我们通常把未被使用的数组元素称为备用链表。而数组第一个元素,即下标为0的元素的cur就存放备用链表的第一个结点的下标;而数组的最后一个元素的cur存放第一个有数值的元素的下标,相当于头结点的作用。

/*将一维数组space中各分量链成一备用链表*/
/*space[0].cur为头指针,“0”表示空指针*/
Status InitList(StaticLinkList space)
{
	int i;
	for(i=0; i < MAXSIZE-1; i++)
		space[i].cur = i + 1;
	space[MAXSIZE-1].cur = 0;         /*目前静态链表为空,最后一个元素的cur为0*/
	return OK;
}

静态链表的插入操作

/*若备用空间链表非空,则返回分配的结点下标,否则返回0*/
int Malloc_SLL(StaticLinkList space)
{
	int i = space[0].cur;                   /*返回数组第一个元素cur存的值*/
	                                        /*就是要返回的第一个备用空闲的下标*/
	if(space[0].cur)
		space[0].cur = space[i].cur;      /*由于要拿出第一个分量来使用了,所以我们*/
		                                  /*就得把它的下一个分量用来做备用*/
    return i;
}

实现插入的具体实例:

/*在L中的第i个元素之前插入新的数据元素e*/
Status ListInsert(StaticLinkList L, int i, ElemType e)
{
	int j, k, l;
	k = MAX_SIZW - 1;      /*注意k首先是最后一个元素的下标*/
	if(i < 1 || i > ListLength(L) - 1)
		return ERROR;
	j =Malloc_SSL(L);      /*获得空闲分量的下标*/
	if(j)
	{
		L[j].data = e;    /*将数据赋值给此分量的data*/
		for(l=1; l<= i - 1; l++)      /*找到第i个元素之前的位置*/
			k = L[k].cur;
		L[j].cur = L[k].cur;    /*把第i个元素之前的cur赋值给新元素的cur*/
		L[k].cur = j;           /*把新元素的下标赋值给第i个元素之前元素的cur*/
		return OK;
	}
	return ERROR;
}

静态链表的删除操作

/*删除在L中第i个数据元素e*/
Status ListDelete(StaticLinkList int i)
{
	int j, k;
	if(i < 1 || i > ListLength(L))
		return ERROR;
	k = MAX_SIZE -1;
	for(j=1; j <= i -1; j++)
		k = L[k].cur;
	j = L[k].cur;
	L[k].cur = L[j].cur;
	Free_SSL(L,j);
	return OK;
}
/*将下标为k的空闲结点回收到备用链表*/
void Free_SSL(StaticsLinkList space, int k)
{
	space[k].cur = space[0].cur;    /*把第一个元素cur赋给要删除的分量cur*/
	space[0].cur = k;               /*把要删除的分量下标赋值给第一个元素的cur*/
}

静态链表获取ListLength

/*初始条件:静态链表L已存在。操作结果:返回L中数据元素个数*/
int ListLength()
{
	int j=0;
	int i = L[MAXSIZE -1].cur;
	while(i)
	{
		i = L[i].cur;
		j++;
	}
	return j;
}

静态链表的优点:
在插入和删除操作时,只需要修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点
缺点:
没有解决连续存储分配带来的表长难以确定的问题,失去了顺序存储结构随机存取的特性

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值