【C++/STL序列式容器】


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值