13C++复习.SLT容器之序列式容器(vector/dque/list)

一、简介

Vector中所采用的数据结构非常简单:线性连续空间。当分配空间被占满而仍然需要添加元素时,vector便会进行一场空间重新配置的大工程!在这里,程序员需要注意的是,一旦引起空间重新配置,之前指向原vector的所有迭代器就都失效了,这一点在工程中容易引起bug。

List则对空间的运用有绝对的精准,一点也不浪费。注意,list内部构成的实际是一个环状的双向链表!所以只需要一个指针,便可以完整地表现整个链表。

Deque相比于vector而言,它没有容量的概念,因为deque是动态地以分段连续空间组合而成,随时都可以增加一段新的空间并链接起来。

为了使得deque在逻辑上看起来是连续空间,在STL内部实现实际是使用了一块map(不是STL中的map容器)作为主控,map是一小块连续空间,其中每个元素都是指针,指向另一段较大的连续线性空间,称为缓冲区,这些缓冲区才是真正存放deque元素的主体。

二、Vector

1、vector特点

(1)将元素置于一个动态数组中加以管理。

(2)可以随机存取元素(用索引字节存取)

(3)数组尾部添加或移除元素非常快速。当在头部或中部安插元素比较费时。

2、vector成员函数

(1)push/pop

    c.pop_back()	//删除末尾的数据。

【示例】

    v.push_back(1);
    v.pop_back();
**```
(2)assign**
```c
    //将[beg,end)一个左闭右开区间的数据赋值给c。
    c.assign(beg,end)
    //将n个elem的拷贝赋值给c。
    c.assign (n,elem)

【示例】

v1.push_back(10);
v1.push_back(20);
v2.push_back(30);
v2.assign(v1.begin(),v1.end());
v.assign(5, 10);

(3)begin/end/rbegin/rend/at

    c.at(int index)
    
    //返回指向第一个数据的迭代器。
    c.begin()
    //返回指向最后一个数据之后的迭代器。
    c.end()
    //返回逆向队列的第一个数据,即c容器的最后一个数据。
    c.rbegin()
    //返回逆向队列的最后一个数据的下一个位置,即c容器的第一个数据再往前的一个位置。
    c.rend() 

【示例】

v.push_back(1);
v.push_back(2);
v.push_back(3);
cout << v.at(2) << endl;
vector<int>::iterator it;
for(it = v.begin();it!=v.end();it++){
    cout << *it << "\t";
}
cout << endl;

(4)clear/empty/front/back

    c.empty()//判断容器是否为空。
    c.front()//返回第一个数据。
    c.back()//传回最后一个数据,不检查这个数据是否存在。

【示例】

v.push_back(1);
v.push_back(2);
v.push_back(3);
if(!vec.empty()){
    cout << “the first number is:” << v.front() << endl;
    cout << “the last number is:” << v.back() << endl;
}

(5)insert系列

    c.insert(pos,elem) 
    //在pos位置插入n个elem的数据,无返回值。
    c.insert(pos,n,elem)
    //在pos位置插入在[beg,end)区间的数据,无返回值。
    c.insert(pos,beg,end)

【示例】

    v.insert(v.begin(),10);
    v.insert(v.begin(),2,20);
    v.insert(v.begin(),v1.begin(),v1.begin()+2);

(6)erase系列

    c.erase(pos)
    //删除[beg,end)区间的数据,传回下一个数据的位置。
    c.erase(beg,end)

【示例】

v.push_back(1);
v.push_back(2);
v.push_back(3);
v.erase(v.begin());
//v.erase(v.begin(), v.end());

