不借助指標實現鍊錶 利用多陣列實現

2021-10-04 17:16:57 字數 1970 閱讀 3729

有些語言不提供指標,這時候我們怎麼實現鍊錶?可以借助陣列來實現。

基本思路如下:在鍊錶中,之所以利用指標,主要是用來儲存後繼節點和前驅節點的位置。如果不用指標,使用陣列下標也可以表示乙個節點的位置。比如我們可以定義三個陣列:key,next和prev,key[i]用來存放i號節點的值,next[i]用來存放i號節點的後繼節點的下標,prev[i]用來存放i號節點的前驅節點的下標。這樣借助於陣列的下標體系,我們一樣可以儲存各個節點之間的位置關係。

我們用乙個常量來儲存頭節點的下標,這樣,乙個基於陣列的鍊錶就實現了(源於《演算法導論》圖10-5)

這樣,所定義陣列的長度,相當於該鍊錶的最大長度。鍊錶初始狀態為0,整個陣列處於「未用」狀態。每次在列表中插入乙個節點,從「未用」陣列中分配乙個節點,連到現有鍊錶中。這樣,還需要資訊來記錄陣列中有多少未用空間。我們用乙個變數free來指向第乙個未用節點的下標,下乙個未用節點就是next[free],以此類推,這樣,基於next陣列,整個未用空間也是乙個鍊錶。

每次向鍊錶中插入節點時,從未用空間鍊錶的頭部取下第乙個節點,用來儲存新的結點,然後連到資料鏈表的頭部。每次刪除節點時,將該節點從資料節點中刪除,然後將其插入未用空間鍊錶的頭部。

過程如圖所示(源於《演算法導論》圖10-7)

明白了基於多陣列實現鍊錶的原理後,我們試著寫一下**。

首先定義多陣列的鍊錶,利用結構體定義即可:

struct mylist ;
初始化函式:初始空間都是未用狀態,將其連線後,歸入未用空間鍊錶。資料鏈表為空,用值為-1代表空即可。

void init_list(struct mylist* l) 

l->next[19] = -1;

l->head = -1;

}

分配空間的函式allocate_object,從未分配空間鍊錶中取出表頭節點,並返回。我們用下標指代節點,所以返回int值即可。

int allocate_object(struct mylist *l) 

int x = l->free;

l->free = l->next[l->free];

return x;

}

歸還空間的函式free_object。將該節點連線到未分配空間鍊錶的表頭即可。

void free_object(struct mylist* l, int x)
向資料鏈表中插入節點的函式list_insert。需要先從未分配空間中申請乙個節點,然後插入資料鏈表的頭部。

void list_insert(struct mylist* l, int x) 

l->key[i] = x;

l->next[i] = l->head;

l->prev[i] = -1;

l->prev[l->head] = i;

l->head = i;

}

從資料鏈表中刪除節點的函式list_delete。先將該節點從資料鏈表中刪除,然後將該節點連線到未用空間鍊錶的頭部。

void list_delete(struct mylist* l, int i) 

else

free_object(l, i);

}

在主函式中測試一下各個功能,檢查無誤,大功告成!

int main() 

list_delete(l, 3);

int i = l->head;

while (i != -1)

return 0;

}

HashMap實現原理,利用陣列和鍊錶儲存元素

陣列 儲存區間連續,占用記憶體嚴重,定址容易,插入刪除困難 鍊錶 儲存區間離散,占用記憶體比較寬鬆,定址困難,插入刪除容易 hashmap綜合應用了這兩種資料結構,實現了定址容易,插入刪除也容易 hashmap結構示意圖 實現原理 用乙個陣列來儲存元素,但是這個陣列儲存的不是基本資料型別。hashm...

C 佇列的幾種實現方式(陣列 指標 鍊錶)

佇列遵循先進先出原則,所以入隊位置固定,出隊位置也固定。include define maxsize 5 佇列最大長度 using namespace std int tag 0 0代表出隊,1代表入隊 struct qtqueue void initqueue qtqueue s bool enq...

利用雙重指標來實現單向鍊錶的節點交換

一道leetcode中的題 given a linked list,swap every two adjacent nodes and return its head.for example,given 1 2 3 4,you should return the list as 2 1 4 3.yo...