list_stack_queue

1.list的介绍及使用

list是STL中的带头双向循环链表,list中的接口比较多,此处类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,已达到可扩展的能力。以下为list中一些常见的重要接口。

1.1list的构造

以下是list构造的解释以及标准库的介绍。

1.2list的迭代器

list 的迭代器属于双向迭代器,仅支持 ++/-- 单步移动,不支持 +/- 跳步操作;vector 的迭代器属于随机迭代器,除了支持双向迭代器的全部功能,还支持 +/- 跳步、[] 随机访问等操作。list 的节点在空间上不连续,因此插入操作不会导致迭代器失效,但删除节点会导致指向该节点的迭代器失效;而 vector 因内存连续,插入(扩容 / 移动)和删除(元素移动)都会导致迭代器失效。

1.3list capacity

由于list的节点在空间上不是连续的所以list提供了专门的接口来记录list的capacity。

1.4list element access

以下是返回头尾节点的接口。

1.5list modifiers

以下是list的增删查改接口。

2.stack

2.1.stack的使用

以下是stack的常用接口。

以下是最小栈的解法。

cpp 复制代码
class MinStack
{
public:
void push(int x)
{
// 只要是压栈,先将元素保存到_elem中
_elem.push(x);
// 如果x小于_min中栈顶的元素,将x再压入_min中
if(_min.empty() || x <= _min.top())
_min.push(x);
}
void pop()
{
// 如果_min栈顶的元素等于出栈的元素,_min顶的元素要移除
if(_min.top() == _elem.top())
_min.pop();
栈的弹出压入序列
逆波兰表达式求值
_elem.pop();
}
int top(){return _elem.top();}
int getMin(){return _min.top();}
private:
// 保存栈中的元素
std::stack<int> _elem;
// 保存栈的最小值
std::stack<int> _min;
};

1.2stack的模拟实现

栈的特性和vector有些相似所以在模拟实现栈是完全可以使用vector来模拟实现。

cpp 复制代码
#include<vector>
namespace bite
{
template<class T>
class stack
{
public:
stack() {}
void push(const T& x) {_c.push_back(x);}
void pop() {_c.pop_back();}
T& top() {return _c.back();}
const T& top()const {return _c.back();}
size_t size()const {return _c.size();}
bool empty()const {return _c.empty();}
private:
std::vector<T> _c;
};
}

3.queue

3.1queue的使用

以下是queue的常用接口。

3.2queue的模拟实现

因为queue的接口中存在头删和尾插,因此使用vector来封装效率太低,故可以借助list来模拟实现queue,具体如下:

cpp 复制代码
#include <list>
namespace bite
{
template<class T>
class queue
{
public:
queue() {}
void push(const T& x) {_c.push_back(x);}
void pop() {_c.pop_front();}
T& back() {return _c.back();}
const T& back()const {return _c.back();}
T& front() {return _c.front();}
const T& front()const {return _c.front();}
size_t size()const {return _c.size();}
bool empty()const {return _c.empty();}
private:
std::list<T> _c;
};
}

4.priority_queue的介绍和使用

4.1priority_queue的使用

priority_queue(优先级队列)是 C++ STL 的容器适配器,底层基于堆(heap)结构实现。默认情况下,它通过less<T>比较规则实现大顶堆(较大的元素优先出队);也可通过指定模板参数(如greater<T>)改为小顶堆,或自定义仿函数实现任意优先级规则。

4.2priority_queue的模拟实现

由于priority_queue底层就是堆所以可以使用vector对其进行封装就可以实现了。不过由于vector是顺序表所以还需我们自行实现向上向下调整算法。如下:

cpp 复制代码
template <class T>
    class myless
    {
    public:
        bool operator()(const T& x,const T& y)
        {
            return x < y;
        }
    };
    template <class T>
    class mygreater
    {
    public:
        bool operator()(const T& x, const T& y)
        {
            return x > y;
        }
    };

    template <class T, class Container = std::vector<T>, class Compare = std::less<T> >

    class priority_queue

    {

    public:

        priority_queue()
        {

        }

        template <class InputIterator>

        priority_queue(InputIterator first, InputIterator last);

        bool empty() const
        {
            return c.empty();
        }

        size_t size() const
        {
            return c.size();
        }

        T& top() 
        {
            return c.front();
        }
        const T& top() const
        {
            return c.front();
        }
        void a(size_t x)
        {
            size_t y = (x - 1) / 2;
            while (x > 0)
            {
                if (comp(c[x], c[y]))
                {
                    std::swap(c[x], c[y]);
                    x = y;
                    y = (x - 1) / 2;
                }
                else {
                    break;
                }
            }
        }
        void b(size_t x)
        {
            size_t y = 2 * x + 1;
            while (y < c.size())
            {
                if ((y + 1) < c.size() && comp(c[y], c[x]))
                {
                    ++y;
                }
                if (comp(c[y], c[x]))
                {
                    std::swap(c[x], c[y]);
                    x = y;
                    y = x * 2 + 1;
                }
                else
                {
                    break;
                }
            }
        }
        void push(const T& x)
        {
            c.push_back(x);
            a(c.size() - 1);
        }

        void pop()
        {
            std::swap(c[0], c[c.size() - 1]);
            c.pop_back();
            b(0);
        }

    private:

        Container c;

        Compare comp;

    };

5.容器适配器

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。STL标准库中sstack、queue的底层使用的其实是容器适配器默认使用deque。

5.1deque的简单介绍

deque(双端队列)结合了 vector(支持随机下标访问)和 list(头尾增删效率高)的核心优点:既可以像 vector 一样通过下标随机访问元素,又能像 list 一样高效完成头尾的插入 / 删除操作。但 deque 无法完全取代 vector 和 list------ 它的中间位置 insert/erase 效率极低,随机访问效率略低于 vector,中间操作效率远低于 list。deque 的底层并非二维数组,而是由 "中控数组 + 多个分段连续的内存块" 组成,通过迭代器的无缝跳转逻辑,保证了元素在逻辑上的连续性;且 deque 在扩容时无需拷贝全部元素,这一点比 vector 更高效。以下是deque的底层结构:

相关推荐
zh_xuan2 小时前
最小跳跃次数
数据结构·算法
zh_xuan2 小时前
单青蛙跳台阶
数据结构·算法
罗湖老棍子3 小时前
【 例 1】石子合并(信息学奥赛一本通- P1569)
数据结构·算法·区间dp·区间动态规划·分割合并
小高Baby@4 小时前
JSON、bind、form
数据结构·json
数智工坊6 小时前
【数据结构-栈】3.1栈的顺序存储-链式存储
java·开发语言·数据结构
执着2596 小时前
力扣102、二叉树的层序遍历
数据结构·算法·leetcode
元亓亓亓6 小时前
考研408--数据结构--day5--栈与队列的应用
数据结构·考研··408·队列
小高Baby@7 小时前
Golang中面向对象的三大特性之多态的理解
数据结构·golang
dazzle7 小时前
Python数据结构(十五):归并排序详解
数据结构·python·算法