(3)vector容器、deque容器、打分案例、stack容器、queue容器

STL中,最常用的容器之一

vector容器

vector基本概念

vector数据结构和数组非常相似,也称为单端数组

与普通数组的区别

数组是静态空间

vector可以动态扩展

动态扩展

不是在原空间后续接新空间,而是找到更大的内存空间,将原数据拷贝到新空间,释放原空间

vector容器的迭代器是支持随机访问的迭代器

vector构造函数

创建vector容器

void printVector(vector<int>& v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}
void test01() {
	vector<int>v1;//默认构造,无参构造
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
	}
	printVector(v1);//0 1 2 3 4 5 6 7 8 9
	//通过区间构造
	vector<int>v2(v1.begin(), v1.end());
	printVector(v2);//0 1 2 3 4 5 6 7 8 9
	//n个elem方式构造
	vector<int>v3(10,100);
	printVector(v3);//100 100 100 100 100 100 100 100 100 100
	//拷贝构造,用的比较多
	vector<int>v4(v3);
	printVector(v4);//100 100 100 100 100 100 100 100 100 100

}
int main() {
	test01();
	system("pause");
	return 0;
}

vector多种构造方式没有什么可比性,灵活使用即可

vector赋值操作

函数原型:

void printVector(vector<int>& v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;//换行
}
void test01() {
	vector<int>v1;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
	}
	printVector(v1);//0 1 2 3 4 5 6 7 8 9
	//赋值
	vector<int>v2;
	v2 = v1;
	printVector(v2);//0 1 2 3 4 5 6 7 8 9
	//assign赋值
	vector<int>v3;
	v3.assign(v1.begin(), v1.end());
	printVector(v3);//0 1 2 3 4 5 6 7 8 9
	//n个elem方式赋值
	vector<int>v4;
	v4.assign(10, 100);
	printVector(v4);//100 100 100 100 100 100 100 100 100 100
}

总结: vector赋值方式比较简单, 使用operator=, 或者assign都可以

vector容量和大小

void printVector(vector<int>& v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}
void test01() {
	vector<int>v1;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
	}
	printVector(v1);//0 1 2 3 4 5 6 7 8 9
	if (v1.empty()) {
		cout << "v1为空" << endl;
	}
	else {
		cout << "v1不为空" << endl;
		cout << "v1容量:" << v1.capacity() << endl;//v1容量:13
		cout << "v1大小:" << v1.size() << endl;//v1大小:10
	}
	//重新指定大小
	v1.resize(15,100);//利用重载版本,可以指定默认填充值:参数2
	printVector(v1);//如果重新指定的比原来的长,默认 用0填充 新位置
	//0 1 2 3 4 5 6 7 8 9 100 100 100 100 100
	v1.resize(5);
	printVector(v1);//如果重新指定的比原来的短,超出部分被删除
	//0 1 2 3 4
}

总结:
●判断是否为空 --  empty
●返回元素个数 --  size
●返回容器容量 --  capacity
●重新指定大小 --  resize

vector插入和删除

void printVector(vector<int>& v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}
void test01() {
	vector<int>v1;
	v1.push_back(10);//尾插
	v1.push_back(20);
	v1.push_back(30);
	v1.push_back(40);
	v1.push_back(50);
	printVector(v1);//10 20 30 40 50
	v1.pop_back();//尾删
	printVector(v1);//10 20 30 40
	v1.insert(v1.begin(), 100);//插入 第一个参数是迭代器
	printVector(v1);//100 10 20 30 40
	v1.insert(v1.begin(), 2, 1000);
	printVector(v1);//1000 1000 100 10 20 30 40
	v1.erase(v1.begin());//删除 参数也是迭代器
	printVector(v1);//1000 100 10 20 30 40
	v1.erase(v1.begin(), v1.end());//清空
	v1.clear();//清空
	printVector(v1);//空行
}

总结:
●尾插 -- push_ back
●尾删 -- pop_ back
●插入 -- insert (位置迭代器)
●删除 -- erase (位置迭代器)
●清空 --  clear

vector数据存取

void test01() {
	vector<int>v1;
	for (int i = 0; i < 10; i++) {//插入数据
		v1.push_back(i);
	}
	//利用[]方式访问数组元素
	for (int i = 0; i < v1.size(); i++) {
		cout << v1[i] << " ";
	}
	cout << endl;
	//利用at方式访问元素
	for (int i = 0; i < v1.size(); i++) {
		cout << v1.at(i) << " ";
	}
	cout << endl;
	cout << "第一个元素:" << v1.front() << endl;//第一个元素:0
	cout << "最后一个元素:" << v1.back() << endl;//最后一个元素:9
}

