C++各個容器比較(vector,deque,list,set,map,queue,stack)


1、vector(連續的空間存儲,可以使用[ ]操作符)可以快速的訪問隨機的元素,快速的在末尾插入元素,但是在序列中間隨機的插入、刪除元素要慢。而且,如果一開始分配的空間不夠時,有一個重新分配更大空間的過程。

 
2、deque(小片的連續,小片間用鏈表相連,實際上內部有一個map的指針,因為知道類型,所以還是可以使用[ ],只是速度沒有vector快)快速的訪問隨機的元素,快速的在開始和末尾 插入元素。隨機的 插入刪除元素要慢,空間的從新分配空間后,原有的元素不需要備份。對deque的排序操作,可將deque先復制到vector,排序后再復制回deque
 
3、list(每個元素間用鏈表相連)訪問隨機元素沒有vector快,隨機地 插入元素要比vector快,對每個元素分配空間,不存在空間不夠,重新分配的情況。
 
4、set內部元素唯一,用一棵平衡樹結構來存儲,因此遍歷的時候就排序了,查找也比較快
 
5、map一對一地映射結合,key沒有重復
 
6、 queue的聲明 queue<int,deque<int> > s是受限的隊列,存儲的空間由第二個參數的容器確定,第一個參數在沒有第二個參數的情況下,決定存儲空間類型,第二個參數存在的情況下,第一個類型參數無效。默認情況下是deque類型的,因此可以如此聲明 queue<int> s1,這樣,聲明的隊列存儲空間就是默認的deque。另外, queue第二個參數可以選擇的容器類型包括deque、list,其余的如果聲明,操作受限。
 
7、stack的默認存儲空間也是deque,其他的聲明和 queue差不多,可以使用的容器類型包括deque、vector、list,stack是先進后出棧。
 

 

1、stack
stack 模板類的定義在<stack>頭文件中。
stack 模板類需要兩個模板參數,一個是元素類型,一個容器類型,但只有元素類型是必要
的,在不指定容器類型時,默認的容器類型為deque。
定義stack 對象的示例代碼如下:
stack<int> s1;
stack<string> s2;
stack 的基本操作有:
入棧,如例:s.push(x);
出棧,如例:s.pop();注意,出棧操作只是刪除棧頂元素,並不返回該元素。
訪問棧頂,如例:s.top()
判斷棧空,如例:s.empty(),當棧空時,返回true。
訪問棧中的元素個數,如例:s.size()。

 

2、queue
queue 模板類的定義在<queue>頭文件中。
與stack 模板類很相似,queue 模板類也需要兩個模板參數,一個是元素類型,一個容器類
型,元素類型是必要的,容器類型是可選的,默認為deque 類型。
定義queue 對象的示例代碼如下:
queue<int> q1;
queue<double> q2;

queue 的基本操作有:
入隊,如例:q.push(x); 將x 接到隊列的末端。
出隊,如例:q.pop(); 彈出隊列的第一個元素,注意,並不會返回被彈出元素的值。
訪問隊首元素,如例:q.front(),即最早被壓入隊列的元素。
訪問隊尾元素,如例:q.back(),即最后被壓入隊列的元素。
判斷隊列空,如例:q.empty(),當隊列空時,返回true。
訪問隊列中的元素個數,如例:q.size()

#include <cstdlib>
#include <iostream>
#include <queue>

using namespace std;

int main()
{
 
   int e,n,m;
 
   queue<int> q1;
 
   for(int i=0;i<10;i++)
 
      q1.push(i);
 
   if(!q1.empty())
 
   cout<<"dui lie  bu kong\n";
 
   n=q1.size();
 
   cout<<n<<endl;
 
   m=q1.back();
 
   cout<<m<<endl;
 
   for(int j=0;j<n;j++)
 
   {
 
      e=q1.front();
 
      cout<<e<<" ";
 
      q1.pop();
 
   }
 
   cout<<endl;
 
   if(q1.empty())
 
   cout<<"dui lie  bu kong\n";
 
   system("PAUSE");
 
   return 0;
}

3、priority_queue
在<queue>頭文件中,還定義了另一個非常有用的模板類priority_queue(優先隊列)。優先隊
列與隊列的差別在於優先隊列不是按照入隊的順序出隊,而是按照隊列中元素的優先權順序
出隊(默認為大者優先,也可以通過指定算子來指定自己的優先順序)。
priority_queue 模板類有三個模板參數,第一個是元素類型,第二個容器類型,第三個是比
較算子。其中后兩個都可以省略,默認容器為vector,默認算子為less,即小的往前排,大
的往后排(出隊時序列尾的元素出隊)。
定義priority_queue 對象的示例代碼如下:
priority_queue<int> q1;
priority_queue< pair<int, int> > q2; // 注意在兩個尖括號之間一定要留空格。
priority_queue<int, vector<int>, greater<int> > q3; // 定義小的先出隊
priority_queue 的基本操作queue 相同。
初學者在使用priority_queue 時,最困難的可能就是如何定義比較算子了。
如果是基本數據類型,或已定義了比較運算符的類,可以直接用STL 的less 算子和greater
算子——默認為使用less 算子,即小的往前排,大的先出隊。
如果要定義自己的比較算子,方法有多種,這里介紹其中的一種:重載比較運算符。優先隊
列試圖將兩個元素x 和y 代入比較運算符(對less 算子,調用x<y,對greater 算子,調用x>y),
若結果為真,則x 排在y 前面,y 將先於x 出隊,反之,則將y 排在x 前面,x 將先出隊。
看下面這個簡單的示例:
#include <iostream>

#include <queue>
using namespace std;
class T
{
public:
int x, y, z;
T(int a, int b, int c):x(a), y(b), z(c)
{
}
};
bool operator < (const T &t1, const T &t2)
{
return t1.z < t2.z; // 按照z 的順序來決定t1 和t2 的順序
}
main()
{
priority_queue<T> q;
q.push(T(4,4,3));
q.push(T(2,2,5));
q.push(T(1,5,4));
q.push(T(3,3,6));
while (!q.empty())
{
T t = q.top(); q.pop();
cout << t.x << " " << t.y << " " << t.z << endl;
}
return 1;
}
輸出結果為(注意是按照z 的順序從大到小出隊的):
3 3 6
2 2 5
1 5 4
4 4 3
再看一個按照z 的順序從小到大出隊的例子:
#include <iostream>
#include <queue>
using namespace std;
class T
{
public:
int x, y, z;
T(int a, int b, int c):x(a), y(b), z(c)
{
}
};
bool operator > (const T &t1, const T &t2)
{
return t1.z > t2.z;
}
main()
{
priority_queue<T, vector<T>, greater<T> > q;
q.push(T(4,4,3));
q.push(T(2,2,5));
q.push(T(1,5,4));
q.push(T(3,3,6));
while (!q.empty())
{
T t = q.top(); q.pop();
cout << t.x << " " << t.y << " " << t.z << endl;
}
return 1;
}
輸出結果為:
4 4 3
1 5 4
2 2 5
3 3 6
如果我們把第一個例子中的比較運算符重載為:
bool operator < (const T &t1, const T &t2)
{
return t1.z > t2.z; // 按照z 的順序來決定t1 和t2 的順序
}
則第一個例子的程序會得到和第二個例子的程序相同的輸出結果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM