在接下來的幾個練習中,我介紹了map
介面的幾個實現。其中乙個基於雜湊表,這可以說是所發明的最神奇的資料結構。另乙個是類似的treemap
,不是很神奇,但它有附加功能,它可以按順序迭代元素。我們從乙個
map
開始,它使用鍵值對的list
實現。
1.實現mylinearmap
簡單來說,就是繼承map,放入list中,來看下初始結構
public
class
mylinearmap
implements
map@override
public k getkey()
@override
public v getvalue()
@override
public v setvalue
(v newvalue)
}
2.分析mylinearmap
兩個私有方法findentry
用於根據key值,找到對應的實體,equal
用於比較,下邊是實現:
private entry findentry
(object target)
}return null;
}private
boolean
equals
(object target, object obj)
return target.
equals
(obj)
;}
equals
執行時間取決於值的大小,跟數目無關,是常數時間o(1).
findentry
執行時間取決於數目,最好的情況下,可以一開始就找到,但是平均下來的話,仍要遍歷整個map,是線性時間,時間複雜度為o(n).
大部分的mylinearmap
核心方法使用findentry
,包括put
,get
,和remove
。這就是他們的樣子:
public v put
(k key, v value)
else
}public v get
(object key)
return entry.
getvalue()
;}public v remove
(object key)
else
}
這三個方法中,呼叫findentry
是線性時間,其餘操作都為常數時間,所以總的時間複雜度為線性時間。
總而言之,核心方法都是線性的,這就是為什麼我們將這個實現稱為mylinearmap
如果我們知道輸入的數量很少,這個實現可能會很好(很好的原因就是,數目少了有更大機率查詢為常數時間),但是我們可以做得更好。實際上,map
所有的核心方法都是常數時間的實現。當你第一次聽到這個訊息時,可能似乎覺得不可能。實際上我們所說的是,你可以在常數時間內大海撈針,不管海有多大。這是魔法。
我們不是將條目儲存在乙個大的list
中,而是把它們分解成許多短的列表(這樣查詢時就為常數時間)。對於每個鍵,我們將使用雜湊碼(在下一節中進行說明)來確定要使用的列表。 使用大量的簡短列表比僅僅使用乙個更快,但正如我將解釋的,它不會改變增長級別;核心功能仍然是線性的。但還有乙個技巧:如果我們增加列表的數量來限制每個列表的條目數,就會得到乙個恆定時間的對映。你會在下乙個練習中看到細節,但是首先要了解雜湊!
Early Orders 資料結構 思維
early orders 資料結構 思維 題目大意 給你乙個序列,讓你找乙個字典序最小的子串行,要求這子串行是乙個前k個數的全排列。題解 難度不太,冷靜思考。我用的優先佇列寫的,寫起來還是有點噁心,碼量不大,要注意很多細節。include define lson id 1 define rson i...
資料結構思維筆記(六)雙鏈表
1.雙鏈表資料結構list和deque介面的雙鏈表實現。所有的操作都能像雙向列表那樣執行。索引該列表中的操作將從頭或者尾遍歷列表,使用更接近指定索引的那個。linkedlist物件包含指向列表的第乙個和最後乙個元素的鏈結。所以我們可以從列表的任意一端開始,並以任意方向遍歷它。因此,我們可以在常數時間...
資料結構思想
程式的好壞一般來說有2個標準,乙個是時間複雜度,乙個是空間複雜度。時間複雜度說的是程式執行的時間 空間複雜度說的是程式的記憶體占用的多少。而資料結構就是為了解決時間複雜度的,或者說乙個好的資料結構 演算法 可以節省程式執行的時間。顧名思義,線性表是一條線的。首先要稍稍提一下,資料結構的儲存只有陣列 ...