前言:本篇文章絕大部分來自《數據結構與算法分析C語言描述》中關於“鏈表的遊標實現”部分,要理解遊標這個概念就是起靜態鏈表指針的作用的,還有靜態鏈表裏爲什麼要準備一個“備用”的鏈表,靜態鏈表如何實現"malloc()"和"free()"的功能的,下面開始:
一、鏈表遊標實現的聲明
/* 鏈表的遊標實現,靜態鏈表 */
//鏈表遊標實現的聲明
#ifndef _Cursor_H
#define _Cursor_H
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 //鏈表的最大長度
typedef int ElemType; //定義一個元素型
typedef int List; //確定數組的頭元素,即可確定數組
typedef int PtrToNode; //定義一個指針型
typedef PtrToNode Position;
/* Place in the implementation file */
struct Node
{
ElemType Elem; //數據域
Position Next; //指針域
};
struct Node CursorSpace[MAXSIZE]; //結構數組
void InitCursorSpace(void); //建立新的靜態鏈表
List MakeEmpty( List L ); //L取值在1到MAXSIZE之間,不能取到0,l[0]是備用鏈表的頭結點
int IsEmpty( const List L );
int IsLast( const Position P, const List L );
Position Find( ElemType X, const List L );
void Delete( ElemType X, List L);
Position FindPrevious( ElemType X,const List L);
void Insert( ElemType X ,List L ,Position P );
void DeleteList( List L);
Position Header( const List L);
Position First( const List L);
Position Advance( const Position P);
ElemType Retrieve( const Position P);
#endif /* _Cursor_h */
二、Cursor.h函數實現
/* 相關函數實現 */
#include"Cursor.h"
#include<stdio.h>
/* 實現InitCursorSpace() */
/* 將一維數組CursorSpace中各分量鏈成一個備用鏈表
,CursorSpace[0].Next作爲頭指針 */
/* “0 ”表示空指針 */
void InitCursorSpace(void)
{
int i;
for( i = 0; i < MAXSIZE -1; ++i)
CursorSpace[i].Next = i + 1; //初始化備用鏈表
CursorSpace[MAXSIZE-1].Next = 0; //鏈表的頭結點
}
/* 實現malloc()函數的功能 */
static Position
CursorAlloc( void )
{
Position P;
P = CursorSpace[0].Next;
CursorSpace[0].Next = CursorSpace[P].Next;
return P;
}
/* 實現free()功能 */
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;
}
/* 測試P是否爲鏈表末尾的函數——遊標實現 */
/* Return true if P is the last position in list L */
int
IsLast( Position P,List L)
{
return CursorSpace[P].Next == 0;
}
/* Find——遊標實現 */
/* Return Position of X in L;0 if not find */
/* Uses a header node */
Position
Find( ElemType X, List L)
{
Position P;
P = CursorSpace[L].Next;
while( P && CursorSpace[P].Elem != X)
P = CursorSpace[P].Next;
return P;
}
/* 對鏈表進行刪除操作Delete——遊標實現 */
/* Delete first occurence of X from a list */
/* Assume use a header node */
void
Delete(ElemType X,List L)
{
Position P,TmpCell;
P= Find(X,L);
if(!IsLast( P,L))
{
TmpCell = CursorSpace[P].Next;
CursorSpace[P].Next = CursorSpace[TmpCell].Next;
CursorFree(TmpCell);
}
}
/* 對鏈表插入操作Insert——遊標實現 */
/* Insert after legal position P */
/* Header implementation assumed */
void
Insert(ElemType X, List L, Position P)
{
Position TmpCell ;
TmpCell = CursorAlloc();
if( TmpCell == 0)
printf("Out of space!!!");
CursorSpace[ TmpCell].Elem = X;
CursorSpace[TmpCell].Next = CursorSpace[P].Next;
CursorSpace[P].Next = TmpCell;
}
三、測試用主函數
* 測試用主函數 */
#include <stdio.h>
#include <stdlib.h>
#include"Cursor.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
ElemType Display( List L);
int main(void) {
InitCursorSpace();
printf("從第一個位置插入1到10\n") ;
int i;
int L=1;
for(i=1;i<=10;i++)
Insert( i, 1, i);
/*Insert(1,1,1) ;
Insert(2,1,2) ;
Insert(3,1,3) ;
Insert(4,1,4) ;
Insert(5,1,5) ;*/
CursorSpace[11].Next = 0;
CursorSpace[12].Next = 0;
/* printf("%5d\n",CursorSpace[1].Elem); */
Display( L) ;
printf("刪除第8個位置上的數\n");
Delete( 8, 1);
Display( L) ;
printf("在第8個位置插入666\n") ;
Insert(666, 1, 8);
Display( L) ;
return 0;
}
ElemType Display( List L){ //輸出表
if(L<0 || L > MAXSIZE-1)
return ERROR;
Position P;
P = CursorSpace[L].Next;
int i;
for(i=1;i<10;i++)
printf("**%d",CursorSpace[i].Elem);
/* while( P =!0 )
{
P= CursorSpace[P].Next;
printf("**%d",CursorSpace[P].Elem);
} */
printf("\n");
return OK;
}
主函數功能沒有實現,僅供參考;
並且這裏的List L和CursorSpace L是有很大區別的,一個是在原來的表裏取一部分元素鏈成一個表,後一個是直接創建了一個新表。