鏈表的游標(cursor)實現


諸如BASIC和FORTRAN等許多語言都不支持指針。如果需要鏈表而又不能使用指針,這時我們可以使用游標(cursor)實現法來實現鏈表。

在鏈表的實現中有兩個重要的特點:

燈泡數據存儲在一組結構體中。每一個結構體包含有數據以及指向下一個結構體的指針。

燈泡一個新的結構體可以通過調用malloc而從系統全局內存(global memory)得到,並可以通過free而被釋放。

游標法必須能夠模仿實現這兩條特性:

紅心定義一個全局的結構體數組(模擬系統全局內存)。對於數組中的任何單元,其數組下標可以用來代表一個地址。

typedef int ptr_to_node;
typedef ptr_to_node list;
typedef ptr_to_node position;

struct node
{
    element_type     element;
    position         next;
};

struct node cursor_space[spacesize];

紅心在這個全局的結構體數組中,保留一個表freelist作為備用單鏈表,用來malloc或free游標可用空間,該表用0作為表頭。剛開始時,freelist就是整個結構體數組。

需要理解的是:所有的鏈表,包括備用表和已用表,全部都在我們定義的全局結構體數組中,只是它們的表頭不同,從不同的表頭出發形成了不同的單鏈表。

假設我們定義了一個大小為11的游標空間,其初始化狀態如下:

Slot Element Next
0
1
2
3
4
5
6
7
8
9
10
  1
2
3
4
5
6
7
8
9
10
0

注:對於Next, 0的值等價於NULL指針。

上面的狀態用鏈表形式表示為:cursor_space[0]—>cursor_space[1]—>cursor_space[2]—>cursor_space[3]—>cursor_space[4]—>cursor_space[5]—>cursor_space[6]—>cursor_space[7]—>cursor_space[8]—>cursor_space[9]—>cursor_space[10]—>NULL.

為執行malloc功能,將(在表頭后面的)第一個元素從freelist中刪除。為了執行free功能,我們將該單元放在freelist的前端。

malloc和free的游標實現如下:

static position
cursor_alloc(void)
{
    position p;

    p = cursor_space[0].next;
    cursor_space[0].next = cursor_space[p].next;

    return p;
}

static void
cursor_free(position p)
{
    cursor_space[p].next = cursor_space[0].next;
    cursor_space[0].next = p;
}

為加深理解,請參考如下實例:

Slot Element Next
0
1
2
3
4
5
6
7
8
9
10
-
b
f
header
-
header
-
c
d
e
a
6
9
0
7
0
10
4
8
2
0
1

如果單鏈表L的值是5,M的值是3,我們又規定了freelist表頭為0,因此,從上表中我們可以得到三個鏈表:

freelist:cursor_space[0]—>cursor_space[6]—>cursor_space[4]—>NULL 

L:header—>a—>b—>e—>NULL

M:header—>c—>d—>f—>NULL

freelist是分配L、M鏈表后還剩余的可分配空間。

 

游標實現

/* return ture if L is empty */
int isempty(list L)
{
    return cursor_space[L].next = 0;
}
/* return true if P is the last position in list L */

int islast(position p, list L)
{
    return cursor_space[P].next == 0;
}
/* return position of X in L; 0 if not found */
/* uses a header node */

position find(element_type X, list L)
{
    position p;
    
    p = cursor_space[L].next;
    while(p && cursor_space[p].element != X)
        p = cursor_space[p].next;
    
    return p;
}
/* delete first occurence of X from a list */
/* assume use of a header node */

void delete(element_type X, list L)
{
    position p, tmpcell;
    
    p = find_previous(X, L);
    
    if(!islast(p, L))
    {
        tmpcell = cursor_space[p].next;
        cursor_space[p].next = cursor_space[tmpcell].next;
        cursor_free(tmpcell);
    }
}
/* insert (after legal position P) */

void insert(element_type X, list L, position P)
{
    position tmpcell;
    
    tmpcell = cursor_alloc();
    if(tmpcell == 0)
        fatal_error("out of sapce!!!");

    cursor_space[tmpcell].element = X;
    cursor_space[tmpcell].next = cursor_space[P].next;
    cursor_space[P].next = tmpcell;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM