对于C++中stack和queue的认识以及priority_queue的模拟实现

1. stack 和queue

stack 是栈,先入后出,只能从栈尾进行插入,栈尾进行输出。

queue是队列,元素先入先出,从队尾插入,队头出。

stack和queue的接口都类似,

区别仅仅是stack的栈顶元素用top,而queue的队头元素用front。

1.1 stack的底层

我们知道,vector类似于C语言学的数组,vector不适用于指定位置删除或增加,因为删除了之后需要移动后面的每个位置。

从stack和vector的接口看,栈就是一种特殊的vector。所以stack的底层用vector来实现。

而为了让栈适应所有类型的数据,就会用到模版。

复制代码
namespace zzj
{
  template<class T,class container = vector<T> >
class stack
{
  public:
    stack()
         {};
    void push(const T& x)
{
   _C.push_back(x);
 }
void pop()
{
 _c.pop_back();
}

T& top()
{
  return _c.back();
}
  private:
    container _c;
}
}

1.2 queue的底层实现

因为queue的接口存在头删和尾插,用vector封装太慢了,所以我们用list进行实现。

复制代码
namespace zzj
{
  template<class T,class container = list<T> >
class queu
{
  public:
    queue()
         {};
    void push(const T& x)
{
   _C.push_back(x);
 }
void pop()
{
 _c.pop_front();
}

T& back()
{
  return _c.back();
}
T& front ()
{
 return _c.front();
}
  private:
    container _c;
}
}

2. priority_queue

优先级队列是一种容器适配器,将里面的元素全部进行按序排列。即按从大到小或从小到大进行排列。

默认是从大到小进行排列。

优先级队列的底部通常是vector。但是优先级队列只能检索第一个元素,即最大或最小的元素。类似于堆,因此底层我们可以通过堆来进行排列。

2.1 优先级队列的模拟实现

堆需要进行向下调整和向上调整建堆。先分别实现向下调整建堆和向上调整建堆。

2.1.1 向下调整建堆:

我们需要从最后一个父结点开始,进行向下调整建堆。直到根节点。

复制代码
adjustdown(int parent)
{
   int child = parent*2+1;//左孩子
   while(child<container.size())
      { 
         if(child+1<container.size()&&container.[child]<container.[child+1])
{
 child++;
} 
else if(container.[parent]<container.[child])
{
  swap(container.[parent],container.[child]);
  parent = child;
  child = parent*2+1;
}
else break;
      }
}

2.1.2 向上调整建堆

我们需要从最后一个子节点开始建堆。

复制代码
adjustup(int child)
{
 int parent = (child-1)/2;
 while(parent>0)
{
   if(container.[child]>container.[parent])
{
  swap(container.[child],container.[parent]);
  child = parent;
  parent = (child-1)/2;
}
else break;
}
}

2.3 模拟实现

由于底层是堆结构,当删除第一个元素时,需要先将头尾置换,再将尾删除,再进行向下调整操作。

复制代码
void pop()
{
	swap(_con.[0], _com.[_con.size() - 1]);
	_con.pop_back();
	adjustdown(0);
}

当插入元素时,也是先插入到尾部,然后进行向上调整。

复制代码
void push(const T& x)
{
	_con.push_back(x);
	adjustup(_con.size() - 1);
}
相关推荐
归去来 兮15 分钟前
Python爬虫爬取数据案例
开发语言·爬虫·python
ShineWinsu17 分钟前
对于 C++:C++20中Concept(概念) 与 Coroutine(协程)的解析
linux·开发语言·网络·c++·c++20·epoll
ly768917 分钟前
C 语言从入门到进阶:语法、指针、内存管理与工程实践详解
c语言·开发语言
quantdash_cc34 分钟前
历史数据断层与REST请求慢到崩溃?QuantDash高性能量化数据API终极解决方案
开发语言·python·缓存·php·量化·quantdash
breeze jiang35 分钟前
Next.js 16 App Router 实战:从 About、Blog 动态路由到全局 404
开发语言·javascript·ecmascript
熊野君38 分钟前
Prompt / RAG / 规则 / Skills —— 定位、协作与实现路线
开发语言·python
liulilittle1 小时前
llmx 学习手册 06 —— CPU 指令集优化(AVX-512 三层演进)
c++·学习·算法·ai·llm
skr爱码士1 小时前
05_Qt 核心模块概览——Qt Core、Gui、Widgets、Quick 的职责划分
c++·qt·系统架构·客户端
山甫aa1 小时前
JavaWeb后端开发学习手册
java·开发语言·数据库·学习·mysql·springboot·web
zlinear数据采集卡1 小时前
数据采集卡从入门到精通(42):项目实战三——设备预测性维护系统,从布点到预警
开发语言·单片机·嵌入式硬件·安全·fpga开发