1 Star 0 Fork 0

xzx/C++学习

Create your Gitee Account
Explore and code with more than 13.5 million developers,Free private repositories !:)
Sign up
文件
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
deque.h 9.07 KB
Copy Edit Raw Blame History
xzx authored 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

Search