什麼型別可以作為key
使用有序,即key有序,map是基於紅黑樹的,每個節點為key-value,
value省略不寫。紅黑樹是二叉查詢樹的一種,先看乙個二叉查詢樹實現的map,結構如下:
8
/ \3 10
/ \ \
1 6 14
/ \ /
4 7 13
可以看到,按照先序遍歷的話key值依次是1 3 4 6 7 8 10 13 14是有序的。
二叉查詢樹有以下性質如果到此為止用二叉查詢樹實現map的話會有乙個問題,即如果插入的元素的key值本來就是有序的,那麼形成的二叉樹將是以下形式:
14/13
/10/8
/7/6
/4/3
/ 1
這樣帶來的問題便是複雜度的上公升,查詢的複雜度由o(log(n))退化為o(n),而避免複雜度退化的方法便是使用紅黑樹實現map,紅黑樹實質上是一種自平衡二叉查詢樹。
既然map是基於紅黑樹實現的那麼也就決定了,map的key是惟一的,不能有重複key.
另外,應為是有序的,所以要想有資格作為map的key,就必須具備可比較這個硬條件。
比如,基本型別中的int,char,string,
等都是可以比較大小的,當然可以作為key使用。
自己實現的類或者結構體可以作為key麼?
比如我們隨便寫乙個類作為key的例子,下邊的這段**是無法編譯通過的
#include
#include
class
ckeytest;~
ckeytest()
;int _age =0;
};intmain()
對ckeytest
這個類只需稍作修改,即可以了。
#include
#include
class
ckeytest;~
ckeytest()
;int _age =0;
bool
operator
<
(const ckeytest& obj)
const
};
將自定義類用作key有以下需要注意:
要過載比較操作符,如果類的「大小」無法比較,因為那麼在將新元素插入套紅黑樹的時候,咦?我的位置在哪呢?
程式實現時候要注意如果在類內過載<
,那麼這個「函式」必須是const
的,,即this
指標的型別等價於const &
否則還是不能用
上邊的操作符過載也可以通過友元實現,但是與第二條一樣引數型別必須是const &
, 如下:
class
ckeytest;~
ckeytest()
;int _age =0;
friend
bool
operator
<
(const ckeytest& obj,
const ckeytest& obj2);}
;bool
operator
<
(const ckeytest& obj,
const ckeytest& obj2)
map 容器的使用需要新增
標頭檔案, 並且使用命名空間std
,命名空間的使用,以下兩種方法都是可以的,
推薦使用第二種。
建議不要在函式外直接使用using namespace std;
#include
#include
int main (
)
#include
#include
int main (
)
size()
函式原型size_type size() const;
返回容器的元素數目,時間複雜度為o(1
)o(1)
o(1)
,我們看**實現:
_nodiscard size_type size()
const
noexcept
empty()
函式原型bool empty() const noexcept;
(c++11)
函式判斷map是否為空,時間複雜度為o(1
)o(1)
o(1)
,**實現如下,只是呼叫了一下上邊的size函式,在使用中遇到需要判斷是否為空的場景建議使用empty()
而不是size() == 0
.
_nodiscard bool
empty()
const
noexcept
max_size
函式原型size_type max_size() const;
map可以容納的最大元素數,有下面幾點需要知道: 獲取
map可以通過以下兩種方式獲取元素,操作符和函式
at()
前文提到過,map通常基於二叉樹實現,因此獲取的時間複雜度,即是二叉樹查詢的複雜度,也就是二叉樹的深度log(n)
#include
#include
intmain()
這兩種方法有以下不同,
at()
操作符成員函式
鍵值不存在時,新增新元素,因此可用於新增操作
不存在時丟擲異常
返回引用
被過載為兩種形式,可返回const
引用或者引用,可用於const &的形參
新增新元素
前邊提到,新增新元素可以通過操作符實現,也可以通過函式
insert
完成,時間複雜度log(n)
。
#include
#include
intmain()
刪除所有元素
函式void clear();
用於刪除所有元素,時間複雜度為o(n
)o(n)
o(n)
刪除指定元素
void erase (iterator position)
;size_type erase (
const key_type& k)
;void erase (iterator first, iterator last)
;
以上三個成員函式分別通過迭代器,鍵,和迭代器範圍刪除元素,前兩個刪除單個元素,第三個刪除多個元素。時間複雜度分別為o(1
)o(1)
o(1)
,o (l
og(n
))
o(log(n))
o(log(
n)),o(n
)o(n)
o(n)
find
iterator find (
const key_type& k)
;const_iterator find (
const key_type& k)
const
;
find通過鍵k
查詢對應元素,若從查詢到則返回對應迭代器,若未找到則返回map::end
,複雜度為log(n)
。
count
size_type count (
const key_type& k)
const
;
返回鍵k
對應的元素數,返回結果只可能為0或1,複雜度為log(n)
。 演算法之從入門到放棄
該系列筆記意在學習總結資料結構和演算法相關知識點 分享競賽和考研 工作面試中涉及的題目。該系列文章不定期更新,預計在2021 06 01前全部完成。以下是相關鏈結。如有錯誤,歡迎指正。1 基礎演算法 1.1 列舉 遍歷 1.2 模擬 1.3 遞迴 分治 1.4 貪心 1.5 排序 1.5.1 選擇排...
shell指令碼之從入門到放棄
批處理 預定義變數 用途 當前程序的程序號 pid 最後一次執行的命令的返回狀態。如果這個變數的值為 0,則證明上一條命令正確執行 如果這 個變數的值為非 0 具體是哪個數由命令自己來決定 則證明上一條命令執行錯誤 1後台執行的最後乙個程序的程序號 pid 備註 for,while,until三個大...
python從入門到實踐之字典
目錄 字典是乙個對映集合,他儲存的是鍵值對,通過鍵來查詢值,而不是索引 通過大括號 與鍵值對來表示乙個字典 字典名 鍵值對之間www.cppcns.com用冒號隔開,鍵值對之間用逗號隔開可以使用xnznkjd函式dict 生成乙個空字典 一般都是通過字典的鍵來查詢值,如果用值來查詢鍵,書上沒講怎麼查...