二叉樹(binary tree)和哈希表(hash table)都是很基本的數據結構,可是咱們要怎麼從二者之間進行選擇呢?他們的不一樣是什麼?優缺點分別是什麼?數據結構
回答這個問題不是一兩句話能夠說清楚的,緣由是在不一樣的狀況下,選擇的依據確定也不一樣。首先來回顧一下這兩個數據結構:wordpress
哈希表使用hash function來對輸入的數據分配index到哈希表對應的槽中。假設有一個哈希表的size是100,而咱們輸入的數據是從0~99,咱們要把輸入數據儲存到哈希表中。理論上來講,該哈希表插入和查找操做的時間複雜度都是O(1)。排序
二叉樹遵循右子樹大於根節點,左子樹小於根節點的原則進行數據的插入和保存。若是這個樹的平衡的,那麼,對於每一個元素的插入和查找操做的時間複雜度是O(log(n)),n是樹的節點個數,log(n)一般是樹的深度。固然,對於不平衡的狀況,那就須要更復雜的數據結構的樹(紅黑樹等)進行處理。get
上文彷佛得出結論哈希表要好於二叉樹,可是it is not always the case。哈希表有如下幾個突出的缺點:hash
當更多的數插入時,哈希表衝突的可能性就更大。對於衝突,哈希表一般有兩種解決方案:第一種是線性探索,至關於在衝突的槽後創建一個單鏈表,這種狀況下,插入和查找以及刪除操做消耗的時間會達到O(n),且該哈希表須要更多的空間進行儲存。第二種方法是開放尋址,他不須要更多的空間,可是在最壞的狀況下(例如全部輸入數據都被map到了一個index上)的時間複雜度也會達到O(n)。it
因此,在決定創建哈希表以前,最好能夠估計輸入的數據的size。不然,resize哈希表的過程將會是一個很是消耗時間的過程。例如,若是如今你的哈希表的長度是100,可是如今有第101個數要插入。這時,不只哈希表的長度可能要擴展到150,且擴展以後全部的數都須要從新rehash。io
哈希表中的元素是沒有被排序的。然而,有些狀況下,咱們但願儲存的數據是有序的。table
另外一方面,咱們討論二叉樹:function
二叉樹不會有衝突(collision),這意味着咱們可以保證二叉樹的插入和查找操做一直都是O(log(n))的時間複雜度。擴展
二叉樹的空間佔用跟輸入的輸入數據一致。因此咱們不須要爲二叉樹預先分配固定的空間。因此,你也不須要預先知道輸入數據的size。
全部的元素在樹中是排序好的。
若是你預先知道輸入數據的大小,並且有足夠的空間儲存哈希表,且不須要對數據進行排序,那麼哈希表老是好的。由於哈希表在插入,查找和刪除操做中只須要常數時間。
另外一方面,若是數據是持續的加入,你預先不知道數據的大小,那麼二叉樹是一個折中的選擇。
Reference:
Hash table vs Binary search tree