用数组模拟链式结构

在实际程序设计过程在,手撸链表及单链表的单向遍历和双链表的复杂操作带来很多不便。其实,为了模仿链式结构可用两个数组代替,及前驱数组pre和后继数组next。这种方法方便了我们对于链式结构的建立与处理,但其不足之处在于占用了较多的空间,有较高的空间复杂度,且其只是单纯的逻辑模拟,只支持删除操作,不支持插入操作,即使如此,其作为逻辑跳转表也是可取的,下面以一道简单题为例:
在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <cstring>


using namespace std;   //使用名称空间std

//内联函数声明及定义区(定义在其他无main函数的文件中会发生链接错误)



int main()
{
	int prime[3010];                //幸运数字存储数组
	int pre[50010], next[50010];    //模拟结点前驱和后继
	int n;
	int i, j;
	int ans = 0;//prime数组位置标记
	int count;  //循环计数器                                                                                             

	for (i = 1;i<50000;i++)
	{
		pre[i] = i - 1;    //设置前驱数组
		next[i] = i + 1;   //设置后继数组
	}
	for (i = next[1];i < 50000;i = next[i])     //使用后继而非i++
	{//i本身看做逻辑链表,i即为对应结点,使用了前驱和后继数组设定的逻辑结构
		prime[++ans] = i;//找到此阶段的第一个数(幸运数字)
		if (ans == 3000)  break;
		count = 1;
		for (j = next[i];j < 50000;j = next[j])
		{//排除此阶段的非幸运数字,修改逻辑结构
			if (count == i)
			{//找到计数位置(待删除的非幸运数字)
				pre[next[j]] = pre[j];   //删除计数点处j结点
				next[pre[j]] = next[j];
				count = 1;//进行下一次计数循环
			}
			else  //未到计数点
				count++;
		}

	}
	while (cin >> n)
	{
		cout << prime[n] << endl;   //第一个数从下标1开始
	}
	return 0;
}

删除j结点时的逻辑:
pre[j]->j->next[j]
要删除j,只需改变前驱与后继的逻辑顺序,
next[j]的前驱指向pre[j],pre[j]的后继指向next[j],即:
pre[next[j]]=pre[j];
next[pre[j]]=next[j];

总结:
用数组模拟链式结构的本质在于前驱与后继的逻辑模拟,此法用于只有删除操作的情形,模拟跳跃,作为逻辑跳跃表较为合适。

猜你喜欢

转载自blog.csdn.net/qq_40432881/article/details/82875417