連結串列-遊標實現(C語言版)
阿新 • • 發佈:2019-01-24
如果用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();
List 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函式來測試一下。
如果有錯誤,請積極指正。
注:程式碼改編自《資料結構與演算法分析》第二版