另類的鍊錶資料結構以及演算法

2021-05-25 17:53:16 字數 2153 閱讀 9106

一般情況下,我們使用鍊錶無非就是在鍊錶結點中儲存該鍊錶中下乙個元素的指標.如果為了刪除方便,可能需要儲存前乙個元素的指標,也就是雙向鍊錶,這樣在刪除乙個結點的時候就可以很快的定位到前面和後面的結點,並且改變它們相應的指向.在這些操作裡面,指向鍊錶元素的指標無疑是最關鍵的資料.

考慮這樣乙個問題,如果兩個程序進行通訊,a程序負責管理鍊錶,b程序向a程序發出分配或者刪除鍊錶元素的請求.這種情況下,像上面所描述的那樣a程序直接向b程序返回鍊錶元素的指標是不能做到的了,很自然的,可以想到返回另乙個key標示該鍊錶元素.但是,當需要查詢或者刪除該鍊錶元素的時候,就不能像上面那樣馬上定位到鍊錶元素的位置了,需要遍歷整個鍊錶.原來常量級時間複雜度的演算法,在使用情形變換了之後變成了o(n)級別的複雜度.

可以找到別的辦法來解決這個問題.第一可以返回乙個key標示該鍊錶元素,第二保證了時間的複雜度,在這裡需要定義一種新的資料結構和演算法來解決這個問題.

首先,我們使用乙個陣列,陣列中的元素是指向鍊錶元素的指標,而指標的索引則是每個鍊錶元素的id,這樣,通過id就可以馬上定位到對應的鍊錶元素.

但是這裡又會出現另乙個問題,該id是從零開始的,假如在一段時間之後,需要分配乙個新的鍊錶元素,如何知道陣列中的哪個位置是可以分配的?在這裡,使用了乙個整型資料的陣列,陣列中的每個元素是該id對應的鍊錶元素在鍊錶中下乙個結點的id(有點拗口).我們使用兩個煉表頭,乙個將已經使用的鍊錶元素id連線起來,另乙個則將未使用的鍊錶元素id連線起來.於是,在程式初始化的時候,未使用的鍊錶中儲存了所有的id,而已經使用的鍊錶為空.每次分配了乙個新的鍊錶元素,將它的id放在使用鍊錶的最開始;而每次釋放乙個鍊錶元素,將它的id放到未使用的鍊錶頭部.

同時,改變原先鍊錶元素的定義,在該結構體中,儲存的不再是指標,而是鍊錶中前乙個元素的陣列索引id.而它的下乙個元素id則儲存在上面的那個陣列中.

如果上面我的解釋還不夠明白,可以看看下面的**:

#include 

<

stdio.h

>

#define

list_node_null -1

#define

array_size 200

/*鍊錶元素定義 

*/typedef 

struct

list_node

list_node;

/*存放鍊錶元素指標的陣列 

*/list_node

*list_array[array_size];

/*未使用鍊錶的頭結點id 

*/int

top_of_free;

/*已使用鍊錶的頭結點id 

*/int

top_of_used;

/*儲存鍊錶下乙個元素結點id的鍊錶 

*/int

next_list[array_size];

void

init_list()

/*最後乙個結點是空 

*/next_list[i -1

] =list_node_null;

top_of_free =0

;top_of_used 

=list_node_null;

}int

alloc_list_node()

/*未使用煉表頭結點往下走一步 

*/top_of_free 

=next_list[top_of_free];

if(null 

==list_array[id])}if

(list_node_null 

==top_of_used)

else

return

id;}

void

free_list_node(

intid)if(

list_node_null != next &&

null 

!=list_array[next])if

(id 

==top_of_used)

/*將鍊錶id返回到free鍊錶頭部並且修改free煉表頭結點 

*/next_list[id] 

=top_of_free;

top_of_free 

=id;

}int

main()

這個想法很巧妙,有效的避免了查詢和刪除陣列元素帶來的開銷.我不知道具體的出處在**,如果您知道,勞煩告訴我一聲:)

資料結構 PTA 鍊錶逆置 另類堆疊 函式 鍊錶

本題要求實現乙個函式,將給定單向鍊錶逆置,即表頭置為表尾,表尾置為表頭。鍊錶結點定義如下 struct listnode struct listnode reverse struct listnode head 其中head是使用者傳入的鍊錶的頭指標 函式reverse將鍊錶head逆置,並返回結果...

資料結構與演算法 鍊錶

題目 合併兩個已經排序好的鍊錶 非遞迴和遞迴兩種 方法1 cpp view plain copy print color 000000 合併鍊錶.cpp 定義控制台應用程式的入口點。include stdafx.h include using namespace std struct listnod...

資料結構與演算法 鍊錶

在講述鍊錶之前讓我們對資料結構進行乙個簡單的回顧 我們知道,資料結構指的是描述實際問題中各個資料項節點之間的前後邏輯結構關係,即要麼是線性結構 即某一資料項的前繼節點和後繼節點有且只有乙個 要麼是非線性結構 即某一資料節點的前驅或者後繼節點不止乙個 在確定了實際資料項的資料結構之後,我們要採用某種儲...