C++做演算法題,容器知識看這一篇就夠啦!

loopyhz發表於2024-08-17

C++常用容器分享(演算法題,掌握這些就夠了)

vector

是什麼

連續的順序儲存結構,其實就是一個可變陣列
想使用的話記得 #include<vector>

怎麼用

初始化語法 vector<型別> 名字(長度,初始值)

演示一下

// 一維的vector 
vector<int> arr; // 不指定裡面有多少個元素
vector<int> arr(100); // 指定裡面有100個元素 這100個元素都是預設值 0
vector<int> arr(100, 1); // 指定裡面有100個元素,每個元素指定為1

// 二維的vector 
vector<vector<int>> arr;  // 不初始化行列  
vector<vector<int>> arr(100, vector<int>()); // 100行 但是沒初始化列數
vector<vector<int>> arr(100, vector<int>(100, 1)); // 100行100列 每個值都是1

常用的操作

列舉一下

arr.push_back(1) // 把1插入到這個vector的尾部   長度 +1 
arr.pop_back() // 把最後一個元素刪除了   長度  -1    
arr.size() // 獲取長度
arr.clear() // 清空
arr.empty() // 返回值是bool 是空的就返回true
arr.resize(新長度, 預設值) 
// 如果是縮短,則刪除多餘的值  如果是擴大,且指定了預設值,則新元素均為預設值(舊元素不變)

stack

是什麼

透過二次封裝雙端佇列 (deque) 容器,實現先進後出的棧資料結構。
想使用的話記得 #include<stack>

怎麼用

初始化 stack<型別> 名字

常用操作

// stk是我們初始化好的棧
stk.push(1) // 把 1進棧
stk.pop() //  把棧頂元素出棧   注意 這個沒法取到棧頂元素  只是把他扔出去
stk.top() //  取到棧頂元素
stk.size() // 獲得棧的大小
stk.empty() 

注意 :

  1. 沒有 clear resize 方法
  2. 不能取內部元素 不能遍歷

queue

是什麼

透過二次封裝雙端佇列 (deque) 容器,實現先進先出的佇列資料結構。
使用記得 #include<queue>

怎麼用

初始化 queue<型別> que

que.push() // 入隊
que.pop() // 出隊
que.front() // 取隊首 
que.back() // 取隊尾
que.size() // 大小
que.empty() 

注意:

  1. 沒有 clear resize 方法
  2. 不能取內部元素 不能遍歷

優先佇列

是什麼

一個持續維護元素有序性的佇列 也就是一個堆
提供常數時間的最大元素查詢,對數時間的插入與提取,底層原理是二叉堆。
使用記得 #include<queue>

怎麼用

初始化 priority_queue<型別, 容器,比較器>
型別: 要儲存的資料型別
容器: 儲存資料的底層容器,預設是vector, 寫演算法題就保持預設就行了
比較器: 預設是less<型別> 型別 可以自定義 預設的話就是初始了一個大頂堆 堆頂元素最大

綜上,寫演算法題常見的兩種初始化方式如下

priority_queue<int> que; // 預設的 只寫型別就行了 大頂堆
priority_queue<int,vector<int>,greater<int>> que // 自定義的就要全都寫上  小頂堆

常用操作

que.push(1) // 進堆
que.pop() // 出堆
que.top() // 取堆頂
que.size // 佇列大小
que.empty();  // 判空

注意:

  1. 不能遍歷 不能取裡面的某一個元素 只能取堆頂元素

set

是什麼

提供對數時間的插入、刪除、查詢的集合資料結構。底層原理是紅黑樹。
還可以去重 有的時候去重會用他
一共有三種set

分別是:

set: 去重 有序(從小到大)
multiset: 不去重 有序(從小到大)
unordered_set: 去重 無序

怎麼用

初始化 set<型別,比較器> st
比較器預設是 less<型別> 也就是從小到大

所以有下面兩種初始化的方式

set<int> st // 從小到大
set<int,greater<int>> st // 從大到小

常用方法:

st.insert() // 插入元素
st.erase()  // 刪除元素
st.find()  // 查詢元素   返回的是一個迭代器 如果元素存在 返回指向這個元素的迭代器 不存在就返回末尾的迭代器
auto it = st.find() 
cout << *it << endl  // 要這麼用 才能拿到查詢的這個元素

st.count()  // 查詢元素存在不存在  返回1就是存在
// size() clear() empty() 均存在

他是可以遍歷的!!

// 方法1  用迭代器遍歷
for(set<int>::iterator it = st.begin(); it != st.end(); ++it) 
for(auto it = st.begin(); it != st.end(); ++it) 
//方法2   增強for迴圈
for(auto x : st)

注意:

  1. 雖然可以遍歷 但是不能用下標訪問資料
  2. 遍歷的時候只能讀 不能修改元素
  3. 迭代器不能像vector一樣相減直接得到下標

map

是什麼

提供對數時間的有序鍵值對結構。底層原理是紅黑樹。

有三種比較常用
map: 鍵去重 鍵有序(從小到大)
multimap: 鍵不去重 鍵有序(從小到大)
unordered_map: 鍵去重 鍵無序

怎麼用

初始化:

map<int,int> mp // 鍵從小到大
map<int,int,greater> mp // 鍵從大到小

三種遍歷和取值方法

// 迭代器
for(auto it = mp.begin(); it != mp.end(); ++it)
    cout << it -> first << it -> second << endl
// 增強for迴圈
for(auto x: mp)
    cout << x.first << x.second << endl
//架構化繫結的增強for迴圈
for(auto x: mp)
    cout << x << v << endl

常用方法:

mp[1] = 2 // 增加新的鍵值對   修改已經有的
mp.find(元素) // 查詢元素返回迭代器
mp.erase()
mp.count()
size    empty   clear 都有

注意:

  1. 如果使用中括號 訪問map時對應的鍵不存在,那麼就會新增這個鍵,設定為預設值, 所以中括號會影響鍵的存在性
  2. 不能像vector一樣相減得到下標

以上就是我認為做演算法題必須要掌握的容器知識啦QWQ

相關文章