(7)swap

    swap(c1,c2//)同上。

【示例】

    v1.push_back(10);
    v2.swap(v1);
    swap(v3,v1);

三、Deque

1、Deque特点

(1)deque是“double-ended queue的缩写

(2)可以随机存取元素(用索引直接存取)

(3)数组头部和尾部添加或移除元素都非常快,当在中部或头部安插元素比较费时。

双端队列(deque),顾名思义,两端都可以操作,插入和删除。而且,还可以在中间进行操作。内部采用线性表顺序结构,与vector不同的是,deque采用分块的线性存储结构存储数据,每块大小512字节。

所有的deque块使用一个Map块进行管理,每个Map数据项纪录各个deque块的首地址。当考虑容器内部的内存分配策略和操作性能时,deque相对于vector更有优势,同时,也可以用下标来访问。

2、构造函数

    deque<Elem> c1(c2) //复制一个deque。
    deque<Elem> c(n) //创建一个deque,含有n个数据,数据均已缺省构造产生。
    deque<Elem> c(n, elem)// 创建一个含有n个elem拷贝的deque。
    deque<Elem> c(beg,end) //创建一个以[beg;end)区间的deque。
    ~deque<Elem>() //销毁所有数据,释放内存。

3、成员函数

(1)begin_end系列

    c.end()//返回指向最后一个元素下一个位置的迭代器
    c.rbegin()//返回指向反向队列的第一个元素的迭代器(即原队列的最后一个元素)
    c.rend()//返回指向反向队列的最后一个元素的下一个位置(即原队列的第一个元素的前一个位置)

【示例】

deque<int>::iterator it;//deque迭代器
deque<int>::reverse_iterator rit;//deque反向迭代器
for(it=d.begin();it!=d.end();it++){
    cout << *it << " ";
}
cout << endl;
for(rit=d.rbegin(); rit!=d.rend(); rit++){
    cout << *rit << " ";
}
cout << endl;

(2)assign系列

    c.assign(beg,end)将[beg,end)区间的数据拷贝复制到容器c

【示例】

d2.assign(2, 8);
deque<int>::iterator it;
cout << "d2.assign(n,num):";
for(it=d2.begin();it!=d2.end();it++){
    cout << *it << " ";
}
d2.assign(d1.begin(), d1.begin()+3);
cout << "d2.assign(beg,end):";
for(it=d2.begin();it!=d2.end();it++){
    cout << *it << " ";
}
cout << endl;

(3)at和[]下标运算符

    c.operator[]//下标运算符重载

【示例】

    cout << "d.at(pos):" << d.at(2);
    cout << "d[2] : " << d[2];
    return 0;

(4)empty/front/back

    c.front()//返回c容器的第一个元素
    c.back()//返回c容器的最后一个元素

【示例】

    if(!d.empty()){
        cout << "d.front():" << d.front() << endl;
        cout << "d.back(): " << d.back() << endl;
    }

(5)size系列

    c.max_size()//返回c容器可能存放元素的最大数量

【示例】

    cout << "d.size():" << d.size() << endl;
    cout << "d.max_size():" << d.max_size() << endl;
    return 0;

(6)insert系列

    c.insert(pos,elem) //在pos位置插入一个elem的拷贝,返回插入的值的迭代器。
    c.insert(pos,n,elem)//在pos位置插入n个elem的数据,无返回值。
    c.insert(pos,beg,end)//在pos位置插入在[beg,end)区间的数据,无返回值。

【示例】

deque<int>::iterator it;
cout << "insert before:" ;
for(it=d.begin();it!=d.end();it++){
    cout << *it << " ";
}
cout << endl;
d.insert(d.end(),22);
d.insert(d.end(), 3,88);
int a[5] = {1,2,3,4,5};
d.insert(d.begin(),a,a+3);
cout << "insert after:" ;
for(it=d.begin();it!=d.end();it++){
    cout << *it << " ";
}
d.clear();
cout << endl;

(7)erase系列

    c.erase(beg,end)//删除区间为[beg,end)之间的元素

【示例】

d.erase(d.begin());
deque<int>::iterator it;
cout << "erase(pos) after:" ;
for(it=d.begin();it!=d.end();it++){
    cout << *it << " ";
}
cout << endl;
d.erase(d.begin(), d.begin()+3);
cout << "erase(beg,end) after:" ;
for(it=d.begin();it!=d.end();it++){
    cout << *it << " ";
}
cout << endl;

(8)push_pop系列

    c.pop_back()//删除末尾位置的元素
    c.push_front(num)//在开头位置插入元素
    c.pop_front()//删除开头位置的元素

【示例】

d.push_back(10);
deque<int>::iterator it;
cout << "push_back(num):" ;
for(it=d.begin();it!=d.end();it++){
        cout << *it << " ";
}
cout << endl;

d.pop_back();
cout << "pop_back(num):" ;
for(it=d.begin();it!=d.end();it++){
    cout << *it << " ";
}
cout << endl;

d.push_front(10);
cout << "push_front(num):" ;
for(it=d.begin();it!=d.end();it++){
    cout << *it << " ";
}
cout << endl;

d.pop_front();
cout << "pop_front(num):" ;
for(it=d.begin();it!=d.end();it++){
    cout << *it << " ";
}
cout << endl;
return 0;

(9)resize

【示例】

cout << "d.size():" << d.size() << endl;
d.resize(d.size()+5);
cout << "d.resize() after:" << d.size() <<endl;
deque<int>::iterator it;
cout << "resize() after:" ;
for(it=d.begin();it!=d.end();it++){
cout << *it << " ";
}
cout << endl;

(10)swap系列

    swap(c1,c2)//同上。

【示例】

d1.swap(d2);
deque<int>::iterator it;
cout << "d1 swap after:" ;
for(it=d1.begin();it!=d1.end();it++){
    cout << *it << " ";
}
cout << endl;
cout << "d2 swap after:" ;
for(it=d2.begin();it!=d2.end();it++){
    cout << *it << " ";
}
cout << endl;

swap(d3,d2);
cout << "d3 swap after:" ;
for(it=d3.begin();it!=d3.end();it++){
    cout << *it << " ";
}
cout << endl;

四、List

1、List特点

(1)双向链表

(2)不提供随机存取(按顺序走到需要存取的元素,O(n))

(3)在任何位置上执行插入和删除动作都非常块,内部只需要调整一下指针。

list是双向链表,有vector,deque的特征,而且效率高。它有插入(前插,后插,中间插),删除(前删,后删,清空等),排序等功能。而且,可以剔除连续相同元素,保留一个。

2、构造函数

    list<int> c1(3); //建一个含三个默认值是0的元素的链表
    list<int> c2(5,2); //建一个含五个元素的链表,值都是2
    list<int> c4(c2); //建一个c2的copy链表
    list<int> c5(c1.begin(),c1.end()); c5含c1一个区域的元素[_First, _Last)。

3、成员函数

(1)begin_end系列

    c.end()        //返回指向链表最后一个元素之后的迭代器。
    c.rbegin()     //返回逆向链表的第一个元素,即c链表的最后一个数据。
    c.rend()       //返回逆向链表的最后一个元素的下一个位置,即c链表的第一个数据再往前的位置。

【示例】

list<int>::iterator it;//List的迭代器
list<int>::reverse_iterator rit;//List反向迭代器
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << "\t";
}
cout << endl;
for(rit=a1.rbegin(); rit!=a1.rend(); rit++){
    cout << *rit  <<  "  ";
}
cout << endl;