除了用迭代器获取vector容器中元素,[ ]和at也可以

vector互换容器

实现两个容器内元素互换

void printVector(vector<int>& v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}
void test01() {
	cout << "交换前:" << endl;
	vector<int>v1;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
	}
	printVector(v1);//0 1 2 3 4 5 6 7 8 9
	vector<int>v2;
	for (int i = 10; i > 0; i--) {
		v2.push_back(i);
	}
	printVector(v2);//10 9 8 7 6 5 4 3 2 1
	cout << "交换后:" << endl;
	v1.swap(v2);
	printVector(v1);//10 9 8 7 6 5 4 3 2 1
	printVector(v2);//0 1 2 3 4 5 6 7 8 9
}
void test02() {
	vector<int>v;
	for (int i = 0; i < 100000; i++) {
		v.push_back(i);
	}
	cout << "v容量:" << v.capacity() << endl;//v容量:138255
	cout << "v大小:" << v.size() << endl;//v大小:100000
	v.resize(3);//重新指定大小
	cout << "v容量:" << v.capacity() << endl;//v容量:138255
	cout << "v大小:" << v.size() << endl;//v大小:3
	//巧用swap收缩内存
	vector<int>(v).swap(v);
	//vector<int>(v) -- 匿名对象,被v按照目前使用的大小初始化,容量、大小都是3
	//.swap(v) -- 容器交换
	//匿名对象运行完后,系统会自动回收
	cout << "v容量:" << v.capacity() << endl;//v容量:3
	cout << "v大小:" << v.size() << endl;//v大小:3
}

swap可以使两个容器互换,可以达到实用的收缩内存效果

vector预留空间

减少vector在动态扩展容量时的扩展次数

void test01() {
	vector<int>v;
	v.reserve(100000);//利用reserve预留空间
	int num = 0;//统计开辟内存次数
	int* p = NULL;
	for (int i = 0; i < 100000; i++) {
	    v.push_back(i);
		if (p != &v[0]) {
			p = &v[0];
			num++;
		}
	}
	cout << " num = " << num << endl;//num = 30,预留空间后,num = 1
}

deque容器

deque容器基本概念

双端数组,可以对头端进行插入和删除操作

deque与vector区别:

  • vector对于头部的插入删除效率低,数据量越大,效率越低
  • deque相对而言,对头部的插入删除速度回比vector快
  • vector访问元素时的速度会比deque快,这和两者内部实现有关

deque内部工作原理:

  • deque内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据
  • 中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间

deque容器的迭代器也是支持随机访问的

deque构造函数

#include<deque>;
void printDeque(const deque<int>& d) {//防止被修改,加const变成只读,iterator也要加const
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		//*it = 100;//可以写出此行,相当于把容器中数据修改了
		cout << *it << " ";
	}
	cout << endl;
}
void test01() {
	deque<int>d1;
	for (int i = 0; i < 10; i++) {
		d1.push_back(i);
	}
	printDeque(d1);//0 1 2 3 4 5 6 7 8 9
	deque<int>d2(d1.begin(), d1.end());
	printDeque(d2);//0 1 2 3 4 5 6 7 8 9
	deque<int>d3(10, 100);
	printDeque(d3);//100 100 100 100 100 100 100 100 100 100
	deque<int>d4(d3);
	printDeque(d4);//100 100 100 100 100 100 100 100 100 100
}

deque容器和vector容器构造方式几乎一致

deque赋值操作

void printDeque(const deque<int>& d) {
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}
void test01() {
	deque<int>d1;
	for (int i = 0; i < 10; i++) {
		d1.push_back(i);
	}
	printDeque(d1);//0 1 2 3 4 5 6 7 8 9
	deque<int>d2;//operator= 赋值
	d2 = d1;
	printDeque(d2);//0 1 2 3 4 5 6 7 8 9
	//assign赋值
	deque<int>d3;
	d3.assign(d1.begin(), d1.end());
	printDeque(d3);//0 1 2 3 4 5 6 7 8 9
	deque<int>d4;
	d4.assign(10, 100);
	printDeque(d4);//100 100 100 100 100 100 100 100 100 100
}

deque赋值操作与vector相同

