list【链表】
链表低层实现是一个双向链表。如图,结构较为简单,不再赘述。。
vector【数组】
低层是一个数组,但是空间是动态调整的,比静态空间的array更灵活。
vector会申请比实际存储更大的空间(未雨绸缪。。),当增加元素超过容量则扩充1倍的容量,仍然不足就继续1倍1倍的增加容量。
迭代器:扩容以原大小2倍另外配置一块较大空间,非原来的内存空间,因此指向原来vecotr的迭代器都失效。
priority_queue【堆】
用list实现?插入O(1),找到极值需要O(n)复杂度
用二叉搜索树?插入和找到极值需要O(logn)复杂度,but实现复杂
用二叉堆,复杂度
迭代器:无迭代器
1.插入元素,重点是上浮sift_up操作
2.移除元素,重点是下潜sift_down操作
3.建堆,重点是下潜sift_down操作
4.堆排序,建堆后,每次将堆顶元素和尾部元素交换,然后将堆顶元素下潜sift_down操作,则程序执行完后,即可得到一个递增数组
代码如下
class heapOp {
public:
static void buildheap(vector<int>& nums) {
int len = nums.size();
for (int i = (len - 2) / 2; i >= 0; i--) {
sift_down(nums, i, len);
}
}
static void push(vector<int>& nums, int a) {
nums.push_back(a);
sift_up(nums);
}
static void pop(vector<int>& nums) {
int len = nums.size();
pophead(nums, len);
nums.pop_back();
}
static void sortheap(vector<int>& nums) {
buildheap(nums);
for (int i = nums.size(); i > 1; i--) {
pophead(nums, i);
}
}
private:
// 比较函数a<b为大根堆,a>b为小根堆
static bool cmp(int a, int b) {return a < b;}
// 上浮操作
static void sift_up(vector<int>& nums) {
int len = nums.size();
if (len > 1) {
int parent = (len - 2) / 2;
int cur = len - 1;
if (cmp(nums[parent], nums[cur])) {
int temp = nums[cur];
do {
nums[cur] = nums[parent];
cur = parent;
if (cur == 0) break;
parent = (parent - 1) / 2;
} while (cmp(nums[parent], temp));
nums[cur] = temp;
}
}
}
// 下潜操作
static void sift_down(vector<int>& nums, int i, int len) {
if (len < 2 || (len - 2) / 2 < i) return;
int child = 2 * i + 1;
if (child + 1 < len && cmp(nums[child], nums[child + 1])) child++;
if (cmp(nums[i], nums[child])) return;
int temp = nums[i];
do {
nums[i] = nums[child];
i = child;
if ((len - 2) / 2 < i) break;
child = i * 2 + 1;
if (child + 1 < len && cmp(nums[child], nums[child + 1])) child++;
} while (cmp(nums[child], nums[i]));
nums[i] = temp;
}
// 弹出堆顶
static void pophead(vector<int>& nums, int len) {
if (len > 1) {
swap(nums[len - 1], nums[0]);
sift_down(nums, 0, len - 1);
}
}
};
deque【分段连续数组】
相比vector单向开口,deque是双向开口的,即deque首尾增删元素是常数时间,而vector首部增删元素需要O(n)时间。
deque由一段一段的定量连续空间构成,由控制器进行控制
维护三个指针,分别是控制其的map指针、指向第一个缓冲区第一个元素的指针和最后一个缓冲区最后一个元素的(下一个位置)的指针
迭代器:有四个成员cur、first、last、node,以便在不同缓冲区之间进退
queue、stack【deque】
queue先进先出的数据结构
stakc先进后出的数据结构
将deque容器进行适配,关闭某些接口形成queue和stack。
当然,queue和stack低层也可以用list来实现。。
迭代器:无迭代器,严格FIFO或FILO