使用静态链表解决复杂问题的步骤

一、定义静态链表

代码如下:

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

上面的定义中,我们把结点的地址、数据域、指针域都进行了定义,并且留了一个XXX来适应不同的题目(例如可以设置为结点是否为链表上的一个结点)

 

二、静态链表的初始化

在程序的开始,对静态链表进行初始化。一般来说,需要对定义中的XXX进行初始化,将其定义为正常情况下达不到的数字(一般来说需要小于所有能达到的数字,理由在第四步中说明)例如对结点是否在链表上这个性质来说,我们可以初始化为0(即false),表示结点不在链表上。

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

三、遍历链表

 

题目一般都会给出一条链表的首结点的地址,那么我们就可以依据这个地址来遍历得到整条链表。需要注意的是,这一步同时也是我们对结点的性质XXX进行标记,并且对有效结点的个数进行计数的时候,例如对结点是否在链表上这个性质来说,当我们遍历链表时,就可以把XXX置为1,即true

int p=begin,count=0;
while(p!=-1){
	//-1代表链表结束
	XXX=1;
	count++;
	p=node[p].next; 
}

步骤四

 

由于使用静态链表时,是直接采用地址映射(hash)的方式,这就会使得数组下标的不连续,而很多时候题目中给出的结点并不都是有效结点(即可能存在不在链表上的结点)。为了能够可控的访问有效结点,一般都需要对数组进行排序以把有效结点移到数组左端,这样就可以用步骤3的count来访问它们;

既然需要把有效结点移到前面,那么就可以利用之前定义的XXX来帮忙,在步骤2中,XXX需要被初始化为比正常结点的XXX取值要小的数值,这个做法就可以在这一步起到作用吧,由于无效结点的XXX在步骤3中不会被修改,因此一定比有效结点的XXX小。于是在写sort的排序函数cmp时,就可以在cmp的两个参数结点中有无结点时按XXX从大到小排序,这样就可以把有效结点全部移到数组的左端。

一般来说,题目中还会有额外的要求,因此,cmp函数都需要有二级排序,不过这需要看具体的题目,例如:如果题目的要求需要把链表按照结点顺序排序,就需要在cmp函数中建立第二级排序,即在cmp的两个参数结点中有无效结点时按XXX从大到小排序,而当两个结点都是有效结点时,按照结点在链表中的位置从小到大排序(结点的顺序可以在第三步中得到)

bool cmp(Node a,Node b){
	if(a.xxx==-1||b.xxx==-1){
		//至少有一个结点是无效结点,就把它放在数组后面
		return a.xxx>b.xxx; 
	}else{
		//第二级排序 
	}
}

在经历了步骤四之后,链表中的有效结点就都在数组的左端了,且已经按照结点的性质进行了排序,接下来就是看题目的具体要求(比较常见的是按照各种不同的要求来输出链表)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值