一、容器适配器
stack和queue并不属于容器,他们是容器适配器,他们的实现不再像之前一样利用数组和指针进行实现,而是利用已经封装好的容器进行实现的。
我们翻看文档可以发现,stack和queue都是属于容器适配器,而他们的底层实现是通过deque容器来实现的,deque容器我们之前并没有见到过,我们只需知道deque是vector和list的结合体,deque分别拥有vector和list的特性。
二、模拟实现stack
2.1 模拟实现stack的接口
namespace bit
{
template<class T, class Con = deque<T>>
class stack
{
public:
stack();
void push(const T& x);
void pop();
T& top();
const T& top()const;
size_t size()const;
bool empty()const;
private:
Con _c;
};
}
这些就是模拟实现stack的接口,其中对于构造函数stack()我们可以不写,因为我们是利用deque来实现stack,deque并不是内置类型,在初始化时会自动调用自己的构造函数,所以并不需要我们自己写stack的构造函数。
这里为了区分库里的stack,我们使用命名空间bit来进行区分。
2.2 模拟实现push
void push(const T& x)
{
_c.push_back(x);
}
模拟实现插入十分简单,我们只需将数据尾插到容器中即可,我们只需将容器的尾部当成栈顶即可。
2.3 模拟实现pop
void pop()
{
_c.pop_back();
}
栈实在栈顶进行插入和删除,我们将容器尾部当成栈顶,所以删除只需对容器进行尾删即可。
2.4 模拟实现top
T& top()
{
return _c.back();
}
const T& top()const
{
return _c.back();
}
top返回的是栈顶的元素,我们只需返回容器尾部的数据即可。
2.5 模拟实现size和empty
size_t size()const
{
return _c.size();
}
bool empty()const
{
return _c.empty();
}
模拟实现size和empty我们一样可以利用deque容器的函数,返回容器内部的数据个数和容器是否为空即可。
2.6 测试结果
上面的图片分别对push、pop、size和empty进行了测试,结果都是正确的,说明stack的实现没有问题。
2.7 模拟实现stack完整代码
stack.h文件:
#pragma once
#include<iostream>
#include<deque>
using namespace std;
namespace bit
{
template<class T, class Con = deque<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:
Con _c;
};
void test_stack1()
{
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
st.push(4);
cout << st.top() << endl;
st.pop();
cout << st.top() << endl;
}
void test_stack2()
{
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
st.push(4);
cout << st.size() << endl;
st.pop();
st.pop();
cout << st.size() << endl;
cout << st.empty() << endl;
}
};
test.cpp文件:
#include"Stack.h"
int main()
{
//bit::test_stack1();
bit::test_stack2();
return 0;
}
三、模拟实现queue
2.1 模拟实现queue的接口
namespace bit
{
template<class T, class Con = deque<T>>
class queue
{
public:
queue();
void push(const T& x);
void pop();
T& back();
const T& back()const;
T& front();
const T& front()const;
size_t size()const;
bool empty()const;
private:
Con _c;
};
}
这些就是模拟实现queue的接口,同样的,对于构造函数queue()我们可以不写,同样使用命名空间bit来对库里面的queue进行区分。
2.2 模拟实现push
void push(const T& x)
{
_c.push_back(x);
}
模拟实现push,同样只需要进行尾插,容器尾部即是队尾。
2.3 模拟实现pop
void pop()
{
_c.pop_front();
}
队列是队尾入数据,队头出数据,容器的头部即是队头,所以我们删除要对容器进行头删。
2.4 模拟实现back
T& back()
{
return _c.back();
}
const T& back()const
{
return _c.back();
}
back返回的是队尾的数据,所以我们只需返回容器尾部的数据即可。
2.5 模拟实现front
T& front()
{
return _c.front();
}
const T& front()const
{
return _c.front();
}
同样的,返回队头的数据我们只需返回容器头部的数据即可。
2.6 模拟实现size和empty
size_t size()const
{
return _c.size();
}
bool empty()const
{
return _c.empty();
}
同样,返回数据个数和是否为空只需返回容器中的数据个数和容器是否为空即可。
2.7 测试结果
上面的图片分别对push、pop、front、back、size和empty进行了测试,结果都是正确的,说明queue的实现没有问题。
2.8 模拟实现queue完整代码
Queue.h文件:
#pragma once
#include<iostream>
#include<queue>
using namespace std;
namespace bit
{
template<class T, class Con = deque<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:
Con _c;
};
void test_queue1()
{
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
q.push(4);
cout << q.front() << endl;
cout << q.back() << endl;
q.pop();
cout << q.front() << endl;
cout << q.back() << endl;
}
void test_queue2()
{
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
q.push(4);
cout << q.size() << endl;
q.pop();
cout << q.size() << endl;
cout << q.empty() << endl;
}
}
test.cpp文件:
#include"Queue.h"
int main()
{
//bit::test_queue1();
bit::test_queue2();
return 0;
}
四、 总结
以上就是模拟实现stack和queue的全部内容了,希望以上所讲能够对你有所帮助,有所帮助的话记得一键三连哦,感谢各位。