1.向量
向量(vector)是可以改变其大小的线性序列容器。像数组一样,向量使用连续的空间存储元素,这表明向量也可以像数组一般通过其下标来访问其元素。但与数组不同的是,向量的大小可以动态变化。
向量在内部使用动态数组的方式来存储元素,无需关心实现细节。(平均意义下,向量插入元素的时间复杂度是常数O(1)级别)
1.1 向量构造
如何定义一个新的向量,常见的有如下几种方式:
定义一个向量
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
void print(vector<int> myVector, int n) {
printf("vector%d: ", n);
for(int i = 0; i < myVector.size(); ++i) {
printf("%d ",myVector[i]);
}
printf("\n");
}
int main()
{
int myArray[] = {1, 2, 3, 4, 5};
vector<int> myVector1; //
vector<int> myVector2(myArray, myArray + 5); //通过构造函数拷贝数组,区间左闭右开
vector<int> myVector3(5, 2); //也可以拷贝1个数组,这个数组的内容是5个2
vector<int> myVector4(myVector2); //可以拷贝向量
vector<int> myVector5(myVector4.begin(), myVector4.end()-2); //也可以只拷贝一部分,左闭右开区间
print(myVector1, 1);
print(myVector2, 2);
print(myVector3, 3);
print(myVector4, 4);
print(myVector5, 5);
return 0;
}
vector<类型>
可以是基础数据类型,也可以是自定义的数据类型如结构体等。
1.2 向量操作
即常见的系统内部已经定义的函数应该怎么使用。
1、返回向量的尺寸(元素个数):int n = myVector.size();
2、将向量尾部的值给弹出去:myVector.pop_back();
3、从向量尾部推入一个值:myVector.push_back();
4、插入操作:
-
可以插入一个值
myVector.insert(position, x);
; -
可以插入多个相同的值
myVector.insert(position, n, x);
; -
可以插入一段值,
myVector.insert(position, first_add, last_add);
,需要给定要插入元素的数组/向量的地址区间,左闭右开,且注意向量与数组不同的地方在于不能直接用名字访问地址,而是使用封装好的函数myVector.begin()
、myVector.end()
。
5、删除操作:
-
可以删除指定下标位置的一个元素
myVector.erase(position);
-
可以删除指定的一段下标区间内元素,左闭右开,
myVector.erase(first_add, last_add);
6、清除操作:myVector.clear()
常用的向量函数
//vector定义,常见的方式 2024-02-22
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
int main()
{
int myArray[] = {1, 2, 3, 4, 5};
vector<int> myVector(myArray , myArray+5); //通过构造函数给向量拷贝一个数组
int n = myVector.size();
myVector.pop_back(); //从向量尾部弹出一个值 1, 2, 3, 4
myVector.push_back(6); //从尾部推进去一个值6 1, 2, 3, 4, 6
//1, 9, 2, 3, 4, 6
myVector.insert(myVector.begin() + 1 , 9); //参数1:position,插入向量的下标位置;参数2:x,要插入的值
//7, 7, 7, 1, 9, 2, 3, 4, 6
myVector.insert(myVector.begin(), 3, 7); //参数1:position,插入向量的下标位置;参数2:n,插入几次;参数3:x,要插入的值
//1, 2, 7, 7, 7, 1, 9, 2, 3, 4, 6
myVector.insert(myVector.begin(), myArray, myArray + 2); //position, first_address, last_address(区间左闭右开)
//1, 2, 7, 7, 7, 1, 2, 3, 4, 6
myVector.erase(myVector.begin() + 6); //参数1:position,删除下标为6的元素
//1, 7, 7, 1, 2, 3, 4, 6
myVector.erase(myVector.begin() + 1, myVector.begin() + 3); //first_add, last_add(左闭右开) 删除从下标fisrt开始,到下标last-1之间的元素
myVector.clear();
return 0;
}
2.队列
在做题过程中,一旦发现有先进先出的特性时一定要首先想到队列这种数据结构。使用队列模板queue,就应在代码中添加头文件,其格式为#include <queue>
。定义一个队列和定义向量非常类似,写法为queue<typename> name
。
2.2 queue的状态
1、判空操作,即返回当前队列是否为空:empty()
2、队列长度,返回当前队列元素个数:size()
2.3 queue元素的添加或删除
1、入队操作,即向队列中添加新的元素:push(elem)
2、出队操作,即删除已有的元素:pop()
2.4 queue元素的访问
只能对队列的头尾两端进行操作。
1、访问队首,即获得队头元素的函数:front()
2、访问队尾,即获得队尾元素的函数为:back()
常用的队列函数
//队列的定义及常用操作 2024-02-22
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
int main()
{
queue<int> myQueue;
for(int i = 0; i < 10; ++i) {
myQueue.push(i); //入队
}
int sum = 0;
while(!myQueue.empty()) {
sum +=myQueue.front(); //访问队首
myQueue.pop(); //出队
}
cout << sum << endl;
return 0;
}
3.栈
同样,C++内部封装了容器stack,我们只要学会如何使用即可。栈的特性是后进先出规则。要使用stack的标准模板,需要添加头文件#include <stack>
,栈的常用函数与队列非常相似。
3.2 stack的状态
1、**判空**操作,返回当前栈是否为空:``empty()``2、栈长度,返回当前栈元素个数:size()
3.3 stack元素的添加或删除
1、入栈操作:定义一个栈后,要向栈中添加新元素push()
4、出栈操作:删除已有的元素pop()
3.4 stack元素的访问
只能对栈的栈顶一端进行操作,所以只能用top()
来访问栈顶元素,而不像队列那样可以访问队头和队尾。
常用的栈函数
//栈的定义和常用操作 2024-02-23
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
int main()
{
stack<int> myStack;
for(int i = 0; i < 10; ++i) {
myStack.push(i); //入栈
}
int sum = 0;
while (!myStack.empty()) { //判空
printf("%d ", myStack.top());
sum += myStack.top(); //访问栈顶
myStack.pop(); //出栈
}
printf("\n");
printf("%d\n",sum);
return 0;
}