这个系列是实现自己的std容器,某些地方进行了简化,但核心原理保留
一.vector
#include<bits/stdc++.h>
using namespace std;
template <typename T>
class MyVector{
private:
T *elements;
size_t capacity;
size_t size;
public:
MyVector():elements(nullptr),capacity(0),size(0) {}
~MyVector(){
delete[] elements;
}
// 拷贝构造函数
MyVector(const MyVector &other) : capacity(other.capacity), size(other.size)
{
elements = new T[capacity];
std::copy(other.elements, other.elements + size, elements);
}
// 拷贝赋值操作符
MyVector &operator=(const MyVector &other)
{
if (this != &other)
{
delete[] elements;
capacity = other.capacity;
size = other.size;
elements = new T[capacity];
std::copy(other.elements, other.elements + size, elements);
}
return *this;
}
void push_back(const T& value){
if(size==capacity){
reserve(capacity==0?1:2*capacity);
}
elements[size] = value;
size++;
}
void pop_back(){
if(size>0){
--size;
}
}
// 获取数组中元素的个数
size_t getSize() const
{
return size;
}
// 获取数组的容量
size_t getCapacity() const
{
return capacity;
}
// 访问数组中的元素
T &operator[](size_t index)
{
// 检查索引是否越界
if (index >= size)
{
throw std::out_of_range("Index out of range");
}
return elements[index];
}
// const版本的访问数组中的元素
const T &operator[](size_t index) const
{
// 检查索引是否越界
if (index >= size)
{
throw std::out_of_range("Index out of range");
}
return elements[index];
}
// 在指定位置插入元素
void insert(size_t index, const T &value)
{
if (index > size)
{
throw std::out_of_range("Index out of range");
}
if (size == capacity)
{
reserve(capacity == 0 ? 1 : capacity * 2);
}
for (size_t i = size; i > index; --i)
{
elements[i] = elements[i - 1];
}
elements[index] = value;
++size;
}
// 清空数组
void clear()
{
size = 0;
}
// 使用迭代器遍历数组的开始位置
T *begin()
{
return elements;
}
// 使用迭代器遍历数组的结束位置
T *end()
{
return elements + size;
}
// 使用迭代器遍历数组的开始位置(const版本)
const T *begin() const
{
return elements;
}
// 使用迭代器遍历数组的结束位置(const版本)
const T *end() const
{
return elements + size;
}
// 打印数组中的元素
void printElements() const
{
for (size_t i = 0; i < size; ++i)
{
std::cout << elements[i] << " ";
}
std::cout << std::endl;
}
private:
void reserve(size_t newCapacity){
if(newCapacity>capacity){
T* newElements = new T[newCapacity];
std::copy(elements,elements+size,newElements);
delete[] elements;
elements = newElements;
capacity = newCapacity;
}
}
};
int main()
{
// 创建一个 Vector 对象
MyVector<int> myVector;
int N;
std::cin >> N;
// 读走回车
getchar();
std::string line;
for (int i = 0; i < N; i++)
{
// 读取整行
std::getline(std::cin, line);
std::istringstream iss(line);
std::string command;
iss >> command;
if (command == "push")
{
int value;
iss >> value;
myVector.push_back(value);
}
else if (command == "print")
{
if (myVector.getSize() == 0) {
std::cout << "empty" << std::endl;
continue;
}
myVector.printElements();
}
else if (command == "size")
{
std::cout << myVector.getSize() << std::endl;
}
else if (command == "get")
{
int index;
iss >> index;
std::cout << myVector[index] << std::endl;
}
else if (command == "insert")
{
int index, value;
iss >> index >> value;
myVector.insert(index, value);
}
else if (command == "pop")
{
myVector.pop_back();
}
else if (command == "iterator")
{
if (myVector.getSize() == 0)
{
std::cout << "empty" << std::endl;
continue;
}
for (auto it = myVector.begin(); it != myVector.end(); ++it)
{
std::cout << *it << " ";
}
std::cout << std::endl;
}
else if (command == "foreach")
{
if (myVector.getSize() == 0)
{
std::cout << "empty" << std::endl;
continue;
}
for (const auto &element : myVector)
{
std::cout << element << " ";
}
std::cout << std::endl;
}
else if (command == "clear")
{
myVector.clear();
}
}
return 0;
}
二.deque
#include <bits/stdc++.h>
using namespace std;
template <typename T>
class Deque {
private:
T* elements; // 就是一个循环一维数组
size_t capacity; // 数组的总容量
size_t frontIndex; // deque的前端索引
size_t backIndex; // deque的后端索引
size_t size; // deque中的元素数量
public:
// 构造函数
Deque() : elements(nullptr), capacity(0), frontIndex(0), backIndex(0), size(0) {}
// 析构函数
~Deque() {
clear();
delete[] elements;
}
// 在deque的前端插入元素
void push_front(const T& value) {
// 检查是否需要扩展数组容量
if (size == capacity) {
resize();
}
// 计算新的前端索引
frontIndex = (frontIndex - 1 + capacity) % capacity;
// 在新的前端位置插入元素
elements[frontIndex] = value;
// 增加deque的元素数量
++size;
}
// 在deque的后端插入元素
void push_back(const T& value) {
// 检查是否需要扩展数组容量
if (size == capacity) {
resize();
}
// 在当前后端位置插入元素
elements[backIndex] = value;
// 计算新的后端索引
backIndex = (backIndex + 1) % capacity;
// 增加deque的元素数量
++size;
}
// 从deque的前端移除元素
void pop_front() {
// 检查deque是否为空
if (size == 0) {
throw std::out_of_range("Deque is empty");
}
// 删除元素不需要显式地删除, 以后新追加元素会自动覆盖
// 计算新的前端索引
frontIndex = (frontIndex + 1) % capacity;
// 减少deque的元素数量
--size;
}
// 从deque的后端移除元素
void pop_back() {
// 检查deque是否为空
if (size == 0) {
throw std::out_of_range("Deque is empty");
}
// 删除元素不需要显式地删除, 以后新追加元素会自动覆盖
// 计算新的后端索引
backIndex = (backIndex - 1 + capacity) % capacity;
// 减少deque的元素数量
--size;
}
// 随机访问元素
T& operator[](int index) {
if (index < 0 || index >= size) {
throw std::out_of_range("Index out of range");
}
return elements[(frontIndex + index) % capacity];
}
// 获取deque中的元素数量
size_t getSize() const {
return size;
}
// 清空deque
void clear() {
while (size > 0) {
pop_front();
}
}
// 打印deque中的元素
void printElements() const {
size_t index = frontIndex;
for (size_t i = 0; i < size; ++i) {
std::cout << elements[index] << " ";
index = (index + 1) % capacity;
}
std::cout << std::endl;
}
private:
// 扩展数组容量
void resize() {
// 计算新的容量
size_t newCapacity = (capacity == 0) ? 1 : capacity * 2;
// 创建新的数组
T* newElements = new T[newCapacity];
// 复制元素到新数组
size_t index = frontIndex;
for (size_t i = 0; i < size; ++i) {
newElements[i] = elements[index];
index = (index + 1) % capacity;
}
// 释放旧数组的内存
delete[] elements;
// 更新成员变量
elements = newElements;
capacity = newCapacity;
frontIndex = 0;
backIndex = size;
}
};
int main() {
// 创建一个 Deque 对象
Deque<int> myDeque;
int N;
std::cin >> N;
// 读走回车
getchar();
std::string line;
// 接收命令
for (int i = 0; i < N; i++) {
std::getline(std::cin, line);
std::istringstream iss(line);
std::string command;
iss >> command;
int value;
if (command == "push_back") {
iss >> value;
myDeque.push_back(value);
}
if (command == "push_front") {
iss >> value;
myDeque.push_front(value);
}
if (command == "pop_back") {
if (myDeque.getSize() == 0) {
continue;
}
myDeque.pop_back();
}
if (command == "pop_front") {
if (myDeque.getSize() == 0) {
continue;
}
myDeque.pop_front();
}
if (command == "clear") {
myDeque.clear();
}
if (command == "size") {
std::cout << myDeque.getSize() << std::endl;
}
if (command == "get") {
iss >> value;
std::cout << myDeque[value] << std::endl;
}
if (command == "print") {
if (myDeque.getSize() == 0) {
std::cout << "empty" << std::endl;
} else {
myDeque.printElements();
}
}
}
return 0;
}
三.stack
注意stack要用到上面的deque,这边就用std原生的deque代替了,当然也可以用别的container模板
#include <bits/stdc++.h>
using namespace std;
template <typename T, typename Container = std::deque<T>>
class MyStack {
private:
Container data; // 使用底层容器存储栈的元素
public:
// 压入元素到栈顶
void push(const T& value) {
data.push_back(value);
}
// 弹出栈顶元素
void pop() {
if (!empty()) {
data.pop_back();
} else {
throw std::runtime_error("Stack is empty.");
}
}
// 返回栈顶元素的引用
T& top() {
if (!empty()) {
return data.back();
} else {
throw std::runtime_error("Stack is empty.");
}
}
// 检查栈是否为空
bool empty() const {
return data.empty();
}
// 返回栈的大小
size_t size() const {
return data.size();
}
};
int main() {
// 使用 std::deque 作为底层容器的示例
MyStack<int, std::deque<int>> stack;
int N;
std::cin >> N;
getchar();
std::string line;
for (int i = 0; i < N; i++) {
std::getline(std::cin, line);
std::istringstream iss(line);
std::string command;
iss >> command;
int element;
if (command == "push") {
iss >> element;
stack.push(element);
}
if (command == "pop") {
try {
stack.pop();
} catch(const std::runtime_error& e) {
// 不做任何处理
continue;
}
}
if (command == "top") {
try {
std::cout << stack.top() << std::endl;
} catch(const std::runtime_error& e) {
std::cout << "null" << std::endl;
}
}
if (command == "size") {
std::cout << stack.size() << std::endl;
}
if (command == "empty") {
std::cout << (stack.empty() ? "true" : "false") << std::endl;
}
}
return 0;
}
二.queue
注意queue要用到上面的deque,这边就用std原生的deque代替了,,当然也可以用别的container模板
#include <bits/stdc++.h>
using namespace std;
template <typename T, typename Container = std::deque<T>>
class MyQueue {
private:
Container data; // 使用底层容器存储队列的元素
public:
// 将元素添加到队尾
void push(const T& value) {
data.push_back(value);
}
// 移除队头元素
void pop() {
if (!empty()) {
data.pop_front();
} else {
throw std::runtime_error("Queue is empty.");
}
}
// 访问队头元素的引用
T& front() {
if (!empty()) {
return data.front();
} else {
throw std::runtime_error("Queue is empty.");
}
}
// 访问队尾元素的引用
T& back() {
if (!empty()) {
return data.back();
} else {
throw std::runtime_error("Queue is empty.");
}
}
// 检查队列是否为空
bool empty() const {
return data.empty();
}
// 返回队列的大小
size_t size() const {
return data.size();
}
};
int main() {
// 使用 std::deque 作为底层容器的示例
MyQueue<int, std::deque<int>> myQueue;
int N;
std::cin >> N;
getchar();
std::string line;
for (int i = 0; i < N; i++) {
std::getline(std::cin, line);
std::istringstream iss(line);
std::string command;
iss >> command;
int element;
if (command == "push") {
iss >> element;
myQueue.push(element);
}
if (command == "pop") {
try {
myQueue.pop();
} catch(const std::runtime_error& e) {
// 不做任何处理
continue;
}
}
if (command == "front") {
try {
std::cout << myQueue.front() << std::endl;
} catch(const std::runtime_error& e) {
std::cout << "null" << std::endl;
}
}
if (command == "back") {
try {
std::cout << myQueue.back() << std::endl;
} catch(const std::runtime_error& e) {
std::cout << "null" << std::endl;
}
}
if (command == "size") {
std::cout << myQueue.size() << std::endl;
}
if (command == "empty") {
std::cout << (myQueue.empty() ? "true" : "false") << std::endl;
}
}
return 0;
}