第二章线性表——2.3:线性表的链式表示和实现

第二章线性表——2.3:线性表的链式表示和实现

在上一节我们看到了顺序存储结构在进行插入和删除的时候都需要从起点开始,在移动数据上花费大量的时间,因此人们想出了链式结构来解决这个问题。

一个链表中由很多结点组成,节点中有两个域,分别为数据域和**指针域。**数据域中存储元素信息,指针域中存储下个节点的地址。

学习链表,我们先从单链表学起。单链表又称为线性链表,因为他的每个结点中只有一个指针域。

而一个单链表的存取都是从头指针开始的。头指针中没有元素信息,只有下一个结点的地址,同时单链表中的最后一个结点中的指针为空,即NULL。大家可以拿笔画一画,印象就会很深刻。

单链表的结构指针如下。

typedef struct lnode
{
	elemtype data;
	struct lnode* next;
}lnode,*linklist;

有时候,我们会设置一个头结点作为头指针的下一个结点,这个头结点我们会放置比如这个链表的长度之类的数据,头结点后面的第一个结点才正式存储我们的数据。

例2.8把链表中第i个结点的值赋值给e,L有头结点。

Status getelem(linklist l, int i, elemtype& e)
{
	p = l->next;
	j = 1;
	while (p && j < i)
	{
		p = p->next;
		j++;
	}
	if (!p || j > i)return error;
	e = p->data;
	return ok;
}

例2.9在L的第i个位置之前插入一个元素,L有头结点。

Status listinsert_l(linklist& l, int i, elemtype e)
{
	p = l;
	j = 0;
	while (p && j < i - 1)
	{
		p = p->next;
		++j;
	}
	if (!p || j > i - 1)return error;
	s = (linklist)malloc(sizeof(lnode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return ok;
}

例2.10删除第i个结点

Status listdelete(linklist& l, int i, elemtype& e)
{
	p = l;
	j = 0;
	while (p->next && j < i - 1)
	{
		p = p->next;
		j++;
	}
	if (!(p->next) || j > i -1) return error;
	q = p->next;
	p->next = q->next;
	e = q->data;
	free(q);
	return ok;
}

我们之前建立链表是从头输入数据的接下来我们从尾输入数据。

例2.11建立尾部输入数据的链表l。

void creatlist_l(linklist& l, int n)
{
	l = (linklist)malloc(sizeof(lnode));
	l->null;
	for (i = n; i > 0; --i)
	{
		p = (linklist)malloc(sizeof(lnode));
		scanf(&p->data);
		p->next = l->next;
		l->next = p;
	}

例2.12将两个非递减有序链表合成一个新的有序链表

void mergelist_l(linklist& la, linklist& lb, linklist& lc  )
{
	pa = la->next;
	pb = lb->next;
	lc = pc = la;
	while (pa && pb)
	{
		if (pa->data <= pb->data)
		{
			pc->next = pa; pc = pa; pa = pa->next;
		}
		else
		{
			pc->next = pb; pc = pb; pb = pb->next;
		}
	}
	pc->next = pa ? pa : pb;
	fell(lb);
}

例2.12和2.7相比时间复杂度相等,空降复杂度12小些。

有时候我们不用指针,用一维数组也可以描述线性链表,我们称为静态链表。

#define maxx 1000
typedef struct
{
	elemtype data;
	int cur;//游标
}component,slinklist[maxx];

我们将静态链表的第零分量看成头结点。

例2.13在静态链表中找到第一个值为e的元素

int locateelem_sl(slinklist s, elemtype e)
{
	i = s[0].cur;
	while (i && s[i].data != e) i = s[i].cur;
	return i;
}

例2.14将一维数组中的各个分量连接成备用链表。备用链表即没有使用过的结点。

int initspace_sl(slinklist& space)
{
	for (i = 0; i < maxx - 1; ++i) space[i].cur = i - 1;
	space[maxx - 1].cur = 0;
}

例2.15若备用链表非空,返回下标

int malloc_sl(slinklist& space)
{
	i = space[0].cur;
	if (space[0].cur) space[0].cur = space[i].cur;
	return i;
}

例2.16将下标为k的结点收为备用链表

void free_sl(slinklist& space, int k)
{
	space[k].cur = space[0].cur;
	space[0].cur = k;
}

例2.17建立出(A-B)∪(B-A)的静态链表

各位可以自己试试哦

单项链表过后就是双向链表,双向链表很简单理解不做多解释。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Harden先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值