#ifndef MY_DEQUE_H #define MY_DEQUE_H #include "container.h" #include #include template class MyDeque : public Container { private: static const size_t CHUNK_SIZE = 8; // 每个块的大小 T** map; // 中控器 size_t map_capacity; // 中控器容量 size_t start_chunk; // 起始块索引 size_t start_pos; // 起始块中的位置 size_t size_; void initialize_map(size_t n) { map_capacity = std::max(size_t(8), n / CHUNK_SIZE + 1); map = new T*[map_capacity]; for (size_t i = 0; i < map_capacity; i++) { map[i] = new T[CHUNK_SIZE]; } start_chunk = map_capacity / 2; start_pos = CHUNK_SIZE / 2; size_ = 0; } void ensure_capacity(size_t needed_chunks) { if (needed_chunks > map_capacity) { size_t new_capacity = map_capacity * 2; T** new_map = new T*[new_capacity]; size_t new_start = (new_capacity - needed_chunks) / 2; for (size_t i = 0; i < map_capacity; i++) { new_map[new_start + i] = map[i]; } for (size_t i = 0; i < new_start; i++) { new_map[i] = new T[CHUNK_SIZE]; } for (size_t i = new_start + map_capacity; i < new_capacity; i++) { new_map[i] = new T[CHUNK_SIZE]; } delete[] map; map = new_map; start_chunk = new_start; map_capacity = new_capacity; } else if (needed_chunks < map_capacity / 4 && needed_chunks >= 0) { size_t new_capacity = map_capacity / 2; T** new_map = new T*[new_capacity]; size_t new_start = (new_capacity - needed_chunks) / 2; for (size_t i = 0; i < needed_chunks; i++) { new_map[new_start + i] = map[start_chunk + i]; } for(size_t i = 0; i < new_start; i++) { new_map[i] = new T[CHUNK_SIZE]; } for (size_t i = new_start + needed_chunks; i < new_capacity; i++) { new_map[i] = new T[CHUNK_SIZE]; } for(size_t i = 0; i < start_chunk; i++) { delete[] map[i]; } for(size_t i = start_chunk + needed_chunks; i < map_capacity; i++) { delete[] map[i]; } delete[] map; map = new_map; start_chunk = new_start; map_capacity = new_capacity; } } public: MyDeque() { initialize_map(0); } ~MyDeque() { for (size_t i = 0; i < map_capacity; i++) { delete[] map[i]; } delete[] map; } void push_back(const T& value) { size_t end_chunk = (start_chunk + (start_pos + size_) / CHUNK_SIZE); size_t end_pos = (start_pos + size_) % CHUNK_SIZE; if (end_chunk >= map_capacity) { ensure_capacity(end_chunk + 1); end_chunk = (start_chunk + (start_pos + size_) / CHUNK_SIZE); end_pos = (start_pos + size_) % CHUNK_SIZE; } map[end_chunk][end_pos] = value; size_++; } T& back() { if (empty()) { throw std::out_of_range("back of empty deque"); } size_t end_chunk = (start_chunk + (start_pos + size_ - 1) / CHUNK_SIZE); size_t end_pos = (start_pos + size_ - 1) % CHUNK_SIZE; return map[end_chunk][end_pos]; } const T& back() const { if (empty()) { throw std::out_of_range("back of empty deque"); } size_t end_chunk = (start_chunk + (start_pos + size_ - 1) / CHUNK_SIZE); size_t end_pos = (start_pos + size_ - 1) % CHUNK_SIZE; return map[end_chunk][end_pos]; } void pop_back() { if (empty()) { throw std::out_of_range("pop_back from empty deque"); } size_--; if((start_pos + size_ ) / CHUNK_SIZE + 1< map_capacity / 4) { ensure_capacity((start_pos + size_) / CHUNK_SIZE + 1); } } void push_front(const T& value) { if (start_pos == 0) { if (start_chunk == 0) { ensure_capacity(map_capacity + 1); } start_chunk--; start_pos = CHUNK_SIZE; } start_pos--; map[start_chunk][start_pos] = value; size_++; } T& front() { if (empty()) { throw std::out_of_range("front of empty deque"); } return map[start_chunk][start_pos]; } const T& front() const { if (empty()) { throw std::out_of_range("front of empty deque"); } return map[start_chunk][start_pos]; } void pop_front() { if (empty()) { throw std::out_of_range("pop_front from empty deque"); } start_pos++; if (start_pos == CHUNK_SIZE) { start_chunk++; start_pos = 0; } size_--; if((start_pos + size_ ) / CHUNK_SIZE + 1< map_capacity / 4) { ensure_capacity((start_pos + size_) / CHUNK_SIZE + 1); } } T& operator[](size_t n) { size_t chunk = start_chunk + (start_pos + n) / CHUNK_SIZE; size_t pos = (start_pos + n) % CHUNK_SIZE; return map[chunk][pos]; } void push(const T& value) override { push_front(value); } void pop() override { pop_front(); } T& top() override { return front(); } const T& top() const override { return front(); } bool empty() const override { return size_ == 0; } size_t size() const override { return size_; } void clear() override { while(!empty()) pop(); } }; #endif