C++ STL標準容器插入刪除演算法的複雜度
阿新 • • 發佈:2019-02-20
1 vector
內部實現: 陣列 // 就是沒有固定大小的陣列,vector直接翻譯是向量的意思
支援操作:
begin(), //取首個元素,返回一個iterator
end(), //取末尾(最後一個元素的下一個儲存空間的地址)
size(), //就是陣列大小的意思
clear(), //清空
empty(), //判斷vector是否為空
[] //很神奇的東東,可以和陣列一樣操作
//舉例: vector a; //定義了一個vector
//然後我們就可以用a[i]來直接訪問a中的第i + 1個元素!和陣列的下標一模一樣!
push_back(), pop_back() //從末尾插入或彈出
insert() O(N) //插入元素,O(n)的複雜度
erase() O(N) //刪除某個元素,O(n)的複雜度
可以用於陣列大小不定且空間緊張的情況
2 deque
類似 //雙端佇列,兩頭都支援進出
支援push_front()和pop_front()
是的精簡版:) //棧,只支援從末尾進出
支援push(), pop(), top()
是的精簡版 //單端佇列,就是我們平時所說的佇列,一頭進,另一頭出
支援push(), pop(), front(), back()
3 list
內部實現: 雙向連結串列 //作用和vector差不多,但內部是用連結串列實現
支援操作:
begin(), end(), size(), clear(), empty()
push_back(), pop_back() //從末尾插入或刪除元素
push_front(), pop_front()
insert() O(1) //連結串列實現,所以插入和刪除的複雜度的O(1)
erase() O(1)
sort() O(nlogn)(logn) 找不到返
//不支援[ ]操作!
4 set
內部實現: 紅黑樹 //Red-Black Tree,一種平衡的二叉排序樹
//又是一個Compare函式,類似於qsort函式裡的那個Compare函式,作為紅黑樹在內部實現的比較方式
insert() O(logn)
erase() O(logn)
find() O回a.end()
lower_bound() O(logn) 查詢第一個不小於k的元素
upper_bound() O(logn) 查詢第一個大於k的元素
equal_range() O(logn) 返回pair
5 multiset 允許重複元素的
6 map 內部實現: pair組成的紅黑樹 //map中文意思:印射!!
//就是很多pair 組成一個紅黑樹
insert() O(logn)
erase() O(logn)
find() O(logn) 找不到返回a.end()
lower_bound() O(logn) 查詢第一個不小於k的元素
upper_bound() O(logn) 查詢第一個大於k的元素
equal_range() O(logn) 返回pair
[key]運算子 O(logn) *** //這個..太猛了,怎麼說呢,陣列有一個下標,如a[i],這裡i是int型的。陣列可以認為是從int印射到另一個型別的印射,而map是一個任意的印射,所以i可以是任何型別的!
7 multimap 允許重複元素, 沒有[]運算子
8 priority_queue
內部實現: 堆 //優先佇列
支援操作:
push() O(n)
pop() O(n)
top() O(1)
See also: push_heap(), pop_heap() … in
9 hash_map
內部實現: Hash表//內部用雜湊表實現的map
過載HashFcn和EqualKey
支援操作:
insert(); O(1)
earse(); O(1)
[ ]; O(1)
1.sort()
void sort(RandomAccessIterator first, RandomAccessIterator last);
void sort(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering comp);
區間[first,last)
Quicksort,複雜度O(nlogn)
(n=last-first,平均情況和最壞情況)
用法舉例:
1.從小到大排序(int, double, char, string, etc)
const int N = 5;
int main()
{
int a[N] = {4,3,2,6,1};
string str[N] = {“TJU”,”ACM”,”ICPC”,”abc”,”kkkkk”};
sort(a,a+N);
sort(str,str+N);
return 0;
}
2.從大到小排序(需要自己寫comp函式)
const int N = 5;
int cmp(int a,int b) {return a > b;}
int main()
{
int a[N] = {4,3,2,6,1};
sort(a,a+N,cmp);
return 0;
}
3. 對結構體排序
struct SS {int first,second;};
int cmp(SS a,SS b) {
if (a.first != b.first) return a.first < b.first;
return a.second < b.second;
}
v.s. qsort() in C (平均情況O(nlogn),最壞情況O(n^2)) //qsort中的cmp函式寫起來就麻煩多了!
int cmp(const void *a,const void *b) {
if (((SS*)a)->first != ((SS*)b)->first)
return ((SS*)a)->first – ((SS*)b)->first;
return ((SS*)a)->second – ((SS*)b)->second;
}
qsort(array,n,sizeof(array[0]),cmp);
sort()系列:
stable_sort(first,last,cmp); //穩定排序
partial_sort(first,middle,last,cmp);//部分排序
將前(middle-first)個元素放在[first,middle)中,其餘元素位置不定
e.g.
int A[12] = {7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5};
partial_sort(A, A + 5, A + 12);
// 結果是 "1 2 3 4 5 11 12 10 9 8 7 6".
Detail: Heapsort ,
O((last-first)*log(middle-first))
sort()系列:
partial_sort_copy(first, last, result_first, result_last, cmp);
//輸入到另一個容器,不破壞原有序列
bool is_sorted(first, last, cmp);
//判斷是否已經有序
nth_element(first, nth, last, cmp);
//使[first,nth)的元素不大於[nth,last), O(N)
e.g. input: 7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5
nth_element(A,A+6,A+12);
Output: 5 2 6 1 4 3 7 8 9 10 11 12
2. binary_search()
bool binary_search(ForwardIterator first, ForwardIterator last, const LessThanComparable& value);
bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp);
在[first,last)中查詢value,如果找到返回Ture,否則返回False
二分檢索,複雜度O(log(last-first))
v.s. bsearch() in C
Binary_search()系列
itr upper_bound(first, last, value, cmp);
//itr指向大於value的第一個值(或容器末尾)
itr lower_bound(first, last, value, cmp);
//itr指向不小於valude的第一個值(或容器末尾)
pair equal_range(first, last, value, cmp);
//找出等於value的值的範圍 O(2*log(last – first))
int A[N] = {1,2,3,3,3,5,8}
*upper_bound(A,A+N,3) == 5
*lower_bound(A,A+N,3) == 3
make_heap(first,last,cmp) O(n)
push_heap(first,last,cmp) O(logn)
pop_heap(first,last,cmp) O(logn)
is_heap(first,last,cmp) O(n)
e.g:
vector vi;
while (scanf(“%d”,&n) != EOF) {
vi.push_back(n);
push_heap(vi.begin(),vi.end());
}
Others interesting:
next_permutation(first, last, cmp)
prev_permutation(first, last, cmp)
//both O(N)
min(a,b);
max(a,b);
min_element(first, last, cmp);
max_element(first, last, cmp);
Others interesting:
fill(first, last, value)
reverse(first, last)
rotate(first,middle,last);
itr unique(first, last);
//返回指標指向合併後的末尾處
random_shuffle(first, last, rand)
Some Others:
More container: Rope, Slist, Bitset …
More about iterator
Memory allocation
內部實現: 陣列 // 就是沒有固定大小的陣列,vector直接翻譯是向量的意思
支援操作:
begin(), //取首個元素,返回一個iterator
end(), //取末尾(最後一個元素的下一個儲存空間的地址)
size(), //就是陣列大小的意思
clear(), //清空
empty(), //判斷vector是否為空
[] //很神奇的東東,可以和陣列一樣操作
//舉例: vector a; //定義了一個vector
//然後我們就可以用a[i]來直接訪問a中的第i + 1個元素!和陣列的下標一模一樣!
push_back(), pop_back() //從末尾插入或彈出
insert() O(N) //插入元素,O(n)的複雜度
erase() O(N) //刪除某個元素,O(n)的複雜度
可以用於陣列大小不定且空間緊張的情況
2 deque
類似 //雙端佇列,兩頭都支援進出
支援push_front()和pop_front()
是的精簡版:) //棧,只支援從末尾進出
支援push(), pop(), top()
是的精簡版 //單端佇列,就是我們平時所說的佇列,一頭進,另一頭出
支援push(), pop(), front(), back()
3 list
內部實現: 雙向連結串列 //作用和vector差不多,但內部是用連結串列實現
支援操作:
begin(), end(), size(), clear(), empty()
push_back(), pop_back() //從末尾插入或刪除元素
push_front(), pop_front()
insert() O(1) //連結串列實現,所以插入和刪除的複雜度的O(1)
erase() O(1)
sort() O(nlogn)(logn) 找不到返
//不支援[ ]操作!
4 set
內部實現: 紅黑樹 //Red-Black Tree,一種平衡的二叉排序樹
//又是一個Compare函式,類似於qsort函式裡的那個Compare函式,作為紅黑樹在內部實現的比較方式
insert() O(logn)
erase() O(logn)
find() O回a.end()
lower_bound() O(logn) 查詢第一個不小於k的元素
upper_bound() O(logn) 查詢第一個大於k的元素
equal_range() O(logn) 返回pair
5 multiset 允許重複元素的
6 map 內部實現: pair組成的紅黑樹 //map中文意思:印射!!
//就是很多pair 組成一個紅黑樹
insert() O(logn)
erase() O(logn)
find() O(logn) 找不到返回a.end()
lower_bound() O(logn) 查詢第一個不小於k的元素
upper_bound() O(logn) 查詢第一個大於k的元素
equal_range() O(logn) 返回pair
[key]運算子 O(logn) *** //這個..太猛了,怎麼說呢,陣列有一個下標,如a[i],這裡i是int型的。陣列可以認為是從int印射到另一個型別的印射,而map是一個任意的印射,所以i可以是任何型別的!
7 multimap 允許重複元素, 沒有[]運算子
8 priority_queue
內部實現: 堆 //優先佇列
支援操作:
push() O(n)
pop() O(n)
top() O(1)
See also: push_heap(), pop_heap() … in
9 hash_map
內部實現: Hash表//內部用雜湊表實現的map
過載HashFcn和EqualKey
支援操作:
insert(); O(1)
earse(); O(1)
[ ]; O(1)
1.sort()
void sort(RandomAccessIterator first, RandomAccessIterator last);
void sort(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering comp);
區間[first,last)
Quicksort,複雜度O(nlogn)
(n=last-first,平均情況和最壞情況)
用法舉例:
1.從小到大排序(int, double, char, string, etc)
const int N = 5;
int main()
{
int a[N] = {4,3,2,6,1};
string str[N] = {“TJU”,”ACM”,”ICPC”,”abc”,”kkkkk”};
sort(a,a+N);
sort(str,str+N);
return 0;
}
2.從大到小排序(需要自己寫comp函式)
const int N = 5;
int cmp(int a,int b) {return a > b;}
int main()
{
int a[N] = {4,3,2,6,1};
sort(a,a+N,cmp);
return 0;
}
3. 對結構體排序
struct SS {int first,second;};
int cmp(SS a,SS b) {
if (a.first != b.first) return a.first < b.first;
return a.second < b.second;
}
v.s. qsort() in C (平均情況O(nlogn),最壞情況O(n^2)) //qsort中的cmp函式寫起來就麻煩多了!
int cmp(const void *a,const void *b) {
if (((SS*)a)->first != ((SS*)b)->first)
return ((SS*)a)->first – ((SS*)b)->first;
return ((SS*)a)->second – ((SS*)b)->second;
}
qsort(array,n,sizeof(array[0]),cmp);
sort()系列:
stable_sort(first,last,cmp); //穩定排序
partial_sort(first,middle,last,cmp);//部分排序
將前(middle-first)個元素放在[first,middle)中,其餘元素位置不定
e.g.
int A[12] = {7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5};
partial_sort(A, A + 5, A + 12);
// 結果是 "1 2 3 4 5 11 12 10 9 8 7 6".
Detail: Heapsort ,
O((last-first)*log(middle-first))
sort()系列:
partial_sort_copy(first, last, result_first, result_last, cmp);
//輸入到另一個容器,不破壞原有序列
bool is_sorted(first, last, cmp);
//判斷是否已經有序
nth_element(first, nth, last, cmp);
//使[first,nth)的元素不大於[nth,last), O(N)
e.g. input: 7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5
nth_element(A,A+6,A+12);
Output: 5 2 6 1 4 3 7 8 9 10 11 12
2. binary_search()
bool binary_search(ForwardIterator first, ForwardIterator last, const LessThanComparable& value);
bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp);
在[first,last)中查詢value,如果找到返回Ture,否則返回False
二分檢索,複雜度O(log(last-first))
v.s. bsearch() in C
Binary_search()系列
itr upper_bound(first, last, value, cmp);
//itr指向大於value的第一個值(或容器末尾)
itr lower_bound(first, last, value, cmp);
//itr指向不小於valude的第一個值(或容器末尾)
pair equal_range(first, last, value, cmp);
//找出等於value的值的範圍 O(2*log(last – first))
int A[N] = {1,2,3,3,3,5,8}
*upper_bound(A,A+N,3) == 5
*lower_bound(A,A+N,3) == 3
make_heap(first,last,cmp) O(n)
push_heap(first,last,cmp) O(logn)
pop_heap(first,last,cmp) O(logn)
is_heap(first,last,cmp) O(n)
e.g:
vector vi;
while (scanf(“%d”,&n) != EOF) {
vi.push_back(n);
push_heap(vi.begin(),vi.end());
}
Others interesting:
next_permutation(first, last, cmp)
prev_permutation(first, last, cmp)
//both O(N)
min(a,b);
max(a,b);
min_element(first, last, cmp);
max_element(first, last, cmp);
Others interesting:
fill(first, last, value)
reverse(first, last)
rotate(first,middle,last);
itr unique(first, last);
//返回指標指向合併後的末尾處
random_shuffle(first, last, rand)
Some Others:
More container: Rope, Slist, Bitset …
More about iterator
Memory allocation
Function object