golang本身對常用集合的封裝還是比較少的,主要有陣列(切片)、雙向連結串列、堆等。在工作中可能用到其他常用的集合,於是我自己對常用的集合進行了封裝,並對原理做了簡單介紹,程式碼庫地址:https://github.com/chentaihan/container,程式碼都是經過測試的,歡迎下載使用,反饋的問題我會第一時間修復
ArraySort排序陣列
ArraySort使用陣列儲存資料,新增的時候通過類似二分查詢找到插入位置,插入位置後面的資料往後移動一位,插入新元素,查詢就是二分查詢,刪除就是通過二分查詢找到對應的元素,之後的元素都向前移動一位。時間複雜度如下:
功能 | 時間複雜度 |
---|---|
新增 | O(n) |
刪除 | O(n) |
查詢 | O(logn) |
LinkList單連結串列
通過連結串列頭指標和連結串列尾兩個指標將所有元素連結在一起,可以快速的在表頭和表尾插入元素,刪除和查詢都是遍歷連結串列,查詢對應的元素,刪除還需要改變指標指向。時間複雜度如下:
功能 | 時間複雜度 |
---|---|
新增 | O(1) |
刪除 | O(n) |
查詢 | O(n) |
Queue迴圈佇列
佇列先進先出,迴圈佇列採用陣列儲存元素,以迴圈的方式在陣列中新增元素,當陣列寫滿之後自動擴容,元素個數小於1M時二倍擴容,大於等於1M時每次加1M,刪除元素的時候需要將對應的位置賦值為空指標,方便被刪除的元素被回收。時間複雜度如下:
功能 | 時間複雜度 |
---|---|
進佇列 | O(1) |
出佇列 | O(1) |
QueueLink連結串列佇列
佇列先進先出,實現和單連結串列類似,進棧是在表尾新增元素,出棧就是表頭出棧,即表頭指向表頭的下一個元素,相對陣列實現的迴圈佇列,連結串列佇列不存在擴容的問題,但每個元素多了一個指標。時間複雜度如下:
功能 | 時間複雜度 |
---|---|
進佇列 | O(1) |
出佇列 | O(1) |
PriorityQueue優先順序佇列
優先順序佇列採用小堆實現,小堆採用陣列儲存資料,按照完全二叉樹的方式運算元據,每個節點的值都小於等於左右子節點的值,保證了每次出隊的都是最小值,即按照順序出隊。
時間複雜度如下:
功能 | 時間複雜度 |
---|---|
進佇列 | O(logn) |
出佇列 | O(logn) |
Stack棧
棧先進後出,採用陣列儲存元素,每次進棧的是棧頂元素,出棧的也是棧頂元素,當陣列寫滿之後自動擴容,元素個數小於1M時二倍擴容,大於等於1M時每次加1M。時間複雜度如下:
功能 | 時間複雜度 |
---|---|
進棧 | O(1) |
出棧 | O(1) |
StackLink連結串列棧
佇列先進先出,採用單連結串列儲存資料,進棧是在表頭新增元素,出棧就是表頭出棧,即表頭指向表頭的下一個元素,相對陣列實現的迴圈佇列,連結串列佇列不存在擴容的問題,但每個元素多了一個指標。時間複雜度如下:
功能 | 時間複雜度 |
---|---|
進棧 | O(1) |
出棧 | O(1) |
Map
對golang的map簡單封裝,增加了一些方法。對於golang中map的實現原理請看我的這篇文章:https://www.cnblogs.com/hlxs/p/10408961.html,時間複雜度如下:
功能 | 時間複雜度 |
---|---|
新增 | O(1) |
修改 | O(1) |
查詢 | O(1) |
刪除 | O(1) |
MapSync同步map
就是map+讀寫鎖,時間複雜度和map一樣
LinkMap
雙向連結串列 + map,雙向連結串列按照順序儲存新增的元素,可以按照新增的順序遍歷資料,增刪改查時間複雜度都和map一樣
TreeMap
通過二叉搜尋樹儲存資料,後面會詳細介紹二叉搜尋樹,使用二叉搜尋樹就不存在擴容的問題,hashmap則存在擴容的問題,時間複雜度如下:
功能 | 時間複雜度 |
---|---|
新增 | O(logn) |
修改 | O(logn) |
查詢 | O(logn) |
刪除 | O(logn) |
LRU
lru的實現原理其實和LinkMap幾乎一樣,只不過lru在修改或是查詢的時候都會將被訪問的元素移到連結串列的表頭,表尾的資料是最先被淘汰的,時間複雜度如下:
功能 | 時間複雜度 |
---|---|
新增 | O(1) |
修改 | O(1) |
查詢 | O(1) |
刪除 | O(1) |
BinaryTree二叉搜尋樹
提供二叉搜尋樹的增刪改查功能,刪除相對複雜點,時間複雜度如下:
功能 | 時間複雜度 |
---|---|
新增 | O(logn) |
修改 | O(logn) |
查詢 | O(logn) |
刪除 | O(logn) |
heap大堆
堆是對golang本身container/heap的簡單封裝,大堆中某個節點的值總是不大於其父節點的值;堆總是一棵完全二叉樹。,時間複雜度如下:
功能 | 時間複雜度 |
---|---|
新增 | O(logn) |
查詢 | O(n) |
刪除 | O(logn) |
heap小堆
堆是對golang本身container/heap的簡單封裝,小堆中某個節點的值總是不小於其父節點的值;堆總是一棵完全二叉樹。,時間複雜度如下:
功能 | 時間複雜度 |
---|---|
新增 | O(logn) |
查詢 | O(n) |
刪除 | O(logn) |