deque大小操作

void printDeque(const deque<int>& d) {
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}
void test01() {
	deque<int>d1;
	for (int i = 0; i < 10; i++) {
		d1.push_back(i);
	}
	if (d1.empty()) {
		cout << "d1为空" << endl;
	}
	else {
		cout << "d1不为空" << endl;
		cout << "d1大小:" << d1.size() << endl;//d1大小:10
		//deque容器没有容量概念
	}
	//重新指定大小
	//d1.resize(15);//0 1 2 3 4 5 6 7 8 9 0 0 0 0 0
	d1.resize(15,1);
	printDeque(d1);//0 1 2 3 4 5 6 7 8 9 1 1 1 1 1
	d1.resize(5);//0 1 2 3 4
	printDeque(d1);
}
  • deque没有容量概念
  • 判断是否为空 —— empty
  • 返回元素个数 —— size
  • 重新指定个数 —— resize

deque插入和删除

void printDeque(const deque<int>& d) {
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}
void test01() {
	deque<int>d1;
	d1.push_back(10);//尾插
	d1.push_back(20);
	d1.push_front(100);//头插
	d1.push_front(200);
	printDeque(d1);//200 100 10 20
	d1.pop_back();//尾删
	printDeque(d1);//200 100 10
	d1.pop_front();//头删
	printDeque(d1);//100 10
	d1.insert(d1.begin(), 1000);//insert插入
	printDeque(d1);//1000 100 10
	d1.insert(d1.begin(), 2, 10000);
	printDeque(d1);//10000 10000 1000 100 10
	//按照区间进行插入
	deque<int>d2;
	d2.push_back(1);
	d2.push_back(2);
	d2.push_back(3);
	d1.insert(d1.begin(), d2.begin(), d2.end());
	printDeque(d1);//1 2 3 10000 10000 1000 100 10
	//删除
	deque<int>::iterator it = d1.begin();
	it++;
	d1.erase(it);
	printDeque(d1);//1 3 10000 10000 1000 100 10
	//d1.erase(d1.begin(),d1.end());//区间方式删除,此行相当于清空
	d1.clear();//清空
	printDeque(d1);
}

插入和删除提供的位置是迭代器

deque数据存取

void test01() {
	deque<int>d;
	d.push_back(10);//尾插
	d.push_back(20);
	d.push_back(30);
	d.push_front(100);//头插
	d.push_front(200);
	d.push_front(300);
	//利用[]方式访问数组元素
	for (int i = 0; i < d.size(); i++) {
		cout << d[i] << " ";//300 200 100 10 20 30
	}
	cout << endl;
	//利用at方式访问元素
	for (int i = 0; i < d.size(); i++) {
		cout << d.at(i) << " ";//300 200 100 10 20 30
	}
	cout << endl;
	cout << "第一个元素:" << d.front() << endl;// 第一个元素:300
	cout << "最后一个元素:" << d.back() << endl;// 最后一个元素:30
}

deque排序

利用算法实现对deque容器进行排序

#include<algorithm>//算法头文件(标准算法头文件)
void printDeque(const deque<int>& d) {
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}
void test01() {
	deque<int>d;
	d.push_back(10);//尾插
	d.push_back(20);
	d.push_back(30);
	d.push_front(100);//头插
	d.push_front(200);
	d.push_front(300);
	printDeque(d);//300 200 100 10 20 30
	//排序   默认排序规则,从小到大,升序
	//对于支持随机访问的迭代器的容器,都可以利用sort算法直接对其进行排序
	//vector容器也可以利用sort进行排序
	sort(d.begin(), d.end());
	cout << "排序后:" << endl;
	printDeque(d);//10 20 30 100 200 300
}

sort算法非常实用,使用时包含头文件algorithm即可。

案例——评委打分

五名选手:ABCDE,10个评委分别对每一名选手打分,去除最高分,去除最低分,取平均分

实现步骤:

  • 创建五名选手,放到vector中
  • 遍历vector容器,取出来每一个选手,执行for循环,可以把10个评分打分存到deque容器中
  • sort算法对deque容器中分数排序,去除最高和最低分
  • deque容器遍历—遍,累加总分
  • 获取平均分
