list雙向連結串列容器
list容器實現了雙向連結串列的資料結構,資料元素是通過連結串列指標串聯成邏輯意義上的線性表,因此對連結串列的任一位置的元素進行插入、刪除和查詢都是極快的。
list每個節點有三個域:前驅元素指標域、資料域、後繼元素指標域,list的頭結點的前驅元素指標域儲存的是連結串列中尾元素的首指標,而list的尾節點的後繼元素指標域則儲存了頭結點的首指標,這樣構成了一個雙向迴圈連結串列。
由於list物件節點並不要求在一段連續的記憶體中,所以對於迭代器,只能通過“++"和”--“的操作將迭代器移動到後繼/前驅節點元素處。而不能對迭代器進行+n或者-n操作,這點是與vector等不同的地方。
使用list需要包含標頭檔案:#include<list>
建立list物件
(1)建立空連結串列
list<int> l;
(2)建立具有n個元素的連結串列
list<int> l(10);
(3)建立具有初值的n個元素的連結串列
list<int> l(10,5);
元素插入和遍歷
使用push_back()方法往尾部插入新元素,push_front()方法往首部插入新元素,insert()方法往迭代器位置插入新元素,連結串列自動擴張。
注意,迭代器只能採用"++"或者“--”操作,不能進行+n或者-n操作,因為各節點之間在物理上並不是順序儲存的,並且指向連結串列元素的迭代器之間也沒有大小關係。
輸出結果:#include<list> #include<iostream> using namespace std; int main() { list<int> l; l.push_back(2); l.push_back(3); l.push_back(5); l.push_front(1); list<int>::iterator it = l.begin(); it++; l.insert(++it,20); //迭代器之間沒有大小關係,所以使用不等號 for(it=l.begin();it!=l.end();it++) { cout<<*it<<" "; } return 0; }
1 2 20 3 5
反向遍歷
採用反向迭代器reverse_iterator對連結串列進行反向遍歷,使用方法和deque反向遍歷的方法一樣
輸出結果:9 8 7 6 5 4 3 2 1#include<list> #include<iostream> using namespace std; int main() { list<int> l; for(int i=1;i<10;i++) l.push_back(i); list<int>::reverse_iterator rit; for(rit=l.rbegin();rit!=l.rend();rit++) { cout<<*rit<<" "; } return 0; }
元素刪除
(1)使用remove()方法刪除連結串列中的一個值,所有元素值等於該值的元素都會被刪除。
(2)使用pop_front()方法刪除連結串列首元素,使用pop_back()方法刪除連結串列尾元素。
(3)使用erase()方法刪除迭代器位置上的元素
(4)使用clear()方法清空連結串列
#include<list>
#include<iostream>
using namespace std;
void Show(list<int> &l)
{
list<int>::iterator it;
for(it=l.begin();it!=l.end();it++)
cout<<*it<<" ";
cout<<endl;
}
int main()
{
list<int> l;
list<int>::iterator it;
for(int i=1;i<10;i++)
l.push_back(i);
Show(l);
l.pop_back();
l.pop_front();
Show(l);
it = l.begin();
l.insert(++it,5);
l.insert(++it,5);
Show(l);
l.remove(5);
Show(l);
l.erase(it);
Show(l);
l.clear();
cout<<l.size()<<endl;
return 0;
}
輸出結果:
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8
2 5 3 5 4 5 6 7 8
2 3 4 6 7 8
2 3 6 7 8
0
元素查詢
採用find()查詢演算法可以在連結串列中查詢元素,如果找到該元素,則返回的是該元素迭代器的位置,如果找不到則返回end()迭代器的位置。
find()演算法需要宣告標頭檔案包含:#include<algorithm>
#include<list>
#include<algorithm>
#include<iostream>
using namespace std;
void Show(list<int> &l)
{
list<int>::iterator it;
for(it=l.begin();it!=l.end();it++)
cout<<*it<<" ";
cout<<endl;
}
int main()
{
list<int> l;
list<int>::iterator it;
for(int i=1;i<10;i++)
{
l.push_back(i);
}
Show(l);
it = find(l.begin(),l.end(),5);
if(it!=l.end())
cout<<"find 5"<<endl;
else
cout<<"not find 5"<<endl;
it = find(l.begin(),l.end(),10);
if(it!=l.end())
cout<<"find 10"<<endl;
else
cout<<"not find 10"<<endl;
return 0;
}
輸出結果:
1 2 3 4 5 6 7 8 9
find 5
not find 10
元素排序
使用sort()方法對元素進行排序,預設情況先,sort函式中沒有引數,為升序排序,我們可以通過建構函式comp作為sort方法的引數,實現升序排序。
#include<list>
#include<iostream>
using namespace std;
void Show(list<int> &l)
{
list<int>::iterator it;
for(it=l.begin();it!=l.end();it++)
cout<<*it<<" ";
cout<<endl;
}
bool comp(int a,int b)
{
return a>b;
}
int main()
{
list<int> l;
list<int>::iterator it;
for(int i=10;i>0;i--)
{
l.push_back(i);
}
Show(l);
//升序排序
l.sort();
Show(l);
//降序排序
l.sort(comp);
Show(l);
return 0;
}
剔除重複的元素
使用unique()方法可以提出連續重複元素,只保留一個。
注意remove()方法和unique方法的區別,remove是刪除list中所有元素為該值得節點,而unique是對於連續重複節點,只保留一個。
#include<list>
#include<iostream>
using namespace std;
void Show(list<int> &l)
{
list<int>::iterator it;
for(it=l.begin();it!=l.end();it++)
cout<<*it<<" ";
cout<<endl;
}
int main()
{
list<int> l;
list<int>::iterator it;
for(int i=5;i>0;i--)
{
l.push_back(i);
}
Show(l);
l.push_front(1);
l.push_front(1);
l.push_front(1);
Show(l);
l.unique();
Show(l);
return 0;
}
輸出結果:
5 4 3 2 1
1 1 1 5 4 3 2 1
1 5 4 3 2 1