计算机程序设计艺术一线性表“逻辑结构”2
上一篇主要考虑的插入和删除的四中情况情况皆为一个顺序表的情况,如果有两个表那?情况如下:
当恰有两个大小可变的表时,如果我们令这两个表彼此相向地增长,则它们可以很好地共存。
两个可变线性表时的存储空间示意图
这些表可以独立地扩展和收缩使得每一个的最大有效容量都要大大超出可用空间的一半。存储空间
的这种布局使用很频繁。
这种情况下的栈将是可变大小的,由于栈的大小可变,其将需要链接变量,表示开头结束,当每
个可变大小的表是一个栈时,出现一个重要的特殊情况。这个时候,由于在任何时刻,只有每个栈的
顶部元素是有关系的,因此我们几乎可以像以前一样有效地进行。假设我们有n个栈;如果对于第i个
栈,BASE[i]和TOP[i]是链接变量,而且每个节点都是一个字长,则上一篇中的插入和删除算法变成
插入:TOP[i] = TOP[i] + 1; 如果TOP[i] > BASE[i + 1],则VOERFLOW;否则置CONTENTS(TOP[i]) = Y;
删除:如果TOP[i] = BASE[i],则UNDERFLOW;否则,置
Y = CONTNETS(TOP[i]), TOP[i] = TOP[i] - 1;
其中BASE[i + 1]是第i + 1个栈的基地址。条件TOP[i] = BASE[i]时意味着栈i为空。
当有多个栈时,对于插入操作时可能发生的OVERFLOW将不再是危险,因为可以从未填满的表中
腾出空间给已经溢出的表。
以下是代码实现:
插入:
//插入 代码
//TOP[i] > BASE[i + 1]说明i号栈将占用了i + 1号栈,能实现的前提是所有的栈以顺序表方式存在
//CONTNETS(TOP[i])表示的是链接TOP[i]所对应的存储空间
TOP[i] = TOP[i] - 1;
if(TOP[i] > BASE[i + 1])
{
exit(OVERFLOW);
}
else
{
CONTNETS(TOP[i]) = Y;
}
删除:
//删除 代码
//BASE[i] = TOP[i]时,说明空
if(TOP[i] == BASE[i])
{
exit(UNDERFLOW);
}
else
{
Y = CONTENTS(TOP[i]);
TOP[i] -= 1;
}
假设有n个栈,而且值BASE[i]和TOP[i]要像上面所诉的插入和删除加以操作,如果这些栈都共享由L0 < L <= L∞
的所有单元L组成的一个公共的存储区域。我们可以从所有栈为空BASE[j] = TOP[j] = L0,对于1 <= j <= n开始。我们
置BASE[n + 1] = L∞,
当对于栈i,OVERFLOW出现时,存在三种可能:
1)我们求出使i < k <= n和TOP[k] < BASE[k + 1]的最小的k,如果有这样的k。现在上移一个节点: 置
CONTENTS(L + 1) = CONTENTS(L),对于TOP[k] >= BASE[i +1] (这必须对于递减的而不是递增的而不是递增
的L值进行以避免丢失信息。有可能TOP[k] = BASE[i + 1],在这种情况下,不需要任何移动)之后,对于i < j <= k,
值BASE[j] = BASE[j] +1和TOP[j]+= 1;
2)找不到1)中的k,但是我们可以使1 <= k < i和TOP[k] < BASK[k +1]的最大的k。现在下移一个节点:置
CONTNETS(L - 1) = CONTENTS(L),对于BASE[k + 1 ] < L <= TOP[j]。然后k < j <= i,置BASE[j] -= 1和TOP[j] =
TOP[j] -1。
3)对于所有的k != i,我们有TOP[k] = BASE[k +1]。于是显然我们不能为新的入栈项找到空间,放弃.
大概是这样的,比如i满了,则先看紧靠的i + 1中BASE[i + 1]的空间,没有的话,再看i - 1中TOP[i - 1]是否占用,也占用时,放弃。