NDK14_C++基礎: C++容器

NDK開發彙總

一 容器

容器,就是用來存放東西的盒子。

常用的數據結構包括:數組array, 鏈表list, 樹tree, 棧stack, 隊列queue, 散列表hash table, 集合set、映射表map 等等。容器便是容納這些數據結構的。這些數據結構分爲序列式與關聯式兩種,容器也分爲序列式容器和關聯式容器。

STL 標準模板庫,核心包括容器、算法、迭代器。

二 序列式容器/順序容器

元素排列次序與元素無關,由元素添加到容器的順序決定

容器 說明
vector 支持快速隨機訪問
list 支持快速插入、刪除
deque 雙端隊列 允許兩端都可以進行入隊和出隊操作的隊列
stack 後進先出LIFO(Last In First Out)堆棧
queue 先進先出FIFO(First Input First Output)隊列
priority_queue 有優先級管理的queue

向量(vector)

連續存儲的元素

列表 (list)

由節點組成的雙向鏈表,每個結點包含着一個元素

雙端隊列(deque)

連續存儲的指向不同元素的指針所組成的數組

以上三種容器操作基本一樣

基本操作:

#include <vector>
using namespace std;

vector<int> vec_1;
//1個元素
vector<int> vec_2(1);
//6個值爲 1 的元素
vector<int> vec_3(6,1);
//使用容器初始化
vector<int> vec_4(vec_3);

//通過下標操作元素
int i = vec_3[1];
int j = vec_3.at(1);
//首尾元素
vec_3.front()
vec_3.back()

//插入元素 
//vector不支持 push_front list,deque可以
vec_1.push_back(1);
//刪除元素 vector不支持 pop_front
vec_1.pop_back();

//釋放
//可以單個清除,也可以清除一段區間裏的元素
vec_3.erase(vec_3.begin(),vec_3.end())
//清理容器 即erase所有
vec_3.clear(); 

//容量大小
vec_3.capacity();
//在容器中,其內存佔用的空間是隻增不減的,
//clear釋放元素,卻不能減小vector佔用的內存
//所以可以對vector 收縮到合適的大小 
vector< int >().swap(vec_3);  

//在vec是全局變量時候
//建立臨時vector temp對象,swap調用之後對象vec佔用的空間就等於默認構造的對象的大小
//temp就具有vec的大小,而temp隨即就會被析構,從而其佔用的空間也被釋放。

迭代器

//獲得指向首元素的迭代器  模板類,不是指針,當做指針來使用
vector<int>::iterator it = vec.begin();
//遍歷元素
for (; it < vec.end(); it++)
{
	cout << *it << endl;
}
//begin和end   分別獲得 指向容器第一個元素和最後一個元素下一個位置的迭代器
//rbegin和rend 分別獲得 指向容器最後一個元素和第一個元素前一個位置的迭代器

//注意循環中操作元素對迭代器的影響
vector<int>::iterator it = vec.begin();
for (; it < vec.end(); )
{
    //刪除值爲2的元素 
	if (*it == 2) {
		vec.erase(it);
	}
	else {
		it++;
	}
}

棧(stack)

後進先出的值的排列

stack<int> s;
//入棧
s.push(1);
s.push(2);
//彈棧
s.pop();
//棧頂
cout << s.top() << endl;

隊列(queue)

先進先出的值的排列

queue<int> q;
q.push(1);
q.push(2);
//移除最後一個
q.pop();
//獲得第一個
q.front();
//最後一個元素
cout << q.back() << endl;

優先隊列(priority_queue )

元素的次序是由所存儲的數據的某個值排列的一種隊列

//最大的在隊首
priority_queue<int>;
//在vector之上實現的
priority_queue<int, vector<int>, less<int> >; 
//vector 承載底層數據結構堆的容器
//less 表示數字大的優先級高,而 greater 表示數字小的優先級高
//less  	 讓優先隊列總是把最大的元素放在隊首
//greater    讓優先隊列總是把最小的元素放在隊首

//less和greater都是一個模板結構體 也可以自定義