(2)assign系列

    c.assign(beg,end)      //将[beg,end)区间的元素拷贝赋值给链表c。

【示例】

list<int> a1;
list<int>::iterator it;
a1.assign(2,10);
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;
a1.assign(a,a+5);
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

(3)font/back/empty

    c.back()       返回链表c的最后一个元素。
    c.empty()      判断链表是否为空。

【示例】

if(!a1.empty())
   cout << "the first number is:" << a1.front() << endl;
else
   cout << " the last number is:" << a1.back() << endl;

(4)size/max_size/clear

    c.max_size()  //返回链表c可能容纳的最大元素数量。
    c.clear()     //清除链表c中的所有元素。

【示例】

list<int>::iterator it;
cout << a1.size() << endl;
cout << a1.max_size() << endl;
cout << "clear before:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << "\t";
}
cout << endl;
a1.clear();
cout << "clear after:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << "\t";
}
cout << endl;

(5)insert系列

    c.insert(pos,n,num)    //在pos位置插入n个元素num。
    c.insert(pos,beg,end)  //在pos位置插入区间为[beg,end)的元素。

【示例】

list<int>::iterator it;
cout << "insert before:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

a1.insert(a1.begin(),0);
cout << "insert(pos,num) after:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

a1.insert(a1.begin(),2,88);
cout << "insert(pos,n,num) after:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

