算法导论 10.3-4 紧凑的多重数组

一、题目:

我们常常希望一个双链表中的所有元素在存储器中能够紧凑地排列在一起,例如使用多重数组表示中的前m个下标位置(在一个分页的虚拟计算机环境中情况就是这样的)。假设链表以外没有指向链表元素的指针,请说明如何实现过程ALLOCATE_OBJECT和FREE_OBJECT,才能使这种表比较紧凑。(提示:使用栈的数组实现)

思考:

假设当前的数组是紧凑的,即数组中有f个元素,都位于数组的前f个位置

分配一个新的元素时,把f+1的位置分配给它

删除一个元素时,假设待删除的元素的位置是i,先修改元素prev[i]的next指针和元素next[i]的prev指针,删除这个元素。这里数组中间就留下一个空位,让第f个元素填充这个空位,具体方法是修改元素prev[f]的next指针和元素next[f]和prev指针

代码:

#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;

int n, head, f;
//在链表中插入一个元素
void Insert(int *key, int *next, int *prev, int x)
{
	//链表已满
	if(f == n-1)
	{
		cout<<"error:overflow"<<endl;
		return;
	}
	//向上扩充一位,类似于栈
	++f;
	//在新的位置中填入信息,在这里,新元素放在链表首位,在物理空间是在f+1位置
	key[f] = x;
	prev[f] = -1;
	next[f] = head;
	if(head >= 0)
		prev[head] = f;
	head = f;
}
//删除一个元素
void Delete(int *key, int *next, int *prev, int x)
{
	//链表为空时无法删除
	if(f == -1)
	{
		cout<<"error:underflow"<<endl;
		return;
	}
	int i;
	//找到待删除元素的位置
	for(i = 0; i <= f; i++)
	{
		if(key[i] != x)continue;
		//设元素位于数组第i个位置
		//修改指针,删除第i个元素
		if(prev[i] != -1)
			next[prev[i]] = next[i];
		if(next[i] != -1)
			prev[next[i]] = prev[i];
		//如果i中第f个元素,直接删除即可,不需要特殊处理
		//如果i不是第f个元素,就让第f个元素来补第i个元素的空缺
		if(i < f)
		{
			//把第f个元素放到第i个位置
			key[i] = key[f];
			next[i] = next[f];
			prev[i] = prev[f];
			//修改指向f的指针,改为指向i
			if(prev[f] != -1)
				next[prev[f]] = i;
			if(next[f] != -1)
				prev[next[f]] = i;
			
		}
		//删去第一个元素,类似于栈
		f--;
		break;
	}
}
//输出,按数组顺序输出,不是按链表顺序输出
void Print(int *key, int *next, int *prev)
{
	int i;
	for(i = 0; i <= f; i++)
		cout<<i<<": "<<key[i]<<' '<<next[i]<<' '<<prev[i]<<endl;
}
int main()
{
	cin>>n;
	int x;
	string str;
	//构造随机数据
	int *key = new int[n];
	int *next = new int[n];
	int *prev = new int[n];
	head = -1;f = -1;
	while(1)
	{
		cin>>str;
		if(str == "I")
		{
			x = rand() % 100;
			cout<<x<<endl;
			Insert(key, next, prev, x);
		}
		else if(str == "D")
		{
			cin>>x;
			Delete(key, next, prev, x);
		}
		else if(str == "P")
		{
			Print(key, next, prev);
		}
	}
	return 0;
}


 

转载于:https://my.oschina.net/windmissing/blog/690463

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值