class Student {
public:
	int grade;
	Student(int grade):grade(grade) {
	}
};
struct cmp {
	bool operator ()(Student* s1, Student* s2) {
        // > 從小到大
        // < 從大到小 
		return s1->grade > s2->grade;
	}
	bool operator ()(Student s1, Student s2) {
		return s1.grade > s2.grade;
	}
};
priority_queue<Student*, vector<Student*>, cmp > q1;
q1.push(new Student(2));
q1.push(new Student(1));
q1.push(new Student(3));
cout << q1.top()->grade << endl;

三 關聯式容器

關聯容器和大部分順序容器操作一致

關聯容器中的元素是按關鍵字來保存和訪問的 支持高效的關鍵字查找與訪問

集合(set)

由節點組成的紅黑樹,每個節點都包含着一個元素,元素不可重複

set<string> a;  
set<string> a1={"fengxin","666"};
a.insert("fengxin");  // 插入一個元素
a.erase("123");	//刪除

鍵值對(map)

由{鍵,值}對組成的集合

map<int, string> m;
map<int, string> m1 = { { 1,"Lance" },{ 2,"David" } };
//插入元素
m1.insert({ 3,"Jett" });
//pair=鍵值對
pair<int, string> p(4, "dongnao");
m1.insert(p);
//insetrt 返回 map<int, string>::iterator : bool 鍵值對
//如果 插入已經存在的 key,則會插入失敗   
//multimap:允許重複key
//使用m1[3] = "xx" 能夠覆蓋


//通過【key】操作元素
m1[5] = "yihan";
cout << m1[5].c_str() << endl; 
//通過key查找元素
map<int, string>::iterator it = m1.find(3);
cout << (*it).second.c_str()<< endl;
// 刪除 
m1.erase(5);
//遍歷
for (it = m1.begin(); it != m1.end(); it++)
{
	pair<int, string> item = *it;
	cout << item.first << ":" << item.second.c_str() << endl;
}

//其他map================================

unordered_map c++11取代hash_map(哈希表實現,無序)

哈希表實現查找速度會比RB樹實現快,但rb整體更節省內存

需要無序容器,高頻快速查找刪除,數據量較大用unordered_map;

需要有序容器,查找刪除頻率穩定,在意內存時用map。

紅黑樹

二叉樹

在這裏插入圖片描述

二分查找:

查找 2 :

1、查看根節點爲10

2、由於2小於10,因此查找左孩子,節點爲5

3、同時2小與5,繼續查看左邊,找到2節點

查找最大次數爲樹的高度

如果有下面的二叉查找樹,插入7、6、5…

這樣幾乎成爲線性,查找性能大幅下降
在這裏插入圖片描述

爲了解決這種不平衡,紅黑樹就誕生了。

https://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91

紅黑樹(Red Black Tree)又稱爲 RB樹,是一種相對平衡二叉樹 。

1.節點是紅色或黑色。

2.根節點是黑色。

3.每個葉子節點(空節點)都是黑色的。

4 每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)

5.從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點。
在這裏插入圖片描述

  1. 插入新節點總是紅色節點
  2. 如果插入節點的父節點是黑色, 能維持性質
  3. 如果插入節點的父節點是紅色, 破壞了性質。插入算法就是通過重新着色或旋轉, 來維持性質

插入 7 後,破壞了規則,那麼需要根據不同的狀況進行不同的策略使其平衡並符合規則。

7的父節點8 與叔父節點 12 都是紅色,則我們可以將8、12兩個重繪爲黑色並重繪祖父節點9爲紅色。

這裏9是根節點,爲了滿足規則1,又把它重繪爲黑色 .

經過調整:

現在滿足5個規則,因此7插入完成。

接下來插入 6

現在新節點 6 是 父節點 7的左節點,而6的叔父節點 缺少,父節點 7 又是祖父節點8的左子節點 ,

這種情形下,我們進行鍼對6節點的祖父節點8的一次右旋轉

右旋轉:

順時針旋轉紅黑樹的兩個節點,使得父節點被自己的左孩子取代,而自己成爲自己的右孩子。

左旋轉則倒過來

再切換 7 和 8 的顏色

在這裏插入圖片描述

再插入5,5和6都是紅色,將 父節點 6 和叔父節點 8 繪爲黑色,祖父7設爲紅色,最終

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章