資料結構實現 4.2:集合_基於連結串列實現(C++版)
阿新 • • 發佈:2018-11-27
資料結構實現 4.2:集合_基於連結串列實現(C++版)
1. 概念及基本框架
在4.1 中我們通過 二分搜尋樹 實現了集合,這一節我們通過 連結串列 來實現集合。
集合 的基本特性依然要滿足:集合內的元素 不能重複
注:有些集合(多重集合)中元素也可以重複。
同 4.1 一樣,我們先利用一個由 純虛擬函式 構成的 抽象類 作為一個介面來定義這些操作。具體程式碼如下:
template <class T>
class Set{
public:
virtual int size() = 0;
virtual bool isEmpty() = 0;
//增加操作
virtual void add(T num) = 0;
//刪除操作
virtual void remove(T num) = 0;
//查詢操作
virtual bool contains(T num) = 0;
};
下面只需要通過繼承 抽象類
template <class T>
class LinkedListSet : public Set<T>{
...
private:
LinkedList<T> list;
};
同樣,這裡為了避免重複設計就可以相容更多資料型別,引入了 泛型 ,即 模板 的概念。(模板的關鍵字是 class 或 typename)
這裡的 list 表示一個 連結串列 ,同樣,為了保護資料,變數設定為 private 。
注:這裡沒有顯式的給出建構函式,因為子類中除了連結串列物件之外沒有特別需要初始化的東西。編譯器會預設先呼叫 連結串列
實現了前面的程式之後,接下來就是一個集合的增、刪、查以及一些其他基本操作,接下來利用程式碼去實現。
2. 基本操作程式實現
2.1 增加操作
template <class T>
class LinkedListSet : public Set<T>{
public:
...
//增加操作
void add(T num){
if (!list.contains(num)){
list.addFirst(num);
}
}
...
};
為了減小時間複雜度,這裡使用針對連結串列第一個元素進行操作,下面的同理。
注:這裡需要進行判斷,因為連結串列中的元素可以重複。
2.2 刪除操作
template <class T>
class LinkedListSet : public Set<T>{
public:
...
//刪除操作
void remove(T num){
while (list.contains(num)){
list.removeElement(num);
}
}
...
};
因為我實現的連結串列只能刪除第一個滿足條件元素,為了刪除所有滿足條件元素,需要迴圈判斷。實際實現只需要遍歷一遍連結串列即可完成刪除操作。
2.3 查詢操作
template <class T>
class LinkedListSet : public Set<T>{
public:
...
//查詢操作
bool contains(T num){
return list.contains(num);
}
...
};
2.4 其他操作
集合還有一些其他的操作,包括 集合大小 的查詢等操作。
template <class T>
class LinkedListSet : public Set<T>{
public:
int size(){
return list.size();
}
bool isEmpty(){
return list.isEmpty();
}
...
};
3. 演算法複雜度分析
3.1 增加操作
函式 | 最壞複雜度 | 平均複雜度 |
---|---|---|
add | O(n) | O(n) |
因為需要判斷是否存在該元素,所以需要遍歷一遍整個連結串列。
3.2 刪除操作
函式 | 最壞複雜度 | 平均複雜度 |
---|---|---|
remove | O(n) = | O(n) |
3.3 查詢操作
函式 | 最壞複雜度 | 平均複雜度 |
---|---|---|
contains | O(n) | O(n/2) = O(n) |
總體情況:
操作 | 時間複雜度 |
---|---|
增 | O(n) |
刪 | O(n) |
查 | O(n) |
由於連結串列不具有有序性,所以操作都需要 O(n) 級別的時間複雜度。
4. 完整程式碼
程式完整程式碼(這裡使用了標頭檔案的形式來實現類)如下,本節不再提供 連結串列 類的實現程式碼,如有需要,可參看 2.1 。
抽象類 介面程式碼:
#ifndef __SET_H__
#define __SET_H__
template <class T>
class Set{
public:
virtual int size() = 0;
virtual bool isEmpty() = 0;
//增加操作
virtual void add(T num) = 0;
//刪除操作
virtual void remove(T num) = 0;
//查詢操作
virtual bool contains(T num) = 0;
};
#endif
集合類 程式碼:
#ifndef __LINKEDLISTSET_H__
#define __LINKEDLISTSET_H__
#include "LinkedList.h"
#include "Set.h"
template <class T>
class LinkedListSet : public Set<T>{
public:
int size(){
return list.size();
}
bool isEmpty(){
return list.isEmpty();
}
//增加操作
void add(T num){
if (!list.contains(num)){
list.addFirst(num);
}
}
//刪除操作
void remove(T num){
while (list.contains(num)){
list.removeElement(num);
}
}
//查詢操作
bool contains(T num){
return list.contains(num);
}
private:
LinkedList<T> list;
};
#endif