C++刷题基础知识(栈、队列、hash、STL、基础函数等)---持续更新

摘要

  • C++11一些基本的数据结构
  • C++常用函数调用
  • 基本的使用方法(代码以及表格)
  • 主要是为了方便索引查找,助力代码自动化(代码那么多,靠索引字典吧,我尽量的实现了位置索引)

一、基本的数据结构

1.1 栈stack

1.1.1 stack的基本特性

C++ stack(堆栈)是一种基于后进先出(LIFO)原则操作的容器。它具有以下基本特性:

  • 后进先出(LIFO):只有位于堆栈顶部的元素可以被访问和删除,新添加的元素也会被放在堆栈的顶部。
  • 动态性:stack的大小是动态的,可以根据需要自动增长或缩小。
  • 随机访问:stack支持随机访问,可以通过索引直接访问任意位置的元素。但是注意,由于stack是后进先出(LIFO)的,所以最后一个添加到stack中的元素是第一个被访问的。
  • 容器的通用性:stack可以容纳任何类型的元素,包括基本类型和自定义类型。

1.1.2 stack的代码使用例程

#include <stack> //头文件

std::stack<int> myStack;  // 栈的声明创建

using namespace std;   //忽略std::
stack<int> myStack;


myStack.push(10);      //通过push添加元素
myStack.push(20);  

int top = myStack.top(); // 获取栈顶元素

myStack.pop(); // 删除栈顶元素

bool isEmpty = myStack.empty(); // 判断栈是否为空

int size = myStack.size(); // 获取栈的大小



//一些高级使用方法,自定义栈(固定类型和固定长度)
std::stack<int, std::vector<int>> myStack;

1.1.3 stack的用法总结(表格)

函数名 功能描述
push() 向栈顶添加一个元素
pop() 删除栈顶元素
top() 返回栈顶元素的值
empty() 判断栈是否为空,如果为空则返回true,否则返回false
size() 返回栈中元素的个数
clear() 清空栈中的所有元素。

1.2 单端队列queue

1.2.1 queue的基本特性

C++ queue是一种基于先进先出(FIFO)原则操作的容器。它具有以下基本特性:

  • 先进先出(FIFO):队列的头部是第一个被添加的元素,也是第一个可以被删除的元素。新添加的元素总是被放在队列的尾部。
  • 动态性:queue的大小是动态的,可以根据需要自动增长或缩小。
  • 随机访问:queue不支持随机访问,不能通过索引直接访问任意位置的元素。只能从队头开始依次访问。
  • 容器的通用性:queue可以容纳任何类型的元素,包括基本类型和自定义类型。

1.2.2 queue的代码使用例程

#include <queue>    //头文件声明
  
using namespace std;  
  
    
queue<int> q;  // 创建一个整数类型的队列  
  
q.push(10);  // 在队列尾部添加元素 

bool em=q.empty(); //判断队列是否为空

int ans=q.front(); //获取队列的头部第一个元素


int ans=q.back(); //获取队列的尾部第一个元素
   
q.pop();  //删除队列头部第一个元素

int qsize=q.size();    //获取队列大小

1.2.3 queue的用法总结(表格)

函数名 功能描述
push() 在队列尾部添加一个元素
pop() 删除队列的头部元素
front() 返回队列的头部元素
back() 返回队列的尾部元素
empty() 判断队列是否为空(元素个数为0)
size() 返回队列中元素的个数
clear() 清空栈中的所有元素。

 1.3 双端队列deque

1.3.1 deque的基本特性

C++ deque(双端队列)是一种具有队列和栈的性质的数据结构。它支持在队列的前端和后端进行插入和删除操作。其基本特性包括:

  • 双向队列:deque在队列的两端都可以进行插入和删除操作。
  • 动态数组:deque底层通常使用动态数组实现,可以动态地增长和缩小。
  • 顺序存储:deque中的元素是顺序存储的,相邻元素在内存中相邻存储。
  • 支持随机访问:deque支持使用索引进行访问,可以随机访问队列中的元素。
  • 高效的插入和删除操作:deque在队列的两端插入和删除元素的复杂度为O(1)。

1.3.2 deque的代码使用例程

#include <iostream>  
#include <deque>   //头文件声明 

using namespace std;
deque<int> d;  // 创建一个空的deque  
  
     
d.push_front(1);   // 在队列前端插入元素
  
    
d.push_back(3);  // 在队列后端插入元素   

int ans=d.size();//队列大小

d.pop_front();  //删除队列第一个元素
d.pop_back(); //删除队列最后一个元素

bool em=d.empty();//队列是否为空

1.3.3 deque的用法总结(表格)

函数名 功能描述 时间复杂度
push_front() 在队列前端插入一个元素 O(1)
push_back() 在队列后端插入一个元素 O(1)
pop_front() 删除队列前端的一个元素 O(1)
pop_back() 删除队列后端的一个元素 O(1)
front() 返回队列前端的元素 O(1)
back() 返回队列后端的元素 O(1)
empty() 判断空  

 

 1.4 数组容器vector

1.4.1 vector的基本特性

C++ vector是一种动态数组,它具有以下基本特性:

  • 动态性:vector的大小是动态的,可以在运行时添加或删除元素。
  • 随机访问:vector支持随机访问,可以通过索引直接访问任意位置的元素。
  • 容器的通用性:vector可以容纳任何类型的元素,包括基本类型和自定义类型。
  • 高效性:vector在内存中连续存储元素,因此访问元素的速度非常快。

