Chinaunix首页 | 论坛 | 博客
  • 博客访问: 457298
  • 博文数量: 56
  • 博客积分: 517
  • 博客等级: 下士
  • 技术积分: 751
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-12 18:16
文章分类

全部博文(56)

文章存档

2015年(2)

2014年(6)

2013年(29)

2012年(17)

2011年(2)

分类: C/C++

2013-03-12 17:42:01

某些语言,像BASIC和FORTRAN不支持指针,如果需要链表但又不能使用指针就必须有另外的实现方法。游标(cursor)可以实现这种功能。链表的指针实现中有2个特点:
1.数据存储在一组结构体中。每个结构体包含有数据以及指向下一个结构体的指针。
2.一个新的机构体可以通过调用malloc从系统全局内存得到,并可调用free释放。

游标必须能模仿实现以上2条特征。满足条件1的逻辑方法可以使用一个全局的结构体数组。对于该数组中的任何单元,其数组下标可以用来代表一个地址。图1给出链表游标实现的声明。

点击(此处)折叠或打开

  1. #ifndef _cursor_h
  2. #define _cursor_h

  3. #define SpaceSize 64

  4. typedef int ElementType;
  5. typedef int PtrToNode;
  6. typedef PtrToNode List;
  7. typedef PtrToNode Position;

  8. void InitializeCursorSpace();
  9. List MakeEmpty(List l);
  10. int IsEmpty(const List l);
  11. int IsLast(const Position P, const List l);
  12. Position Find(ElementType x, const List l);
  13. void Delete(ElementType x, List l);
  14. Position FindPrevious(ElementType x, const List l);
  15. void Insert(ElementType x, List l, Position p);
  16. void DeleteList(List l);

  17. struct Node
  18. {
  19.     ElementType Element;
  20.     Position Next;
  21. };


struct Node CursorSpace[SpaceSize];

图1链表游标实现的声明
现在我们必须模拟条件2,让CusorSpace数组中的单元代替malloc\free的职能。对于Next,0的值等价于NULL指针。CursorSpace的初始化是一个简单的循环操作。图3表示出了malloc和free的游标实现。注意,如果没有可用空间,那么CursorAlloc将返回0,表明没有可用空间。
index Element Next
0
1
2
3
4
5

1
2
3
4
5
0

图2 一个初始化的CursorSpace

点击(此处)折叠或打开

  1. void InitializeCursorSpace()
  2. {
  3.         int i;
  4.         for (i = 0; i < SpaceSize - 1; i++) {
  5.                 CursorSpace[i].Next = i + 1;
  6.         }

  7.         CursorSpace[SpaceSize - 1].Next = 0;
  8. }

  9. static Position CursorAlloc()
  10. {
  11.         Position P;
  12.         P = CursorSpace[0].Next;
  13.         CursorSpace[0].Next = CursorSpace[P].Next;
  14.         return P;
  15. }

  16. static void CursorFree(Position P)
  17. {
  18.         CursorSpace[P].Next = CursorSpace[0].Next;
  19.         CursorSpace[0].Next = P;
  20. }
图3 例程:CursorSpace初始化、CursorAlloc、CursorFree

点击(此处)折叠或打开

  1. /*Return true if L is empty*/
  2. int IsEmpty(List L)
  3. {
  4.     return CursorSpace[L].Next == 0;
  5. }
图4 测试一个链表释放为空的函数-游标实现

点击(此处)折叠或打开

  1. /*Return true if P is the last position in list*/
  2. /*Parameter L is unused in this implementation*/
  3. int IsLast(Position P, List L)
  4. {
  5.     return CursorSpace[P].Next == 0;
  6. }
图5 测试P是否是链表的末尾的函数-游标实现


点击(此处)折叠或打开

  1. /*Return Position of X in L;0 if not found*/
  2. /*Uses a header node*/
  3. Position Find(ElementType X, List L)
  4. {
  5.      Position P;
  6.     P = CursorSpace[L].Next;
  7.      while (P && CursorSpace[p].Element != X)
  8.         P = CursorSpace[P].Next;
  9.     return P;

  10. }
图6 例程 Find函数游标实现



点击(此处)折叠或打开

  1. /*Delete first occurrence X from a list*/
  2. /*Assume use of header node*/
  3. void Delete(ElementType X, List L)
  4. {
  5.     Position P, TmpCell;
  6.     P = FindPrevious(X, L);

  7.     if (!IsLast(P, L)) {
  8.     TmpCell = CursorSpace[P].Next;
  9.     CursorSpace[P].Next = CursorSpace[TmpCell].Next;
  10.     CursorFree(TmpCell);
  11.     }
  12. }
图7 对链表进行删除操作的例程 Delete - 游标实现


点击(此处)折叠或打开

  1. /*Insert(after legal position)*/
  2. /*Header implementation assumed*/
  3. /*Parameter L is unused in this implementation*/
  4. void Insert(ElementType X, List L, Position P)
  5. {
  6.     Position TmpCell;
  7.     TmpCell = CursorAlloc();
  8.     if (0 == TmpCell)
  9.         FatalError("Out of space!")

  10.     CursorSpace[TmpCell].Element = X;
  11.     CursorSpace[TmpCell].Next = CursorSpace[P].Next;
  12.     CursorSpace[P].Next = TmpCell;
  13. }
图8 对链表进行插入操作的例程 Insert-游标实现
阅读(4646) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~