int arr[5] = {11,22,33,44,55};
a1.insert(a1.begin(),arr,arr+3);
cout << "insert(pos,beg,end) after:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

(6)erase

【示例】

list<int>::iterator it;
cout << "erase before:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;
a1.erase(a1.begin());
cout << "erase after:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

(7)push/pop系列

    c.pop_back()          //删除末尾的元素。
    c.push_front(num)     //在开始位置增加一个元素。
    c.pop_front()         //删除第一个元素。

【示例】

a1.push_back(10);
list<int>::iterator it;
cout << "push_back:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

a1.pop_back();
cout << "pop_back:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

a1.push_front(20);
cout << "push_front:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

a1.pop_front();
cout << "pop_front:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

(8)resize系列

    resize(n,num)  //从新定义链表的长度,超出原始长度部分用num代替。

【示例】

a1.resize(8);
list<int>::iterator it;
cout << "resize(n):";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

a1.resize(10, 10);
cout << "resize(n,num):";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

(9)swap

    swap(c1,c2);      同上。

【示例】

a2.swap(a1);
list<int>::iterator it;
cout << "a2.swap(a1):";
for(it = a2.begin();it!=a2.end();it++){
    cout << *it << " ";
}
cout << endl;

swap(a3,a2);
cout << "swap(a3,a2):";
for(it = a3.begin();it!=a3.end();it++){
    cout << *it << " ";
}
return 0;

(10)merge

    c1.merge(c2,comp) //合并2个有序的链表并使之按照自定义规则排序之后从新放到c1中,释放c2。

【示例】

a1.merge(a2);
list<int>::iterator it;
cout << "a1.merge(a2):";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

a2.merge(a1,[](int n1,int n2){return n1>n2;});
cout << "a2.merge(a1,comp):";
for(it = a2.begin();it!=a2.end();it++){
    cout << *it << " ";
}
cout << endl;

(11)splice系列

    c1.splice(c1.beg,c2,c2.beg)//将c2的beg位置的元素连接到c1的beg位置,并且在c2中施放掉beg位置的元素
    c1.splice(c1.beg,c2,c2.beg,c2.end)//将c2的[beg,end)位置的元素连接到c1的beg位置并且释放c2的[beg,end)位置的元素

【示例】

a1.splice(a1.begin(), a2);
list<int>::iterator it;
cout << "a1.merge(a2):";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;
a1.splice(a1.begin(), a2,++a2.begin());
list<int>::iterator it;
cout << "a1.merge(a2):";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;
return 0;
a1.splice(a1.begin(),a2,a2.begin(),a2.end());
list<int>::iterator it;
cout << "a1.merge(a2):";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;
return 0;

(12)remove

【示例】

a1.remove(3);
list<int>::iterator it;
cout << "remove():";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

(13)remove_if

【示例】

a1.remove_if([](int n){return n<3;});
list<int>::iterator it;
cout << "remove_if():";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

(14)reverse

【示例】

a1.reverse();
list<int>::iterator it;
cout << "reverse:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

(15)unique

【示例】

a1.unique();
list<int>::iterator it;
cout << "unique:";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;
return 0;

(16)sort

    c.sort(comp)       自定义回调函数实现自定义排序

【示例】

a1.sort();
list<int>::iterator it;
cout << "sort():";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

a1.sort([](int n1,int n2){return n1>n2;});
cout << "sort(function point):";
for(it = a1.begin();it!=a1.end();it++){
    cout << *it << " ";
}
cout << endl;

转自https://blog.csdn.net/sinat_33924041/article/details/83687003

posted @   底层逻辑  阅读(123)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示