Set 集合
基於鏈表和二分搜索樹
文章目錄
1、什麼是集合
數學上定義爲由一個或多個確定的元素所構成的整體。但是在計算機領域,集合被定義爲由一個或多個不同的元素所構成的整體。也就是說一個集合裏面的元素都是不同的。
這是由於這種特性,比較經典的就是用在語言統計上。查看一篇文章當中用了多少個詞彙,進而判斷用戶閱讀難度係數。
2、集合類的實現——基於鏈表
同棧和隊列相同,我們都是基於一些其他的數據結構來封裝我們的類。所以我們需要涉及集合的接口。由於我們之前已經封裝好了鏈表底層,具體的函數方法可以查看LinkedList鏈表這篇文章。
2.1、接口函數實現
具體的函數方法依然是增刪改查四個操作。這裏可以並沒有改操作,由於我們並不涉及索引概念,所以就沒有改操作。
接口函數實現:
public interface Set<E> {
void add(E e);
void remove(E e);
boolean contains(E e);
int getSize();
boolean isEmpty();
}
2.2、基本操作函數
由於我們之前已經封裝好了鏈表底層,具體的函數方法可以查看LinkedList鏈表這篇文章。
程序實現:
@Override
public int getSize() {
return linkedList.getSize();
}
@Override
public boolean isEmpty() {
return linkedList.isEmpty();
}
2.3、增加元素
程序實現:
@Override
public void add(E e) {
if (!linkedList.contains(e)) //集合中沒有該元素
linkedList.addFirst(e); //向鏈表頭添加元素時間複雜度最低
}
2.4、刪除元素
程序實現:
@Override
public void remove(E e) {
linkedList.removeElement(e);
}
2.5、查詢元素
程序實現:
@Override
public boolean contains(E e) {
return linkedList.contains(e);
}
@Override
public int getSize() {
return linkedList.getSize();
}
@Override
public boolean isEmpty() {
return linkedList.isEmpty();
}
3、集合類的實現——基於二分搜索樹
由於我們之前已經封裝好了鏈表底層,具體的函數方法可以查看 BST 二分搜索樹 這篇文章。
3.1、基本操作函數
@Override
public int getSize() {
return bst.getSize();
}
@Override
public boolean isEmpty() {
return bst.isEmpty();
}
3.2、增加元素
程序實現:
@Override
public void add(E e) {
bst.add(e);
}
3.3、刪除元素
程序實現:
@Override
public void remove(E e) {
bst.remove(e);
}
3.4、查詢元素
程序實現:
@Override
public boolean contains(E e) {
return bst.contains(e);
}
4、時間複雜度分析
我們從上面可以看出來,我們這幾個方法都非常簡介,這也正是由於我們底層封裝的好。
增加元素 | 刪除元素 | 查詢元素 | |
---|---|---|---|
鏈表 | O(N) | O(N) | O(N) |
二分搜索樹 | O(log(N)) | O(log(N)) | O(log(N)) |
這裏小夥伴可以會問,鏈表中添加元素在頭部添加難道不應該是O(1)的複雜度嗎,其實不是的,那是因爲在集合這個數據結構當中,我們需要保證元素不重複,就要先對鏈表進行遍歷一遍,所以複雜度也就是O(N)級別。
因此我們可以在表中看出來,底層是二分搜索樹的性能遠高於鏈表的實現。
最後
總的來說集合這種數據結構相對來說比較簡單。
更多精彩內容,大家可以轉到我的主頁:曲怪曲怪的主頁
或者關注我的微信公衆號:TeaUrn
源碼地址:可在公衆號內回覆 數據結構與算法源碼 即可獲得。