静态链表 使用

先给一个具体的例子:
问题:
给出两条链表的首地址以及若干节点的地址,数据,下一节点的地址,求两条链表的首个共用节点的地址。如果没有共用节点输出-1。

#include<cstdio>
#include<cstring>
const int maxn = 100010;
struct Node
{
	int data;
	int next;
	bool flag;//节点是否在第一条链表中出现;
}node[maxn];

int main(void)
{
	for(int i = 0; i < maxn; i++)
{
	node[i].flag = false;
}

int s1, s2, n;//s1和s2分别代表两条链表的首地址
scanf("%d%d%d", &s1, &s2, &n);
int address, next;//节点地址和后继节点地址;
char data;//数据;
for(int i = 0; i < n; i++)
{
	scanf("%d %c %d", &address, &data, &next);/*scanf使用%c格式时可以读入空格,
	因此在输入地址数据和后继节点时格式不能写成%d%c%d 必须在中间加空格*/
	node[address].data = data;
	node[address].next = next;
}

int p;
for(p = s1; p != -1; p = node[p].next)
{
	node[p].flag = true;//枚举第一条链表的所有节点,令其出现次数为1
}
for(p = s2; p != -1; p = node[p].next)
{
	//找到第一个已经在第一条链表中出现的节点;
	if(node[p].flag == true)
	{
		break;
	}
}

if(p != -1)//如果第二条链表没到达结尾,说明找到共用节点;
{
	printf("%05d\n",p);
}
else
{
	printf("-1\n");
}
return 0;
}

具体解决步骤:

1.定义静态链表:

const int maxn = 100010
struct Node
{
	int address;//节点地址;
	typename data;//数据域;
	int next;//指针域;
	XXX;//节点的某个性质,不同题目会有不同设置,如下例
}node[maxn];

定义了节点的地址、数据域、指针域、并且留下XXX来适应不同题目(例如可以设置成节点是否为链表上的一个节点)
2.初始化静态链表:
一般来说需要对定义中的XXX进行初始化,将其定义为正常情况下达不到的数字(一般来说需要小于所有能达到的数字,理由在第四步说明),例如针对节点是否在链表上这个性质来讲,可以初始化为0(即 false)表示节点不在链表上。

for(int i = 0; i < maxn; i++)
{
	node[i].XXX = 0;
}

3.遍历标记
题目给出第一条链表的首地址,然后我们就依据首地址来遍历整条链表,这一步同时也是我们对节点性质XXX进行标记,并且对有效节点计数的时候,例如对节点是否在链表上在这个性质来讲就可以把XXX设置为1(即true)。

int p = begin, count = 0;
while(p != -1)
{
	XXX = 1;
	count ++;
	p =node[p].next;
}

4.由于使用静态链表时是直接采用地址映射(hash)hash 的方式,就会使得数组下标的不连续,很多时候题目给出的节点并不都是有效节点,所以我们得对数组进行排序,将有效节点移到数组的左端,这样就可以用步骤3得到的count来访问他们,在写sort的排序函数cmp时候可以借助之前定义的XXX来帮忙,无效节点在步骤3不会被修改所以一定比有效节点的XXX小,就可以在cmp两个参数节点中有无效节点时按照XXX的大小排序,

bool cmp(Node a, Node b)
{
	if(a.XXX == -1 || b.next == -1)
	{
		return a.XXX > b.XXX;
	}
	else
	{
		//二级排序;
	}
}

5.经步骤4有效节点到了数组的左端,且按照节点的性质进行了排序,接下来接看排序后具体干什么了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值