C++順序容器(vector、deque、list)的使用詳解
一:STL(Standard Template Library),即標(biāo)準(zhǔn)模板庫,是一個高效的C++程序庫
1.從實(shí)現(xiàn)層次看,整個STL是以一種類型參數(shù)化(type parameterized)的方式實(shí)現(xiàn)的,基于模板(template)。
2.從邏輯層次來看,在STL中體現(xiàn)了泛型化程序設(shè)計的思想(generic programming),在這種思想里,大部分基本算法被抽象,被泛化,獨(dú)立于與之對應(yīng)的數(shù)據(jù)結(jié)構(gòu),用于以相同或相近的方式處理各種不同情形。
二:STL組件
1.Container(容器) 各種基本數(shù)據(jù)結(jié)構(gòu)
2.Algorithm(算法) 各種基本算法如 sort search等
3.Iterator(迭代器) 連接containers 和 algorithms
4.了解:
- Adapter(適配器) 可改變containers或function object接口的一種組件
- Function object(函數(shù)對象) *
- Allocator(分配器)*
三:容器
1.容器類是容納、包含一組元素或元素集合的對象
2.七種基本容器:
向量(vector)、雙端隊列(deque)、鏈表(list)、集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)
四:類型成員
1.循環(huán)子操作:
- begin():指向第一個元素
- end():指向最后一個元素的后一個位置
- rbegin():指向逆序的第一個元素
- rend():指向逆序的最后一個元素的后一個位置
2.訪問元素操作
- front():訪問第一個元素
- back():訪問最后一個元素
- [ ]:無測試的下標(biāo)訪問(不用于 list)
- at():有測試的下標(biāo)訪問(只用于 vector 和 deque)
3.堆棧和隊列操作
- push_back():將新元素加入到尾部
- pop_back():移出最后一個元素
- push_front():將新元素加入頭部(只用于 list 和 deque)
- pop_front():移出第一個元素(只用于 list 和 deque)
4.表操作
- insert(p,x):將元素x加入到 p 之前
- erase(p):刪除p處的元素
- clear():清除所有的元素
五:迭代器
迭代器是面向?qū)ο蟀姹镜闹羔槪鼈兲峁┝嗽L問容器、序列中每個元素的方法
六:順序容器
順序容器的接口
1.插入方法:push_front(),push_back(),insert(),運(yùn)算符“=”
2.刪除方法:pop() ,erase(),clear()
3.迭代訪問方法:使用迭代器
4.其他順序容器訪問方法(不修改訪問方法):front(),back(),下標(biāo)[ ]運(yùn)算符
七:順序容器--向量(vector)
a.向量屬于順序容器,用于容納不定長線性序列(即線性群體),提供對序列的快速隨機(jī)訪問(也稱直接訪問)
b.數(shù)據(jù)結(jié)構(gòu)很像一個數(shù)組,所以與其他容器相比,vector 能非常方便和高效訪問單個元素,支持隨機(jī)訪問迭代子
c.向量是動態(tài)結(jié)構(gòu),它的大小不固定,可以在程序運(yùn)行時增加或減少
d.與數(shù)組不同,向量的內(nèi)存用盡時,向量自動分配更大的連續(xù)內(nèi)存區(qū),將原先的元素復(fù)制到新的內(nèi)存區(qū),并釋放舊的內(nèi)存區(qū)。這是向量類的優(yōu)點(diǎn)。
頭文件:#include <vector>
例子:
1.push_back尾部添加
#include<iostream> using namespace std; #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<int> v; //迭代器 vector<int>::iterator it; it = v.begin(); //開始位置 //在尾部添加 v.push_back(1); v.push_back(12); //迭代器指針 遍歷向量容器 for(it = v.begin();it<v.end();it++) { cout<<" "<<*it; //取值 } // 1 12 cout<<endl; }
2.insert按照位置插入
#include<iostream> using namespace std; #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<int> v; //迭代器 vector<int>::iterator it; it = v.begin(); //開始位置 //在尾部添加 v.push_back(1); v.push_back(12); //按照位置插入 v.insert(v.begin(),100); for(it = v.begin();it<v.end();it++) { cout<<" "<<*it; //取值 } // 100 1 12 cout<<endl; }
3.獲取id(成員屬性)
CStaff.h
#ifndef CSTAFF_H #define CSTAFF_H #define ADMIN 1 #define MANAGER 2 #define WAITER 3 #include<string> #include<iostream> using namespace std; class Staff { public: Staff(); Staff(int id,string name,string pwd,int prole); ~Staff(); int getId(); string getName(); string getPwd(); int getRole(); private: int ID; string name; string pwd; int role; }; #endif
CStaff.cpp
#include"CStaff.h" #include<iostream> using namespace std; Staff::Staff() { } Staff::Staff(int id,string name,string pwd,int prole) { this->ID = id; this->name = name; this->pwd = pwd; this->role = prole; } int Staff::getId() { return this->ID; } string Staff::getName() { return this->name; } string Staff::getPwd() { return this->pwd; } int Staff::getRole() { return this->role; } Staff::~Staff() { }
main.cpp
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); staffV.insert(staffV.begin(),new Staff(1003,"sam","1234",MANAGER)); for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } // id:1003 // id:1001 // id:1002 }
4.按照位置插入insert --- 需要迭代器指針it++偏移
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //開始位置 it++; staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } //id:1001 //id:1003 //id:1002 }
5.尾部刪除pop_back
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //開始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); //尾部刪除 staffV.pop_back(); for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } // id:1001 // id:1003 }
6. erase按照位置刪除
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //開始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); //尾部刪除 staffV.pop_back(); it = staffV.begin(); //開始位置 staffV.erase(it);//刪除第一個 for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } //id:1003 }
7.erase按照位置刪除(迭代器指針偏移it++)
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //開始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); //尾部刪除 staffV.pop_back(); it = staffV.begin(); //開始位置 it++; staffV.erase(it);//刪除第二個 for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } //id:1001 }
8.size計數(shù)
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //開始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); cout<<"員工數(shù)量:"<<staffV.size()<<endl; for(it=staffV.begin();it<staffV.end();it++) { cout<<"id:"<<(*it)->getId()<<endl; } //員工數(shù)量:3 //id:1001 //id:1003 //id:1002 }
9.容器訪問四種
1.迭代器指針 2.at訪問方式 3.[ ]中括號訪問方式 4.C++新增auto訪問方式
at訪問方式:
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //開始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); cout<<"員工數(shù)量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指針遍歷 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下標(biāo)法 { cout<<"id:"<<staffV.at(i)->getId()<<endl; } //員工數(shù)量:3 //id:1001 //id:1003 //id:1002 }
[ ]中括號訪問方式
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //開始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); cout<<"員工數(shù)量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指針遍歷 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下標(biāo)法 { //cout<<"id:"<<staffV.at(i)->getId()<<endl; cout<<"id:"<<staffV[i]->getId()<<endl; } //員工數(shù)量:3 //id:1001 //id:1003 //id:1002 }
10.clear清空
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> void demo_vector(); int main() { demo_vector(); return 0; } void demo_vector() { vector<Staff *> staffV; vector<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //開始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); cout<<"員工數(shù)量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指針遍歷 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下標(biāo)法 { //cout<<"id:"<<staffV.at(i)->getId()<<endl; cout<<"id:"<<staffV[i]->getId()<<endl; } staffV.clear(); cout<<"員工數(shù)量:"<<staffV.size()<<endl; //員工數(shù)量:3 //id:1001 //id:1003 //id:1002 //員工數(shù)量:0 }
八:順序容器--雙端隊列--deque
a.雙端隊列是一種放松了訪問權(quán)限的隊列。元素可以從隊列的兩端入隊和出隊,也支持通過下標(biāo)操作符“[]”進(jìn)行直接訪問。
b.與向量的對比 功能上:和向量沒有多少區(qū)別,
性能上:在雙端隊列起點(diǎn)上的插入和刪除操作快
頭文件:#include <deque>
1.push_front頭部插入
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> void demo_deque(); int main() { demo_deque(); return 0; } void demo_deque() { deque<Staff *> staffV; deque<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); it = staffV.begin(); //開始位置 it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); //頭部插入 staffV.push_front(new Staff(1004,"lilei","1234",MANAGER)); cout<<"員工數(shù)量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指針遍歷 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下標(biāo)法 { //cout<<"id:"<<staffV.at(i)->getId()<<endl; cout<<"id:"<<staffV[i]->getId()<<endl; } // staffV.clear(); // cout<<"員工數(shù)量:"<<staffV.size()<<endl; //員工數(shù)量:4 //id:1004 //id:1001 //id:1003 //id:1002 }
2.pop_front頭部刪除
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> void demo_deque(); int main() { demo_deque(); return 0; } void demo_deque() { deque<Staff *> staffV; deque<Staff *>::iterator it; staffV.push_back(new Staff(1001,"admin","1234",ADMIN)); staffV.push_back(new Staff(1002,"lily","1234",ADMIN)); //頭部插入 staffV.push_front(new Staff(1004,"lilei","1234",MANAGER)); it = staffV.begin(); //開始位置 //it++; //按照位置插入 staffV.insert(it,new Staff(1003,"sam","1234",MANAGER)); // 3 4 1 2 staffV.pop_front(); //頭部刪除 cout<<"員工數(shù)量:"<<staffV.size()<<endl; /* for(it=staffV.begin();it<staffV.end();it++)//迭代器指針遍歷 { cout<<"id:"<<(*it)->getId()<<endl; }*/ for(int i =0;i<staffV.size();i++) //下標(biāo)法 { //cout<<"id:"<<staffV.at(i)->getId()<<endl; cout<<"id:"<<staffV[i]->getId()<<endl; } // staffV.clear(); // cout<<"員工數(shù)量:"<<staffV.size()<<endl; //員工數(shù)量:3 //id:1004 //id:1001 //id:1002 }
九:順序容器 --列表--list
a.鏈表主要用于存放雙向鏈表,可以從任意一端開始遍歷。鏈表還提供了拼接(splice)操作,將一個序列中的元素從插入到另一個序列中。
b.對比:元素的插入和刪除操作對 list 而言尤為高效
與 vector 和 deque 相比,對元素的下標(biāo)訪問操作的低效是不能容忍的,因此 list 不提供這類操作。
頭文件:#include <list>
list只支持迭代器法
for(it=staffList.begin();it!=staffList.end();it++)//迭代器指針遍歷
1.只支持迭代器指針遍歷
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> #include<list> void demo_list(); int main() { demo_list(); return 0; } void demo_list() { list<Staff *> staffList; list<Staff *>::iterator it; staffList.push_back(new Staff(1001,"admin","1234",ADMIN)); staffList.push_back(new Staff(1002,"lily","1234",ADMIN)); //頭部插入 staffList.push_front(new Staff(1004,"lilei","1234",MANAGER)); it = staffList.begin(); //開始位置 //it++; //按照位置插入 staffList.insert(it,new Staff(1003,"sam","1234",MANAGER)); // 3 4 1 2 staffList.pop_front(); //頭部刪除 cout<<"員工數(shù)量:"<<staffList.size()<<endl; for(it=staffList.begin();it!=staffList.end();it++)//迭代器指針遍歷 { cout<<"id:"<<(*it)->getId()<<endl; } //員工數(shù)量:3 //id:1004 //id:1001 //id:1002 }
2.把一個鏈表(單個元素)里的東西放到另外一個鏈表中--splice
#include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> #include<list> void demo_list(); int main() { demo_list(); return 0; } void demo_list() { list<Staff *> staffList; list<Staff *> list2;//再一個鏈表 list2.push_back(new Staff(1006,"mei","1234",ADMIN));//有一個1006 staffList.push_back(new Staff(1001,"admin","1234",ADMIN)); staffList.push_back(new Staff(1002,"lily","1234",ADMIN)); //頭部插入 staffList.push_front(new Staff(1004,"lilei","1234",MANAGER)); list<Staff *>::iterator it; it = staffList.begin(); //開始位置 it++; //在第二個位置插入1006 //splice move element from list to list staffList.splice(it,list2); cout<<"員工數(shù)量:"<<staffList.size()<<endl; for(it=staffList.begin();it!=staffList.end();it++)//迭代器指針遍歷 { cout<<"id:"<<(*it)->getId()<<endl; } cout<<"員工數(shù)量:"<<list2.size()<<endl; //員工數(shù)量:4 //id:1004 //id:1006 //id:1001 //id:1002 //員工數(shù)量:0 } #include<iostream> using namespace std; #include"CStaff.h" #include<vector> #include<deque> #include<list> void demo_list(); int main() { demo_list(); return 0; } void demo_list() { list<Staff *> staffList; list<Staff *>list2;//再一鏈表 list2.push_back(new Staff(1006,"mei","1234",ADMIN)); //有1006 1007 list2.push_back(new Staff(1007,"didi","1234",ADMIN)); staffList.push_back(new Staff(1001,"admin","1234",ADMIN)); staffList.push_back(new Staff(1002,"lily","1234",ADMIN)); //頭部插入 staffList.push_front(new Staff(1004,"lilei","1234",MANAGER)); list<Staff *>::iterator it; it = staffList.begin(); //開始位置 it++; //在第二個位置插入1006 1007 //splice move element from list to list staffList.splice(it,list2); cout<<"員工數(shù)量:"<<staffList.size()<<endl; for(it=staffList.begin();it!=staffList.end();it++)//迭代器指針遍歷 { cout<<"id:"<<(*it)->getId()<<endl; } cout<<"員工數(shù)量:"<<list2.size()<<endl; //員工數(shù)量:5 //id:1004 //id:1006 //id:1007 //id:1001 //id:1002 //員工數(shù)量:0 }
到此這篇關(guān)于C++順序容器(vector、deque、list)的使用詳解的文章就介紹到這了,更多相關(guān)C++ 順序容器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言中如何實(shí)現(xiàn)單鏈表刪除指定結(jié)點(diǎn)
這篇文章主要介紹了C語言中如何實(shí)現(xiàn)單鏈表刪除指定結(jié)點(diǎn),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07C語言中字符串和數(shù)字的相互轉(zhuǎn)換實(shí)現(xiàn)代碼
以下是對C語言中字符串和數(shù)字的相互轉(zhuǎn)換實(shí)現(xiàn)代碼進(jìn)行了分析介紹,需要的朋友可以參考下2013-07-07C++ vector容器實(shí)現(xiàn)貪吃蛇小游戲
這篇文章主要為大家詳細(xì)介紹了C++ vector容器實(shí)現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-02-02二維指針動態(tài)分配內(nèi)存連續(xù)問題深入分析
當(dāng)我們定義一個二維指針時,如果需要存儲相應(yīng)的數(shù)據(jù),就需要我們動態(tài)的分配內(nèi)存,這時,有一點(diǎn)是需要注意的,分配內(nèi)存的方法不同,內(nèi)存的連續(xù)性也是不相同的2013-07-07一道超經(jīng)典的C++結(jié)構(gòu)體的題目
以下小編就為大家介紹一道超經(jīng)典的關(guān)于C++結(jié)構(gòu)體的題目。需要的朋友可以過來參考下2013-09-09