C++容器

容器的分类

截图.png

分为顺序容器(sequence) 关联容器(asscoiative) 无序容器(unordered)

顺序容器Array、vector、deque、list

关联容器有(mul)set和(mul)map,set和map的区别在于,set的key就是value,而map的key和value是分开的,set和map内部都是通过红黑树实现

无序容器主要为拉链法实现的散列表

测试辅助函数

截图.png

using std::cin;

using std::cout;

using std::string;

long get_a_target_long()

{

long target = 0;

cout<<"target (0 ~"<<RAND_MAX<<"):";

cin>>target;

return target;

}

string get_a_target_string()

{

long target;

char buf[10];

cout<<"target (0 ~"<<RAND_MAX<<"):";

cin>>target;

snprintf(buf,10,"%d"target);

return target;

}

int compareLongs(const void* a,const void* b)

{

return (*(long*)a - *(long*)b);

}

int compareStrings(const void* a,const void* b)

{

if (*(string)a > *(string*)b)

return 1;

else if (*(string)a < *(string*)b)

return -1;

else

return 0;

}

 

1、Array

截图.png

运行结果

截图.png

 

 

const long ASIZE = 500000L;

#include<array>

#include<iostream>

#include<ctime>

#include<cstdlib>

namespace JJ01

{

void test_array()

{

cout<<"test_array().......\n";

//

std::array<long,ASIZE> c;

clock_t timeStart = clock();

for (long i = 0;i < ASIZE;i++){

c[i] = rand();

}

//

cout << "milli-seconds : " << (clock() - timeStart)<<std::endl;//

cout << "array.size()= " << c.size() << std::endl;

cout << "array.front()= " << c.front() << std::endl;

cout << "array.back()= " << c.back() << std::endl;

cout << "array.data()= " << c.data() << std::endl;

//

long target = get_a_target_long();

//

timeStart = clock();

qsort(c.data(),ASIZE,sizeof(long),compareLongs);

long* pItem = (long*)bsearch(&target,c.data(),ASIZE,sizeof(long),compareLongs);

cout<<"qsort()+bsearch(),milli-sconds:"<<clock() - timeStart<<std::endl;

if (pItem != NULL)

cout<<"found,"<<*pItem<<std::endl;

else

cout<<"not found!"<<std::endl;

}

}

int main()

{

using namespace JJ01;

test_array();

return 0;

}

 

2、Vector

截图.png

截图.png

关于vector的内存容量分配,如果vector发现内存容量不足时,会在当前容量的基础上变为原来的两倍(代码中的C++版本是这样的,后面版本变动可能会有所修改),过程就是找一块可用内存,大小为当前内存的两倍,然后把数据拷贝过去,然后释放当前内存

截图.png

 

 

const long ASIZE = 500000L;

#include<vector>

#include<stdexcept>

#include<string>

#include<cstdlib>

#include<cstdio>

#include<iostream>

#include<ctime>

#include<algorithm>

namespace JJ02

{

void test_Vector()

{

cout<<"test_Vector()......."<<std::endl;

//

std::vector<string> c;

char buf[10];

//

clock_t timeStart = clock();

for (long i = 0;i <ASIZE;++i)

{

try{

_snprintf(buf,10,"%d",rand());

c.push_back(string(buf));

}

catch(std::exception& p){

cout<<"i = "<<i<<" "<<p.what()<<std::endl;

//分配失败

abort();

}

}

//

cout<<"milli-seconds : "<<(clock() - timeStart)<<std::endl;

cout<<"vector.size() = "<<c.size()<<std::endl;

cout<<"vector.front() = "<<c.front()<<std::endl;

cout<<"vector.back() = "<<c.back()<<std::endl;

cout<<"vector.data() = "<<c.data()<<std::endl;

cout<<"vector.capacity() = "<<c.capacity()<<std::endl;

//

string target = get_a_target_string();

{

timeStart = clock();

auto pItem = std::find(c.begin(),c.end(),target);

cout<<"::find(),milli-second = "<<(clock() - timeStart)<<std::endl;

if (pItem != c.end())

cout<<"found : "<<*pItem<<std::endl;

else

cout<<"not found!"<<std::endl;

}

//

{

timeStart = clock();

sort(c.begin(),c.end());

string* pItem = (string*)bsearch(&target,c.data(),c.size(),sizeof(string),compareStrings);

//

cout<<"sort() + bsearch(),milli-second = "<<(clock() - timeStart)<<std::endl;

//

if (pItem != NULL)

cout<<"find : "<<*pItem<<std::endl;

else

cout<<"not found"<<std::endl;

}

}

}

