链表在存储器中紧凑的排列

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

 

分析与解答:

     假设链表中已有y个元素,并且已经紧凑排列。令top = y +1,表示下一个将要分配的指针位置

     在分配空间时很简单:

           ALLOCATE-OBJECT分配时,只需要top++,同时在双链表L的头部增加一个元素。

     在释放空间时稍微复杂:

          FREE-OBJECT释放时,若x和y相同,则只需要从双链表L中删除元素x,同时top--;若x<y,则需要将x删除,同时将元素y调整到x的位置,然后top--

 

整个过程如下:

 

  1. ALLOCATE-OBJECT()  
  2. y ← top[free]  
  3. if y > m  
  4.   then error "out of memory"  
  5. if head[L] ≠ NIL  
  6.   then prev[head[L]] = y  
  7. next[y] ← head[L]  
  8. prev[y] ← NIL  
  9. head[L] ← y  
  10. top[free] ← top[free]+1  
  11.   
  12. FREE-OBJECT(x)  
  13. y ← top[free]-1  
  14. if next[x] ≠ NIL  
  15.   then prev[next[x]] ← prev[x]  
  16. if prev[x] ≠ NIL  
  17.   then next[prev[x]] ← next[x]  
  18. else head[L] ← next[x]   
  19. prev[x] ← prev[y]  
  20. next[x] ← next[y]  
  21. key[x] ← key[y]  
  22. if prev[y] ≠ NIL  
  23.   next[prev[y]] ← x  
  24. if next[y] ≠ NIL  
  25.   prev[next[y]] ← x  
  26. top[free] ← top[free]-1  

10.3-5 设L是一长度为m的双链表,存储在长度为n的数组key、next和prev中。假设这些数组由维护双链自由表F的两个过程ALLOCATE-OBJECT和FREE-OBJECT来操纵。进一步假设在数组的n个元素中,有m个在表L和自由表F,移动L中的元素,使他们占有数组中的1, 2, ..., m位置,同时调节自由表F使之保持正确,并占有数组位置m+1, m+2, ..., n。所给出的运行时间应该是Θ(m),且只能使用固定量的额外空间。请仔细论证你所给出的过程的正确性。

 

分析与解答

      如下图所示,长度为m的双链表L存储在长度为n的数组中,自由表为F。为了使双链表分布更加紧凑,我们将移动L中的元素,使其占有数组中的1, 2, ..., m位置。

     我们可以采用交换的手法,将L中的第1个元素和数组第1个位置的元素进行交换,一次类推,L中的第m个位置的元素和数组的第m个元素进行交换,每次交换仅需要常量的额外空间。

 整个过程如下:

  1. COMPACTIFY-LIST(L, F)   
  2. x ← head[L]  
  3. num ← 0  
  4. while x ≠ NIL  
  5.   do num ← num+1  
  6.      if x ≠ num  
  7.        then SWAP-OBJECT(x, num)  
  8.      x ← next[x]  
  9. SWAP-OBJECT(i, j)  
  10. exchange A[i] ↔ A[j]  
  11. if prev[i] ≠ NIL  
  12.   then next[prev[i]] ← j  
  13. if next[i] ≠ NIL  
  14.   then prev[next[i]] ← j  
  15. if prev[j] ≠ NIL  
  16.   then next[prev[j]] ← i  
  17. if next[j] ≠ NIL  
  18.   then prev[next[j]] ← i  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值