您的位置:首页 > 编程语言 > C语言/C++

链表-游标实现(C语言版)

2016-10-16 14:59 218 查看
如果用C/C++写链表的话,用指针会比较方便,但很多语言都没有指针,那么怎么实现比较好呢?游标是个不错的选择。

在用指针实现的链表中,有这样两个特点:

1.数据存在一组结构体中,并且每个结构体都有指向下一个结构体的指针。

2.一个新的结构体可以通过malloc获取内存,也可以用free来释放内存。

游标法也得满足这两个条件。满足条件1比较简单,用一个全局的结构体数组就行了;满足条件2的话可以保留一个表,如图:


0表示表头,然后他们的初始关系是这样这样:


当执行malloc功能时,我们把表头指向的单元拿出来使用,然后把表头指向下一个空单元,执行free功能时,将目标单元回收就行了。

这个表取名叫CursorSpace,下面给出CursorSpace的malloc和free的代码:

static Position CursorAlloc(void)
{
Position P;

P = CursorSpace[0].Next;
CursorSpace[0].Next = CursorSpace[P].Next;

return P;
}

static void CursorFree(Position P)
{
CursorSpace[ P ].Next = CursorSpace[ 0 ].Next;
CursorSpace[ 0 ].Next = P;
}


将代码和图结合起来试一试,应该很容易就能理解了。

下面给出完整代码:

1.头文件:

#ifndef CURSORLIST_H_INCLUDED
#define CURSORLIST_H_INCLUDED

typedef double ElementType;
typedef int PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;

void InitializeCursorSpace( void );

List MakeEmpty(List L);
int IsEmpty(const List L);
int IsLast(const Position P,const List L);
Position Find(ElementType X,const List L);
void Delete(ElementType X,List L);
Position FindPrevious(ElementType X,const List L);
void Insert(ElementType X,List L,Position P);
void DeleteList(List L);
Position Header(const List L);
Position First(const List L);
Position Advance(const Position P);
ElementType Retrieve(const Position P);

#endif // CURSORLIST_H_INCLUDED


2。实现:

#include "CursorList.h"
#include <stdio.h>
#define SpaceSize 100

struct Node
{
ElementType Element;
Position Next;
};

struct Node CursorSpace[ SpaceSize ];

static Position CursorAlloc(void) { Position P; P = CursorSpace[0].Next; CursorSpace[0].Next = CursorSpace[P].Next; return P; } static void CursorFree(Position P) { CursorSpace[ P ].Next = CursorSpace[ 0 ].Next; CursorSpace[ 0 ].Next = P; }

/* Return true if L is empty */
int IsEmpty(List L)
{
return CursorSpace[L].Next == 0;
}

/* Return true if P is the last position in list L */
/* Parameter L is unused in this implementation */
int IsLast(Position P,List L)
{
return CursorSpace[P].Next == 0;
}

/* Return Position of X in L;0 if not found */
/* Uses a header node */
Position Find(ElementType X,List L)
{
Position P;

P = CursorSpace[ L ].Next;
while(P && CursorSpace[P].Element != X)
P = CursorSpace[P].Next;

return P;
}

/* Delete first occurrence of X in L; 0 if not found */
/* Assume use of a header node */
void Delete(ElementType X,List L)
{
Position P,TmpCell;

P = FindPrevious(X,L);

if(!IsLast(P,L))
{
TmpCell = CursorSpace[ P ].Next;
CursorSpace[ P ].Next = CursorSpace[ TmpCell ].Next;
CursorFree(TmpCell);
}
}

/* Insert (after legal position P) */
/* Header implementation assumed */
/* Parameter L is unused in this implementation */
void Insert(ElementType X,List L,Position P)
{
Position TmpCell;

TmpCell = CursorAlloc();
if(TmpCell == 0)
FatalError("Out of space!!!");

CursorSpace[TmpCell].Element = X;
CursorSpace[TmpCell].Next = CursorSpace[ P ].Next;
CursorSpace[P].Next = TmpCell;
}

/* initialize the CursorSpace */
void InitCursorSpace()
{
int i;
for(i = 0; i < SpaceSize; i++)
CursorSpace[i].Next = i==SpaceSize-1?0:i+1;
}

/* Find the front of the first X of The list */
/* Return 0 if not found */
Position FindPrevious(ElementType X,const List L)
{
Position P;
P = L;
while(P&&CursorSpace[CursorSpace[P].Next].Element != X)
P = CursorSpace[P].Next;
return P;
}

/* Do something when the fatal error occurred */
void FatalError(char * s)
{
printf("%s\n",s);
/* stop the program if necessary */
}

int main()
{
InitCursorSpace();
Li
4000
st a = CursorAlloc();
CursorSpace[a].Next = 0;
Insert(1,a,a);
Insert(0,a,a);
Insert(12.998,a,a);
Delete(12.998,a);
//Delete(0,a);
Position P = CursorSpace[a].Next;
printf("%lf\n",CursorSpace[P].Element);
}


同样在最后加了个main函数来测试一下。

如果有错误,请积极指正。

注:代码改编自《数据结构与算法分析》第二版
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  malloc 链表 c语言