int main()

{

using namespace JJ02;

test_Vector();

return 0;

}

 

3、List和forward_list

 

截图.png

list链表没有什么好讲的,比较常规,他分配内存的方式就是一个一个分配,

#include<list>

#include<stdexcept>

#include<string>

#include<cstdlib>

#include<cstdio>

#include<iostream>

#include<ctime>

#include<algorithm>

namespace JJ03

{

void test_List()

{

cout<<"test_List........"<<std::endl;

//

std::list<string> c;

char buf[10];

clock_t timeStart = clock();

//

for (long i = 0;i < ASIZE;i++)

{

try{

_snprintf(buf,10,"%d",rand());

c.push_back(string(buf));

}

catch(std::exception& p) {

cout<<"i = "<<i<<" "<<p.what()<<std::endl;

abort();

}

}

cout<<"milli-seconds : "<<(clock() - timeStart)<<std::endl;

cout<<"list.size() : "<<c.size()<<std::endl;

cout<<"list.max_size() : "<<c.max_size()<<std::endl;

cout<<"list.front() : "<<c.front()<<std::endl;

cout<<"list.back() : "<<c.back()<<std::endl;

//

string target = get_a_target_string();

timeStart = clock();

auto pItem = std::find(c.begin(),c.end(),target);

cout<<"std::find,milli-second : "<<(clock() - timeStart)<<std::endl;

if (pItem != c.end())

cout<<"find, Item = "<<*pItem<<std::endl;

else

cout<<"not found!"<<std::endl;

timeStart = clock();

c.sort();

cout<<"sort,milli-second : "<<(clock() - timeStart)<<std::endl;

}

}

int main()

{

using namespace JJ03;

test_List();

return 0;

}

实现list的size和max_size

/* Return the number of elements of in the list*/

size_type

size() const _GILBCXX_NOEXCEPT

{

return std::distance(begin(),end());

}

/* return the size() of the largest posiible list*/

size_type

max_size() _GILBCXX_NOEXCEPT

{

return _M_get_Node_allocator().max_size();

}

 

运行截图

截图.png

4、deque

截图.png

通常我们认为deque中的中的元素是连续的,但其实不是,deque中存放的是一个个的buffer,每个buffer相当于一个数组,但是头尾都可以进行操作,当进行操作的时候,如果迭代器到了buffer的尾端需要进行判断,如果到了就需要切换到下一个buffer,每个buffer之间可能是不连续的,用指针相连,相当于是一个buffer的链表

截图.png

#include<deque>

#include<stdexcept>

#include<string>

#include<cstdlib>

#include<cstdio>

#include<iostream>

#include<ctime>

#include<algorithm>

namespace JJ05

{

void test_deque()

{

cout<<"test_Deque()......."<<std::endl;

//

std::deque<string> c;

char buf[10];

//

clock_t timeStart = clock();

for (long i = 0;i <ASIZE;++i)

{

try{

_snprintf(buf,10,"%d",rand());

c.push_back(string(buf));

}

catch(std::exception& p){

cout<<"i = "<<i<<" "<<p.what()<<std::endl;

//分配失败

abort();

}

}

//

cout<<"milli-seconds : "<<(clock() - timeStart)<<std::endl;

cout<<"deque.size() = "<<c.size()<<std::endl;

cout<<"deque.front() = "<<c.front()<<std::endl;

cout<<"deque.back() = "<<c.back()<<std::endl;

//cout<<"deque.data() = "<<c.data()<<std::endl;

cout<<"deque.max_size() = "<<c.max_size()<<std::endl;

//

string target = get_a_target_string();

{

timeStart = clock();

auto pItem = std::find(c.begin(),c.end(),target);

cout<<"::find(),milli-second = "<<(clock() - timeStart)<<std::endl;

if (pItem != c.end())

cout<<"found : "<<*pItem<<std::endl;

else

cout<<"not found!"<<std::endl;

}

//

{

timeStart = clock();

std::sort(c.begin(),c.end());

//

cout<<"sort() + bsearch(),milli-second = "<<(clock() - timeStart)<<std::endl;

}

}

}

int main()

{

using namespace JJ05;

test_deque();

return 0;

}

 

运行截图

 

截图.png

5、stack和queue

 

截图.png

截图.png

stack和queue严格意义上不算container,而相当于adapter,因为他们相当于是deque的应用

所以说可以分为adapter而不是container

运行截图

截图.png

posted @ 2025-03-19 20:21  写在风中的信  阅读(7)  评论(0)    收藏  举报