|
|
@ -1,173 +1,218 @@
|
|
|
|
#ifndef MYTINYSTL_STACK_H_
|
|
|
|
#ifndef MYTINYSTL_STACK_H_ // 预处理指令,防止头文件被重复包含
|
|
|
|
#define MYTINYSTL_STACK_H_
|
|
|
|
#define MYTINYSTL_STACK_H_
|
|
|
|
//这是个头文件
|
|
|
|
|
|
|
|
// 这个头文件包含了一个模板类 stack
|
|
|
|
// 这个头文件包含了一个模板类 stack
|
|
|
|
// stack : 栈
|
|
|
|
// stack : 栈
|
|
|
|
|
|
|
|
|
|
|
|
#include "deque.h"
|
|
|
|
#include "deque.h" // 包含 deque 类的头文件
|
|
|
|
|
|
|
|
|
|
|
|
namespace mystl
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模板类 stack
|
|
|
|
namespace mystl // 命名空间 mystl,用于封装 mystl 库的组件
|
|
|
|
// 参数一代表数据类型,参数二代表底层容器类型,缺省使用 mystl::deque 作为底层容器
|
|
|
|
|
|
|
|
template <class T, class Container = mystl::deque<T>>
|
|
|
|
|
|
|
|
class stack
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef Container container_type;
|
|
|
|
|
|
|
|
// 使用底层容器的型别
|
|
|
|
|
|
|
|
typedef typename Container::value_type value_type;
|
|
|
|
|
|
|
|
typedef typename Container::size_type size_type;
|
|
|
|
|
|
|
|
typedef typename Container::reference reference;
|
|
|
|
|
|
|
|
typedef typename Container::const_reference const_reference;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static_assert(std::is_same<T, value_type>::value,
|
|
|
|
|
|
|
|
"the value_type of Container should be same with T");
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
container_type c_; // 用底层容器表现 stack
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
// 构造、复制、移动函数
|
|
|
|
|
|
|
|
stack() = default;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
explicit stack(size_type n)
|
|
|
|
|
|
|
|
:c_(n)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
stack(size_type n, const value_type& value)
|
|
|
|
|
|
|
|
:c_(n, value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class IIter>
|
|
|
|
|
|
|
|
stack(IIter first, IIter last)
|
|
|
|
|
|
|
|
: c_(first, last)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack(std::initializer_list<T> ilist)
|
|
|
|
|
|
|
|
:c_(ilist.begin(), ilist.end())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack(const Container& c)
|
|
|
|
|
|
|
|
:c_(c)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
stack(Container&& c) noexcept(std::is_nothrow_move_constructible<Container>::value)
|
|
|
|
|
|
|
|
:c_(mystl::move(c))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack(const stack& rhs)
|
|
|
|
|
|
|
|
:c_(rhs.c_)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
stack(stack&& rhs) noexcept(std::is_nothrow_move_constructible<Container>::value)
|
|
|
|
|
|
|
|
:c_(mystl::move(rhs.c_))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack& operator=(const stack& rhs)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_ = rhs.c_;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
stack& operator=(stack&& rhs) noexcept(std::is_nothrow_move_assignable<Container>::value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_ = mystl::move(rhs.c_);
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack& operator=(std::initializer_list<T> ilist)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_ = ilist;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
~stack() = default;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 访问元素相关操作
|
|
|
|
|
|
|
|
reference top() { return c_.back(); }
|
|
|
|
|
|
|
|
const_reference top() const { return c_.back(); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 容量相关操作
|
|
|
|
|
|
|
|
bool empty() const noexcept { return c_.empty(); }
|
|
|
|
|
|
|
|
size_type size() const noexcept { return c_.size(); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 修改容器相关操作
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class... Args>
|
|
|
|
|
|
|
|
void emplace(Args&& ...args)
|
|
|
|
|
|
|
|
{ c_.emplace_back(mystl::forward<Args>(args)...); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void push(const value_type& value)
|
|
|
|
|
|
|
|
{ c_.push_back(value); }
|
|
|
|
|
|
|
|
void push(value_type&& value)
|
|
|
|
|
|
|
|
{ c_.push_back(mystl::move(value)); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void pop()
|
|
|
|
|
|
|
|
{ c_.pop_back(); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void clear()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
while (!empty())
|
|
|
|
|
|
|
|
pop();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void swap(stack& rhs) noexcept(noexcept(mystl::swap(c_, rhs.c_)))
|
|
|
|
|
|
|
|
{ mystl::swap(c_, rhs.c_); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
friend bool operator==(const stack& lhs, const stack& rhs) { return lhs.c_ == rhs.c_; }
|
|
|
|
|
|
|
|
friend bool operator< (const stack& lhs, const stack& rhs) { return lhs.c_ < rhs.c_; }
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 重载比较操作符
|
|
|
|
|
|
|
|
template <class T, class Container>
|
|
|
|
|
|
|
|
bool operator==(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return lhs == rhs;
|
|
|
|
// 模板类 stack
|
|
|
|
}
|
|
|
|
// 参数一代表数据类型,参数二代表底层容器类型,缺省使用 mystl::deque 作为底层容器
|
|
|
|
|
|
|
|
template <class T, class Container = mystl::deque<T>>
|
|
|
|
template <class T, class Container>
|
|
|
|
class stack
|
|
|
|
bool operator<(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
return lhs < rhs;
|
|
|
|
typedef Container container_type; // 使用底层容器的型别
|
|
|
|
}
|
|
|
|
typedef typename Container::value_type value_type; // 值类型
|
|
|
|
|
|
|
|
typedef typename Container::size_type size_type; // 大小类型
|
|
|
|
|
|
|
|
typedef typename Container::reference reference; // 引用类型
|
|
|
|
|
|
|
|
typedef typename Container::const_reference const_reference; // 常量引用类型
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static_assert(std::is_same<T, value_type>::value, // 静态断言,确保 T 和 value_type 是相同的类型
|
|
|
|
|
|
|
|
"the value_type of Container should be same with T");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
container_type c_; // 用底层容器表现 stack
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
// 构造、复制、移动函数
|
|
|
|
|
|
|
|
stack() = default; // 默认构造函数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
explicit stack(size_type n) // 构造函数,初始化指定数量的元素
|
|
|
|
|
|
|
|
:c_(n)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
stack(size_type n, const value_type& value) // 构造函数,初始化指定数量的相同元素
|
|
|
|
|
|
|
|
:c_(n, value)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class IIter>
|
|
|
|
|
|
|
|
stack(IIter first, IIter last) // 构造函数,使用迭代器范围初始化
|
|
|
|
|
|
|
|
: c_(first, last)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack(std::initializer_list<T> ilist) // 构造函数,使用初始化列表初始化
|
|
|
|
|
|
|
|
:c_(ilist.begin(), ilist.end())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack(const Container& c) // 构造函数,使用底层容器初始化
|
|
|
|
|
|
|
|
:c_(c)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
stack(Container&& c) noexcept(std::is_nothrow_move_constructible<Container>::value) // 移动构造函数
|
|
|
|
|
|
|
|
:c_(mystl::move(c))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack(const stack& rhs) // 复制构造函数
|
|
|
|
|
|
|
|
:c_(rhs.c_)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
stack(stack&& rhs) noexcept(std::is_nothrow_move_constructible<Container>::value) // 移动构造函数
|
|
|
|
|
|
|
|
:c_(mystl::move(rhs.c_))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack& operator=(const stack& rhs) // 复制赋值运算符
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_ = rhs.c_;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
stack& operator=(stack&& rhs) noexcept(std::is_nothrow_move_assignable<Container>::value) // 移动赋值运算符
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_ = mystl::move(rhs.c_);
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack& operator=(std::initializer_list<T> ilist) // 初始化列表赋值运算符
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_ = ilist;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
~stack() = default; // 默认析构函数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 访问元素相关操作
|
|
|
|
|
|
|
|
reference top() { return c_.back(); } // 返回栈顶元素的引用
|
|
|
|
|
|
|
|
const_reference top() const { return c_.back(); } // 返回栈顶元素的常量引用
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 容量相关操作
|
|
|
|
|
|
|
|
bool empty() const noexcept { return c_.empty(); } // 检查栈是否为空
|
|
|
|
|
|
|
|
size_type size() const noexcept { return c_.size(); } // 返回栈的大小
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 修改容器相关操作
|
|
|
|
|
|
|
|
template <class... Args>
|
|
|
|
|
|
|
|
void emplace(Args&& ...args) // 原地构造并添加元素到栈顶
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_.emplace_back(mystl::forward<Args>(args)...);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void push(const value_type& value) // 将元素添加到栈顶
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_.push_back(value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void push(value_type&& value) // 将移动构造的元素添加到栈顶
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_.push_back(mystl::move(value));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void pop() // 移除栈顶元素
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c_.pop_back();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void clear() // 清空栈
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
while (!empty())
|
|
|
|
|
|
|
|
pop();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void swap(stack& rhs) noexcept(noexcept(mystl::swap(c_, rhs.c_))) // 交换两个栈的内容
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
mystl::swap(c_, rhs.c_);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
friend bool operator==(const stack& lhs, const stack& rhs) { return lhs.c_ == rhs.c_; } // 比较运算符,检查两个栈是否相等
|
|
|
|
|
|
|
|
friend bool operator< (const stack& lhs, const stack& rhs) { return lhs.c_ < rhs.c_; } // 比较运算符,检查一个栈是否小于另一个栈
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 重载比较操作符
|
|
|
|
|
|
|
|
template <class T, class Container>
|
|
|
|
|
|
|
|
bool operator==(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return lhs == rhs;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class T, class Container>
|
|
|
|
|
|
|
|
bool operator<(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return lhs < rhs;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class T, class Container>
|
|
|
|
|
|
|
|
bool operator!=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return !(lhs == rhs);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class T, class Container>
|
|
|
|
|
|
|
|
bool operator>(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return rhs < lhs;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class T, class Container>
|
|
|
|
|
|
|
|
bool operator<=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return !(rhs < lhs);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class T, class Container>
|
|
|
|
|
|
|
|
bool operator>=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return !(lhs < rhs);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 重载 mystl 的 swap
|
|
|
|
|
|
|
|
template <class T, class Container>
|
|
|
|
|
|
|
|
void swap(stack<T, Container>& lhs, stack<T, Container>& rhs) noexcept(noexcept(lhs.swap(rhs)))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lhs.swap(rhs);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace mystl
|
|
|
|
|
|
|
|
#endif // !MYTINYSTL_STACK_H_
|
|
|
|
|
|
|
|
// 比较运算符,检查两个栈是否不相等
|
|
|
|
template <class T, class Container>
|
|
|
|
template <class T, class Container>
|
|
|
|
bool operator!=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
bool operator!=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return !(lhs == rhs);
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 比较运算符,检查一个栈是否大于另一个栈
|
|
|
|
template <class T, class Container>
|
|
|
|
template <class T, class Container>
|
|
|
|
bool operator>(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
bool operator>(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return rhs < lhs;
|
|
|
|
return rhs < lhs; // 如果rhs小于lhs,则lhs大于rhs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 比较运算符,检查一个栈是否小于或等于另一个栈
|
|
|
|
template <class T, class Container>
|
|
|
|
template <class T, class Container>
|
|
|
|
bool operator<=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
bool operator<=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return !(rhs < lhs);
|
|
|
|
return !(rhs < lhs); // 如果rhs不小于lhs,则lhs小于或等于rhs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 比较运算符,检查一个栈是否大于或等于另一个栈
|
|
|
|
template <class T, class Container>
|
|
|
|
template <class T, class Container>
|
|
|
|
bool operator>=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
bool operator>=(const stack<T, Container>& lhs, const stack<T, Container>& rhs)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return !(lhs < rhs);
|
|
|
|
return !(lhs < rhs); // 如果lhs不小于rhs,则lhs大于或等于rhs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 重载 mystl 的 swap
|
|
|
|
// 重载 mystl 的 swap 函数,用于交换两个 stack 对象的内容
|
|
|
|
|
|
|
|
// 这个函数是友元函数,因为它需要访问 stack 的私有成员
|
|
|
|
template <class T, class Container>
|
|
|
|
template <class T, class Container>
|
|
|
|
void swap(stack<T, Container>& lhs, stack<T, Container>& rhs) noexcept(noexcept(lhs.swap(rhs)))
|
|
|
|
void swap(stack<T, Container>& lhs, stack<T, Container>& rhs) noexcept(noexcept(lhs.swap(rhs)))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
lhs.swap(rhs);
|
|
|
|
lhs.swap(rhs); // 调用 stack 类的 swap 方法
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace mystl
|
|
|
|
} // namespace mystl 结束命名空间
|
|
|
|
#endif // !MYTINYSTL_STACK_H_
|
|
|
|
#endif // !MYTINYSTL_STACK_H_ 结束头文件保护宏定义
|
|
|
|
|
|
|
|
|