縱有疾風(fēng)起,人生不言棄。本文篇幅較長(zhǎng),如有錯(cuò)誤請(qǐng)不吝賜教,感謝支持。
一.list容器基本概念
鏈表是一種物理存儲(chǔ)單元上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表中的指針鏈接次序?qū)崿F(xiàn)的。鏈表由一系列結(jié)點(diǎn)(鏈表中每一個(gè)元素稱為結(jié)點(diǎn))組成,結(jié)點(diǎn)可以在運(yùn)行時(shí)動(dòng)態(tài)生成。
每個(gè)結(jié)點(diǎn)包括兩個(gè)部分:
- 一個(gè)是存儲(chǔ)數(shù)據(jù)元素的數(shù)據(jù)域。
- 另一個(gè)是存儲(chǔ)下一個(gè)結(jié)點(diǎn)地址的指針域。
list容器的數(shù)據(jù)結(jié)構(gòu)是一個(gè)有頭雙向循環(huán)鏈表。鏈表其優(yōu)缺點(diǎn)為:
- 采用動(dòng)態(tài)存儲(chǔ)分配,不會(huì)造成內(nèi)存浪費(fèi)和溢出
- 鏈表執(zhí)行插入和刪除操作十分方便,修改指針即可,不需要移動(dòng)大量元素
- 鏈表靈活,但是空間和時(shí)間額外耗費(fèi)較大
list容器的迭代器:
list容器不能像vector一樣以普通指針作為迭代器,因?yàn)槠涔?jié)點(diǎn)不能保證在同一塊連續(xù)的內(nèi)存空間上。list迭代器必須有能力指向list的節(jié)點(diǎn),并有能力進(jìn)行正確的遞增、遞減、取值、成員存取操作。所謂”list正確的遞增,遞減、取值、成員取用”是指,遞增時(shí)指向下一個(gè)節(jié)點(diǎn),遞減時(shí)指向上一個(gè)節(jié)點(diǎn),取值時(shí)取的是節(jié)點(diǎn)的數(shù)據(jù)值,成員取用時(shí)取的是節(jié)點(diǎn)的成員。由于list還是一個(gè)雙向鏈表,迭代器必須能夠具備前移、后移的能力,所以list容器提供的是雙向迭代器(Bidirectional Iterators).
二.list容器的常用操作
list構(gòu)造函數(shù)
注:使用list容器時(shí),需包含頭文件#include <list>
函數(shù)原型 | 解釋 |
---|---|
list <T> lst; |
list采用模板實(shí)現(xiàn)類實(shí)現(xiàn)(顯示實(shí)例化),對(duì)象的默認(rèn)構(gòu)造形式。 |
list(beg,end); | 構(gòu)造函數(shù)將[beg, end)區(qū)間中的元素拷貝給本身。 |
list(n,elem); | 構(gòu)造函數(shù)將n個(gè)elem拷貝給本身。 |
list(const list &lst); | 拷貝構(gòu)造函數(shù)。 |
實(shí)例:構(gòu)造函數(shù)演示
#include <iostream>
using namespace std;
#include <list>//包含頭文件
void printList(const list<int>& mylist)//形參使用const,避免被修改
{//const_iterator只讀迭代器
for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
void test()
{
list<char> mylist1;//list采用模板實(shí)現(xiàn)類實(shí)現(xiàn)(顯示實(shí)例化),對(duì)象的默認(rèn)構(gòu)造形式。
list<int> mylist2(10, 6); //構(gòu)造函數(shù)將n個(gè)elem拷貝給本身。
list<int> mylist3(++mylist2.begin(), --mylist2.end());//構(gòu)造函數(shù)將[beg, end)區(qū)間中的元素拷貝給本身。
list<int> mylist4(mylist2);//拷貝構(gòu)造函數(shù)
printList(mylist2);
printList(mylist3);
printList(mylist4);
}
int main()
{
test();
return 0;
}
list迭代器獲取
獲取正向迭代器iterator:
函數(shù)原型 | 解釋 |
---|---|
iterator begin(); | 返回指向開始位置的迭代器,iterator是正向迭代器。只能使用++運(yùn)算符從左向右遍歷容器,每次沿容器向右移動(dòng)一個(gè)元素。 |
const_iterator begin(); | 返回指向開始位置并且為常量的迭代器 |
const_iterator cbegin(); | 返回指向開始并且為常量的迭代器,const_iterator 常正向迭代器。函數(shù)作用:配合auto使用。 |
iterator end(); | 返回指向末尾元素的下一個(gè)位置的迭代器 |
const_iterator end(); | 返回指向末尾元素的下一個(gè)位置并且為常量的迭代器 |
const_iterator cend(); | 返回指向末尾元素的下一個(gè)位置的并且為常量的迭代器,函數(shù)作用:配合auto使用。 |
獲取反向迭代器reverse_iterator:
函數(shù)原型 | 解釋 |
---|---|
reverse_iterator rbegin(); | 返回反向迭代器,指向末尾元素下一個(gè)位置,操作都是往相反反向,reverse_iterator 為反向迭代器。 |
const_reverse_iterator crbegin(); | 返回反向迭代器,指向末尾元素下一個(gè)位置,操作都是往相反反向,并且為常量屬性,const_reverse_iterator 常反向迭代器。 |
reverse_iterator rend(); | 返回反向迭代器,指向開頭元素的位置,操作都是往相反反向 |
const_reverse_iterator cre nd(); | 返回反向迭代器,指向開頭元素的位置,操作都是往相反反向,并且為常量屬性 |
迭代器都可以進(jìn)行++
操作。反向迭代器和正向迭代器的區(qū)別在于:
對(duì)正向迭代器進(jìn)行++
操作時(shí),迭代器會(huì)指向容器中的后一個(gè)元素;
而對(duì)反向迭代器進(jìn)行++
操作時(shí),迭代器會(huì)指向容器中的前一個(gè)元素。
#include <iostream>
using namespace std;
#include <list>//包含頭文件
void printList1(const list<int>& mylist)//形參使用const,避免被修改
{//const_iterator只讀迭代器
for (auto it = mylist.begin(); it != mylist.end(); ++it)
{
cout << *it << "|";
}
cout << endl;
}
void printList2(const list<int>& mylist)//形參使用const,避免被修改
{//const_iterator只讀迭代器
for (auto it = mylist.rbegin(); it != mylist.rend(); ++it)
{
cout << *it << "|";
}
cout << endl;
}
void test()
{
list<int> mylist;
for (int i = 0; i < 5; i++)
{
mylist.push_back(i + 1);//1 2 3 4 5
}
printList1(mylist);
printList2(mylist);
}
int main()
{
test();
return 0;
}
注意:begin函數(shù)和cbegin函數(shù)都可以返回const_iterator,那么為什么要兩個(gè)函數(shù)呢?
因?yàn)閎egin函數(shù)有重載,無(wú)法配合auto(自動(dòng)推導(dǎo)數(shù)據(jù)類型)使用,所以才多出一個(gè)cbegin函數(shù)。
list特性操作
函數(shù)原型 | 解釋 |
---|---|
size_t size() const; | 返回容器的實(shí)際大?。ㄒ咽褂玫目臻g)。 |
bool empty() const; | 判斷容器是否為空。 |
void clear(); | 清空容器。 |
void resize(size_t size); | 把容器的實(shí)際大小置為size,如果size<實(shí)際大小,會(huì)截?cái)喽喑龅牟糠郑蝗绻鹲ize>實(shí)際大小,則以默認(rèn)值0填充新位置 |
void resize(size_t size,const T &value); | 把容器的實(shí)際大小置為size,如果size<實(shí)際大小,會(huì)截?cái)喽喑龅牟糠郑蝗绻鹲ize>實(shí)際大小,就用value填充。 |
實(shí)例:特性函數(shù)演示
#include <iostream>
using namespace std;
#include <list>//包含頭文件
void printList(const list<int>& mylist)//形參使用const,避免被修改
{//const_iterator只讀迭代器
for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
void test()
{
list<int> mylist;
for (int i = 0; i < 5; i++)
{
mylist.push_back(i + 1);
}
cout << "size:" << mylist.size() << endl;//5
cout << mylist.empty() << endl;//0
if (mylist.empty())
{
cout << "空" << endl;
}
else
{
cout << "不為空" << endl;
}
mylist.resize(3);
printList(mylist);//1 2 3
mylist.resize(5);//重新指定容器的長(zhǎng)度為num,若容器變長(zhǎng),則以默認(rèn)值填充新位置。
printList(mylist);//1 2 3 0 0
mylist .resize(10, 6);//如果容器變長(zhǎng),也可以用value填充
printList(mylist);//1 2 3 0 0 6 6 6 6 6
}
int main()
{
test();
return 0;
}
list元素操作
函數(shù)原型 | 解釋 |
---|---|
T& front(); | 返回第一個(gè)元素。 |
T& back(); | 返回最后一個(gè)元素。 |
list賦值操作
作用:通過(guò)重載賦值運(yùn)算符operator=和成員函數(shù)assign(),給已存在的容器賦值,將覆蓋容器中原有的內(nèi)容。
函數(shù)原型 | 解釋 |
---|---|
list assign(beg, end); | 將[beg, end)區(qū)間中的數(shù)據(jù)拷貝賦值給本身。 |
void assign(const size_t n, const T& value); | 將n個(gè)elem拷貝賦值給本身。 |
list& operator=(const list &lst); | 重載等號(hào)操作符,把容器l賦值給當(dāng)前容器。 |
實(shí)例:賦值操作演示
#include <iostream>
using namespace std;
#include <list>//包含頭文件
#include<algorithm>
void printList(const list<int>& mylist)//形參使用const,避免被修改
{//const_iterator只讀迭代器
for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
void test()
{
list<int> mylist;
mylist.assign(10, 10);
printList(mylist);
list<int> mylist2;
mylist2.assign(mylist.begin()++, mylist.end()--);
printList(mylist2);
cout << mylist.front() << endl;
cout << mylist.back() << endl;
}
int main()
{
test();
return 0;
}
list的交換、反轉(zhuǎn)、排序、歸并操作
函數(shù)原型 | 解釋 |
---|---|
void swap(list<T> &l) ; |
把當(dāng)前容器與l交換,交換的是鏈表結(jié)點(diǎn)的地址。 |
void reverse(); | 反轉(zhuǎn)鏈表。 |
void sort(); | 對(duì)容器中的元素進(jìn)行升序排序。 |
void sort(_Pr2 _Pred); | 對(duì)容器中的元素進(jìn)行排序,排序的方法由_Pred決定(二元函數(shù))。 |
void merge(list< T> &l); | 采用歸并法合并兩個(gè)已排序的list容器,合并后的list容器仍是有序的。 |
實(shí)例:list的交換、反轉(zhuǎn)、排序、歸并操作演示
#include <iostream>
using namespace std;
#include <list>//包含頭文件
#include<algorithm>
void printList(const list<int>& mylist)//形參使用const,避免被修改
{//const_iterator只讀迭代器
for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
bool myfunc2(int v1, int v2)
{
return v1 > v2;
}
void test()
{
list<int> mylist;
for (int i = 0; i < 5; i++)
{
mylist.push_back(i + 10);//10 11 12 13 14
}
list<int> mylist2;
for (int i = 0; i < 5; i++)
{
mylist2.push_back(i);//0 1 2 3 4
}
mylist2.swap(mylist); //把當(dāng)前容器mylist2與mylist交換,交換的是鏈表結(jié)點(diǎn)的地址。
printList(mylist2);//10 11 12 13 14
mylist2.reverse();//反轉(zhuǎn)鏈表
printList(mylist2);//14 13 12 11 10
//注意:list容器不能使用sort算法,list容器有自己專屬的sort成員函數(shù)
//sort(mylist.begin(), mylist.end());
mylist2.sort(myfunc2);//借助myfunc2函數(shù)進(jìn)行比較,然后sort降序排列
printList(mylist2);//14 13 12 11 10
mylist2.sort();//mylist2鏈表使用sort函數(shù)默認(rèn)升序排列
printList(mylist2);//10 11 12 13 14
mylist.sort();//mylist鏈表使用sort函數(shù)默認(rèn)升序排列
printList(mylist);//0 1 2 3 4
mylist2.merge(mylist); //采用歸并法合并兩個(gè)已排序的list容器,合并后的list容器仍是有序的
printList(mylist2); //0 1 2 3 4 10 11 12 13 14
}
int main()
{
test();
return 0;
}
list比較操作
函數(shù)原型 | 解釋 |
---|---|
bool operator == (const vector<T> & l) const ; |
重載==運(yùn)算符,判斷當(dāng)前鏈表與l是否相等 |
bool operator != (const vector<T> & l) const ; |
重載!=運(yùn)算符,判斷當(dāng)前鏈表與l是否不相等 |
list插入和刪除操作
函數(shù)原型 | 解釋 |
---|---|
void push_front(const T& ele); | 在容器頭部插入一個(gè)數(shù)據(jù) |
void push_back(const T& ele); | 尾部插入元素ele |
void pop_front(); | 刪除容器第一個(gè)數(shù)據(jù) |
void pop_back(); | 刪除最后一個(gè)元素 |
iterator insert(iterator pos, const T& value); | 在指定位置插入一個(gè)元素,返回指向插入元素的迭代器。 |
iterator insert(pos,n,elem); | 在pos位置插入n個(gè)elem數(shù)據(jù),返回指向第一個(gè)插入元素的迭代器。 |
iterator insert(iterator pos, iterator first, iterator last); | 在指定位置插入一個(gè)區(qū)間的元素,返回指向第一個(gè)插入元素的迭代器。 |
iterator erase(iterator pos); | 刪除指定位置的元素,返回下一個(gè)有效的迭代器。 |
iterator erase(iterator first, iterator last); | 刪除指定區(qū)間的元素,返回下一個(gè)有效的迭代器。 |
splice(iterator pos, const vector< T> & l); | 把另一個(gè)鏈表連接到當(dāng)前鏈表pos位置處。 |
splice(iterator pos, const vector< T> & l, iterator first, iterator last); | 把另一個(gè)鏈表指定的區(qū)間連接到當(dāng)前鏈表pos位置處。 |
splice(iterator pos, const vector< T> & l, iterator first); | 把另一個(gè)鏈表從first開始的結(jié)點(diǎn)連接到當(dāng)前鏈表pos位置處。 |
void remove(const T& value); | 刪除鏈表中所有值等于value的元素。 |
void remove_if(_Pr1 _Pred); | 刪除鏈表中滿足條件的元素,參數(shù)_Pred是一元函數(shù)。 |
void unique(); | 刪除鏈表中相鄰的重復(fù)元素,只保留一個(gè)。 |
list插入和刪除操作演示:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-623802.html
#include <iostream>
using namespace std;
#include <vector>
#include <list>//包含頭文件
void printList(const list<int>& mylist)//形參使用const,避免被修改
{//const_iterator只讀迭代器
for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
bool myfunc(int val)
{
return val > 300;
}
void test()
{
list<int> mylist;
mylist.push_back(10);//在容器尾部插入一個(gè)數(shù)據(jù)
mylist.push_back(20);
mylist.push_back(30);
mylist.push_back(40);
mylist.push_back(50);
mylist.push_front(100);//在容器頭部插入一個(gè)數(shù)據(jù)
mylist.push_front(200);
mylist.push_front(300);
mylist.push_front(400);
printList(mylist);//400 300 200 100 10 20 30 40 50
cout << "------------------" << endl;
list<int>::const_iterator it = mylist.insert(mylist.begin(), 2, 0);//在pos位置插入n個(gè)elem數(shù)據(jù)
cout << *it << endl;//返回指向第一個(gè)插入元素的迭代器。
cout << "------------------" << endl;
vector<int> v;
v.push_back(1000);
v.push_back(2000);
v.push_back(3000);
mylist.insert(mylist.begin(), v.begin(), v.end()); //在指定位置插入一個(gè)區(qū)間的元素,返回指向第一個(gè)插入元素的迭代器
printList(mylist);//1000 2000 3000 400 300 200 100 10 20 30 40 50
cout << "------------------" << endl;
mylist.erase(mylist.begin());//刪除第一個(gè)元素
printList(mylist); //2000 3000 400 300 200 100 10 20 30 40 50
cout << "------------------" << endl;
list<int> mylist2(6,6);
mylist.splice(mylist.end(),mylist2);//將mylist2鏈接到mylist后
printList(mylist);//2000 3000 400 300 200 100 10 20 30 40 50 6 6 6 6 6 6
cout << "------------------" << endl;
mylist.remove(300); //刪除鏈表中所有值等于300的元素
printList(mylist);//2000 3000 400 200 100 10 20 30 40 50 6 6 6 6 6 6
cout << "------------------" << endl;
mylist.remove_if(myfunc);//刪除鏈表中所有值大于300的元素
printList(mylist);// 200 100 10 20 30 40 50 6 6 6 6 6 6
cout << "------------------" << endl;
}
int main()
{
test();
return 0;
}
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-623802.html
到了這里,關(guān)于C++STL——list容器及其常用操作(詳解)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!