1 Star 0 Fork 0

xzx/C++学习

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
deque.h 9.07 KB
一键复制 编辑 原始数据 按行查看 历史
xzx 提交于 2025-04-25 18:42 +08:00 . update C++Learning/deque的模拟实现/deque.h.
#pragma once
#include<assert.h>
namespace Mydeque
{
template<class inputiterator,class T>
void fill(inputiterator first, inputiterator last, const T& val);
template<class inputiterator,class outputiterator>
void copyAtfirst(inputiterator first, inputiterator last, outputiterator dest); //从后往前拷贝
template<class inputiterator,class outputiterator>
void copyAtlast(inputiterator first, inputiterator last, outputiterator dest); //从前往后拷贝
template<class T, class Ref, class Ptr, size_t buffsize>
struct deque_iterator
{
typedef typename Ref Ref;
typedef typename Ptr Ptr;
typedef Ptr* map_pointer;
typedef deque_iterator self;
deque_iterator()
:first(nullptr),
last(nullptr),
cur(nullptr),
node(nullptr)
{ }
void setnode(map_pointer Node)
{
node = Node;
first = *Node;
cur = first;
last = first + buffsize;
}
Ref operator*()
{
return *cur;
}
Ptr operator->()
{
return &(operator*());
}
self& operator++() //前置++
{
++cur;
if (cur == last) //判断当前元素是否在缓冲区的末尾位置
{
setnode(node + 1);//让node跳跃到下一个缓冲区
cur = first; //cur指向起始位置
}
return *this;
}
self& operator--()
{
if (cur == first) { //判断当前元素是否在缓冲区的起始位置
setnode(node - 1); //让node跳跃到上一个缓冲区
cur = last - 1; //cur指向末尾位置
}
else {
--cur;
}
return *this;
}
self operator++(int)
{
self tmp(*this);
++(*this);
return tmp;
}
self operator--(int)
{
self tmp(*this);
--(*this);
return tmp;
}
int operator-(const self& dq) const
{
return int((node - dq.node - 1) * buffsize) + (cur - first) + (dq.last - dq.cur);
}
self& operator+=(int n)
{
int offset = n + (cur - first);
if (offset >= 0 && offset < buffsize)//判断是否在缓冲区内
{
cur += n;
}
else//目标不在缓冲区内
{
int offset_node =
offset > 0 ? offset / int(buffsize) : ((offset + 1) / (int)buffsize) - 1;
setnode(node + offset_node);//切换到正确的缓冲区
cur = first + offset - offset_node * buffsize;//切换到正确的位置
}
return *this;
}
self operator+(int n)
{
self tmp(*this);
return tmp += n;
}
self& operator-=(int n)
{
return *this += (-n);
}
self operator-(int n)
{
self tmp(*this);
return tmp -= n;
}
Ref operator[](int n)
{
return *(*this + n);
}
bool operator==(const self& dq) const
{
return cur == dq.cur;
}
bool operator!=(const self& dq) const
{
return cur != dq.cur;
}
bool operator<(const self& dq) const
{
return node == dq.node ? cur < dq.cur : node < dq.node;
}
bool operator>(const self& dq) const
{
return node == dq.node ? cur > dq.cur : node > dq.node;
}
Ptr first; //指向缓冲区的头
Ptr last; //指向缓冲区的尾
Ptr cur; //指向缓冲区的当前元素
map_pointer node; //指向缓冲区的指针
};
template<class T, size_t buffsize = 25>
class deque {
public:
typedef T* Ptr;
typedef T& Ref;
typedef T** map_pointer;
typedef deque self;
typedef deque_iterator<T, T&, T*, buffsize> iterator;
typedef deque_iterator<T, const T&, const T*, buffsize> const_iterator;
deque()
{
Create_Map_And_Node(0);
}
deque(size_t n, const T& val)
{
Create_Map_And_Node(n);
iterator it = start;
while (it != finish)
{
*it = val;
++it;
}
}
~deque()
{
for (map_pointer it = start.node; it <= finish.node; it++)
{
delete[] * it;
}
delete[] map;
}
void push_back(const T& val)
{
if (finish.cur != finish.last-1)
{
*finish = val;
++finish;
}
else {
ReserveMapAtBack();
*finish = val;
*(finish.node + 1) = new T[buffsize];
finish.setnode(finish.node + 1);
finish.cur = finish.first;
}
}
void push_front(const T& val)
{
if (start.cur != start.first)
{
--start;
*start = val;
}
else {
ReserveMapAtFront();
*(start.node - 1) = new T[buffsize];
/*start.setnode(start.node - 1);
start.cur = start.last - 1;*/
--start;
*start = val;
}
}
void pop_back()
{
assert(!empty());
if (finish.cur != finish.first)
{
--finish;
}
else {
delete[] finish.first;
finish.setnode(finish.node - 1);
finish.cur = finish.last - 1;
}
}
void pop_front()
{
assert(!empty());
if (start.cur != start.last - 1)
{
++start;
}
else {
delete[] start.first;
start.setnode(start.node + 1);
start.cur = start.first;
}
}
void clear()
{
for (map_pointer i = start.node; i <= finish.node; i++)
{
delete[] * i; //清除所有缓冲区
}
map_pointer tmp = map + map_size / 2;
*tmp = new T[buffsize];
start.setnode(tmp);
start.cur = start.first;
finish = start;
}
iterator insert(iterator pos, const T& val)
{
if (pos == finish) {
push_back(val);
return finish - 1;
}
else if (pos == start) {
push_front(val);
return start;
}
else {
int index = pos - start;
if (index < (size() / 2)) {
push_front(front());
copyAtfirst(start + 2, pos, start + 1);
--pos;
}
else {
push_back(back());
copyAtlast(pos, finish - 2, finish - 1);
}
*pos = val;
return pos;
}
}
iterator erase(iterator pos)
{
assert(!empty());
int index = pos - start;
if (index < (size() / 2))
{
copyAtlast(start, pos, pos + 1);
pop_front();
return pos + 1;
}
else {
copyAtfirst(pos + 1, finish, pos);
pop_back();
return pos;
}
}
T& operator[](size_t pos)
{
assert(pos < size());
return *(start + pos);
}
iterator begin()
{
return start;
}
iterator end()
{
return finish;
}
const_iterator begin() const
{
return start;
}
const_iterator end() const
{
return finish;
}
T& front()
{
return *start;
}
const T& front() const
{
return *start;
}
T& back()
{
return *(finish - 1);
}
const T& back() const
{
return *(finish - 1);
}
size_t size() const
{
return finish - start;
}
bool empty() const
{
return finish == start;
}
private:
void Create_Map_And_Node(size_t elementNum)
{
size_t nodeNum = elementNum / buffsize + 1; //计算缓冲区的大小
map_size = nodeNum < 8 ? 8 : nodeNum + 2; //预留缓冲区,提高效率
map = new Ptr[map_size]; //开辟map_size个缓冲区
//计算[nstart,nfinish]的区间
map_pointer nstart = map + (map_size - (elementNum / buffsize)) / 2;
map_pointer nfinish = nstart + nodeNum - 1;
//初始化这个区间
map_pointer tmp = nstart;
while (tmp <= nfinish)
{
*tmp = new T[buffsize]; //生成缓冲区
tmp++;
}
start.setnode(nstart);
start.cur = start.first;
finish.setnode(nfinish);
finish.cur = finish.first + (elementNum % buffsize);
}
void ReserveMapAtBack(size_t AddNode = 1)
{
if (AddNode >= (map_size - (finish.node - map))) {
reallocMap(AddNode, false);
}
}
void ReserveMapAtFront(size_t AddNode = 1)
{
if (AddNode >= (start.node - map)) {
reallocMap(AddNode, true);
}
}
void reallocMap(size_t AddNode, bool AllocAtFront)
{
size_t oldnodes = finish.node - start.node + 1; //旧的有效缓冲区大小
size_t newnodes = oldnodes + AddNode; //新的有效缓冲区大小
map_pointer newstart;
size_t newmapsize = map_size + (map_size > AddNode ? map_size : AddNode) + 2; //新map的管理缓冲区个数
map_pointer newmap = new Ptr[newmapsize]; //生成新的map数组
newstart = newmap + (newmapsize - newnodes) / 2 + (AllocAtFront ? AddNode : 0);
map_pointer newfinish = newstart + oldnodes - 1;
copyAtfirst(start.node, finish.node + 1, newstart); //拷贝
delete[] map; //释放旧空间
map = newmap;
map_size = newmapsize;
start.setnode(newstart);
finish.setnode(newfinish);
}
map_pointer map; //中控数组
size_t map_size; //中控数组的长度
iterator start; //指向第一个元素的迭代器
iterator finish; //指向最后一个元素后一位的迭代器
};
template<class inputiterator, class T>
void fill(inputiterator first, inputiterator last, const T& val)
{
while (first != last)
{
*first = val;
++first;
}
}
template<class inputiterator, class outputiterator>
void copyAtfirst(inputiterator first, inputiterator last, outputiterator dest) //从后往前拷贝
{
while (first != last)
{
*dest = *first;
++first;
++dest;
}
}
template<class inputiterator, class outputiterator>
void copyAtlast(inputiterator first, inputiterator last, outputiterator dest) //从前往后拷贝
{
while (last != first)
{
--last;
--dest;
*dest = *last;
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/xie-zhus-shovel/c-learning.git
git@gitee.com:xie-zhus-shovel/c-learning.git
xie-zhus-shovel
c-learning
C++学习
master

搜索帮助