//案例——评委打分
#include<iostream>
using namespace std;
#include<vector>//使用每一个容器都要包含头文件
#include<deque>
#include<algorithm>//算法头文件(标准算法头文件)
#include<string>
#include<ctime>
class Person {
public:
	Person(string name, int score) {
		this->m_Name = name;
		this->m_Score = score;
	}
	string m_Name;
	int m_Score;//平均分
};
void createPerson(vector<Person>& v) {
	string nameSeed = "ABCDE";
	for (int i = 0; i < 5; i++) {
		string name = "选手";
		name += nameSeed[i];
		int score = 0;
		Person p(name, score);
		v.push_back(p);//将创建的person对象放入到容器
	}
}
//打分
void setScore(vector<Person>& v) {
	for (vector<Person>::iterator it = v.begin(); it != v.end(); it++) {
		//准备一个deque容器,放评委的打分
		deque<int>d;
		for (int i = 0; i < 10; i++) {
			int score = rand() % 41 + 60;//60~100随机数
			d.push_back(score);
		}
		cout <<"选手:"<< it->m_Name << "\t" << "打分:" << endl;
		for (deque<int>::const_iterator dit = d.begin(); dit != d.end(); dit++) {
			cout << *dit << " ";
		}
		cout << endl;
		//先排序,找到最高最低分,并去除
		sort(d.begin(), d.end());
		d.pop_back();
		d.pop_front();
		//获取平均分
		int sum = 0;
		for (deque<int>::const_iterator dit = d.begin(); dit != d.end(); dit++) {
			sum += *dit;//累加每个评委的分数
		}
		int avg = sum / d.size();//计算平均分
		//将平均分赋值到选手
		it->m_Score = avg;
	}
}
void showScore(vector<Person>& v) {
	for (vector<Person>::iterator it = v.begin(); it != v.end(); it++) {
		cout << "姓名:" << it->m_Name << "\t" << "平均分:" << it->m_Score << endl;
	}
}
int main() {
	//随机数种子
	srand((unsigned int)time(NULL));
	//创建5名选手
	vector<Person>v;//存放选手容器
	createPerson(v);
	测试代码
	//for (vector<Person>::iterator it = v.begin(); it != v.end(); it++) {
	//	cout << (*it).m_Name <<"\t" << (*it).m_Score << endl;
	//}
	//给选手打分
	setScore(v);
	//显示最后得分
	showScore(v);
	system("pause");
	return 0;
}

stack容器

stack基本概念

一种先进后出(First In Last Out,FILO)的数据结构,只有一个出口

栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为

栈容器,符合先进后出

栈可以判断容器是否为空——empty,可以返回元素个数——size。

栈中进入数据称为——入栈(push)

栈中弹出数据称为——出栈(pop)

stack常用接口

栈容器常用的对外接口

#include<stack>;
void test01() {
	stack<int>s;//特点:符合先进后出数据结构
	s.push(10);
	s.push(20);
	s.push(30);
	s.push(40);
	cout << "栈的大小:" << s.size() << endl;//栈的大小:4
	//只要栈不为空,查看栈顶,并且执行出栈操作
	while (!s.empty()) {
		cout << "栈顶元素为:" << s.top() << endl;
		s.pop();//出栈
	}
	cout << "栈的大小:" << s.size() << endl;//栈的大小:0
}

queue容器

queue基本概念

一种先进先出(First In Frist Out,FIFO)的数据结构,有两个出口

判断队列是否为空——empty,返回队列大小——size。

队列queue符合先进先出,只有队头和队尾能被外界访问,因此不允许有遍历行为

队列容器允许从一端新增元素,从另一端移除元素

队列中进数据称为——入队   push

队列中出数据称为——出队   pop

queue常用接口

#include<queue>;
class Person {
public:
	Person(string name, int age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};
void test01() {
	queue<Person>q;//创建队列
	//准备数据
	Person p1("唐僧", 30);
	Person p2("孙悟空", 1000);
	Person p3("猪八戒", 900);
	Person p4("沙僧", 800);
	//入队
	q.push(p1);
	q.push(p2);
	q.push(p3);
	q.push(p4);
	cout << "队列的大小:" << q.size() << endl;//队列的大小:4
	//判断只要对列不为空,查看队头、队尾,出队
	while (!q.empty()) {
		cout << "队头元素——姓名:" << q.front().m_Name << "\t年龄:" << q.front().m_Age << endl;
		cout << "队尾元素——姓名:" << q.back().m_Name << "\t年龄:" << q.back().m_Age << endl;
		q.pop();//出队
	}
	cout << "队列的大小:" << q.size() << endl;//队列的大小:0
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值