1.4.2 vector的代码使用例程

#include <iostream>  
#include <vector>  
   
std::vector<int> v;  // 创建一个空的vector  
  
 
v.push_back(1);  // 在vector末尾添加元素 

int siz=v.size();   //返回vector数组大小

  
    
v.insert(v.begin(), 0);  // 在vector前端插入元素  

  
    
v.erase(v.begin() + 1);  // 删除vector中的元素  
  
     
v.clear();  // 清空vector中的元素 
  

1.4.3 vector的用法总结(表格)

函数名 描述
push_back() 在vector末尾添加一个元素
emplace_back() 在vector末尾添加一个元素(但不通过临时变量存储)
insert() 在vector前端或后端插入一个或多个元素
erase() 删除vector中的一个或多个元素
clear() 清空vector中的所有元素
resize() 调整vector的大小(会进行变量的初始化)
reserve() 调整vector的内存大小(不进行变量的初始化)
empty() 判断vector是否为空
size() 获取vector的大小
capacity() 获取vector的容量
front() 获取vector第一个元素的值
back() 获取vector最后一个元素的值
operator[] 通过索引访问vector中的元素
begin() 获取vector的起始迭代器
end() 获取vector的结束迭代器
rbegin() 获取vector的逆向起始迭代器(从尾部开始)
rend() 获取vector的逆向结束迭代器(从尾部开始)

1.4.4 vector的高级使用(优化)

1.4.4.1 元素插入(优化)

对于vector的元素插入存在两个函数push_back()以及emplace_back(),其都是向容器尾部插入元素,但存在一些小的差异点:

  • push_back()的机理:1.构造一个临时对象——2.调用移动构造函数把临时对象的副本拷贝到容器末尾增加的元素中——3.调用析构释放临时对象。
  • emplace_back()调用构造函数在容器末尾增加一个元素。

可以通过如下代码进行展示:

#include<iostream>
#include <vector>
using namespace std;

class MyTest
{
public:
    //普通构造
    MyTest(int id,int age):m_id(id),m_age(age)
    { 
        cout << "创建" << this << endl;
    }
    //拷贝构造
    MyTest(const MyTest &t):m_id(t.m_id),m_age(t.m_age)
    {  
        cout << "拷贝" << this << endl;
    }
    //移动构造
    MyTest(const MyTest &&t)
    {
        m_id = std::move(t.m_id);
        m_age = std::move(t.m_age);
        cout << "移动" << this << endl;
    }
    //析构
    ~MyTest()
    {
        cout << "析构" << this << endl;
    }
private:
    int m_id; //id成员
    int m_age;//age成员
};

int main(int argc, char *argv[])
{
    vector<MyTest> vec(10);
    cout << "\n ------ push_back --------" << endl;
    vec.push_back(MyTest(1,20));
    cout << "\n ------ emplace_back --------" << endl;
    vec.emplace_back(1,20);
    cout << "\n -------- finish -------- " << endl;
}

通过编译可以得到如下结果:

 ------ push_back --------
创建
移动
析构

 ------ emplace_back --------
创建

 -------- finish --------
析构
析构

因此emplace_back()的效率要比push_back()高得多,在处理大数据量的问题时效果更加明显。

1.4.4.2 容器大小声明(内存初始化)

在C++的std::vector中,resizereserve是两个用于处理动态数组的方法,它们的区别在于它们的目标和行为不同。

  1. resize:此方法用于改变vector的大小。如果你将vector的大小设为新的大小,那么vector中超出新大小的部分会被删除,而小于新大小的部分会被添加空值(对于基本类型)或默认构造的对象(对于类类型)。
  2. reserve:此方法用于改变vector的容量。reserve方法会预先分配足够的内存以容纳新的元素,但并不会构造这些元素。如果分配的容量大于当前的需求,那么多余的内存将被闲置,不会进行任何初始化。
std::vector<int> v;  
v.resize(10);  // v现在包含10个int类型的默认值(通常是0)


std::vector<int> v;  
v.reserve(10);  // v现在具有预先分配的内存,可以容纳10个int类型的元素,但v中仍然没有元素

  1.5 双向链表list *

1.5.1 list的基本特性

        C++的list是一种双链表,这意味着每个元素都有一个指向前一个和后一个元素的指针。相比于单链表,双链表在插入和删除操作中更为高效,因为它不需要遍历链表来找到插入或删除的位置。

        list支持常见的序列操作,如添加元素(push_front, push_back),删除元素(erase),查找元素(find),访问元素(front, back)等。同时,list还支持一些更高级的操作,如合并(splice),排序(sort),反转(reverse)等。

1.5.2 list的代码使用例程

#include <iostream>  
#include <list>  

using namespace std;  
list<int> my_list; // 创建一个整数类型的链表  
  
     
my_list.push_back(1);   // 添加元素
  
  
// 删除元素  
my_list.pop_back(); // 删除末尾元素  
my_list.pop_front(); // 删除头部元素  
my_list.erase(2); // 删除指定元素  
  
// 查找元素  
auto it = my_list.find(1); // 在链表中查找元素1,返回指向它的迭代器  
if (it != my_list.end()) { // 如果找到了元素1  
        std::cout << "Fo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值