9.算法与数据结构——C++STL

1.顺序容器

list列表 (基于双向链表,非连续)

某些STL中用的甚至是双向循环链表。既然是基于双向链表显然其不是连续存储的。
所以每个节点不光包括val 值,还有前后两个指针。
list包含了一个指针,重载了运算符,实现迭代器的递增递减与取值操作
list实际上是一个带有头节点的双向循环链表,node指针指向空的头节点
由此begin就是node->next的val
end 就是node本身,因为是循环的
empty判断node->next==node?即可
back就重载–,找到node的上一个节点。

注接下文array:
不确定大小/频繁插入删除用list
大量查找,用array

这样符合我们操作系统里的局部性原理。

array 固定数组,连续存储

用法:

array<种类,数目> name {具体数值初始化};

在这里插入图片描述
因为array容器中新增了类似at()这样的成员函数,其会检查n是否有效,否则抛出异常,所以比普通数组安全。

vector 动态数组(连续空间,基于三个指针)

动态数组,用于 O(1) 的随机读取.
实现原理:
由三个指针实现,
第一个指针指向vector起始位置
第二个指针指向目前有数据的末尾
第三个指针指向整个vector容器所占内存的末尾。
在这里插入图片描述
由此实现:

template<class _Ty,
    class _Ax>
    class vector
        : public _Vector_val<_Ty, _Ax>
    {   // varying size array of values
public:
    /********/
protected:
    pointer _Myfirst;   // pointer to beginning of array
    pointer _Mylast;    // pointer to current end of sequence
    pointer _Myend; // pointer to end of array
    };

由此:
注意:
end 指向第二个指针
size 是2-1 而capacity 是3-1
注意resize的时候,是新在堆中开辟内存,赋值之后删除旧数组

template <class _Ty, class _Alloc = allocator<_Ty>>
class vector{
public:
    iterator begin() {return _Myfirst;}
    iterator end() {return _Mylast;}
    size_type size() const {return size_type(end() - begin());}
    size_type capacity() const {return size_type(_Myend - begin());}
    bool empty() const {return begin() == end();}
    reference operator[] (size_type n) {return *(begin() + n);}
    reference front() { return *begin();}
    reference back() {return *(end()-1);}
    ...
};

详细使用见:
添加链接描述

deque 双端队列 数组挂载小段空间,连接非连续的空间

支持O(1)的随机读取和头部、尾部的频繁增删
在这里插入图片描述
为了管理这些连续空间,deque 容器用数组(数组名假设为 map)存储着各个连续空间的首地址。也就是说,map 数组中存储的都是指针,指向那些真正用来存储数据的各个连续空间

当 deque 容器需要在头部或尾部增加存储空间时,它会申请一段新的连续空间,同时在 map 数组的开头或结尾添加指向该空间的指针,由此该空间就串接到了 deque 容器的头部或尾部。

遍历的时候四个指针,一个头first一个尾last,一个cur,最后一个node指向map数组指针,如果cur遍历到边缘,就用node指针来更新前三个指针。

由这四个指针,维护两个迭代器:一个start记录map数组中首个连续空间的信息,一个finish迭代器记录map数组最后一个连续空间的信息。但是start的cur指向连续空间的第一个数,而finish的cur指向连续空间的最后一个数。
在这里插入图片描述

2.基于上述容器产生的数据结构

stack 栈(基于deque)

默认基于deque实现,后入先出LIFO。
常用于深度优先搜索,字符串匹配等问题。

堆和栈的区别

首先要了解内存分区:

  1. 栈区:由编译器分配释放,存储局部遍历和函数参数等。
  2. 堆区:由程序员分配释放,由malloc和free负责
  3. 自由存储区:可以是堆也可以是静态存储区(取决于operater new的细节实现方式);所以new和delete从自由存储区分配。
  4. 全局/静态区:全局遍历和静态变量。
  5. 常量存储区:存放常量,不允许修改

区别:

  1. 管理方式:堆由程序员控制,容易内存泄漏。而栈由编译器控制。
  2. 申请后相应方式:操作系统有一个记录空闲内存的链表,申请堆时遍历链表,寻找第一个大于需要空间的堆节点,删除该节点分配给程序。而栈只要剩下的空间够申请就一直提供内存,反之则栈溢出。
  3. 申请大小限制:堆是不连续的,理论上看虚拟内存多大就能多大。而栈是连续的,一般是一两M大小
  4. 效率:栈在计算机底层有专门寄存器提供服务,很快。相反堆需要库函数,比较慢。
  5. 碎片:堆频繁new和delete会造成大量碎片,降低程序效率
  6. 生长方向:堆向高地址方向增长,栈向低地址方向

queue 队列(基于deque)

默认基于deque,先入先出FIFO
常用于广度优先搜索

priority_queue(基于vector)

最大值先出的数据结构,默认基于vector实现堆结构。它可以在O(nlogn)的时间排序数组,O(logn) 的时间插入任意值,O(1) 的时间获得最大值,O(logn) 的时间删除最大值。priority_queue 常用于维护数据结构并快速获取最大或最小值。

3.有序数据结构

set 有序集

默认基于红黑树(一种特殊的二叉查找树)。元素不可重复
它可以在 O(nlogn) 的时间排序数组,O(logn) 的时间插入、删除、查找任意值,O(logn) 的时间获得最小或最大值。这里注意,set 和 priority_queue 都可以用于维护数据结构并快速获取最大最小值,但是它们的时间复杂度和功能略有区别,如priority_queue默认不支持删除任意值,而set获得最大或最小值的时间复杂度略高,具体使用哪个根据需求而定。

map 有序表

在set的基础上加上映射关系,使得每个key存一个value值。

4.无序数据结构(对每个有序容器作哈希处理)

unordered_set 哈希集

可以在 O(1) 的时间快速插入、查找、删除元素,常用于快速的查询一个元素是否在这个容器内
如果需要每次判断一个元素在不在一个vector内,我们可以将其转化成一个哈希集:这样就能很快的查找:

unordered_set<int> dict(v.begin(),v.end());
if(v.count(a))
{
...
}

unordered_map 哈希表

在 unordered_set 的基础上加上映射关系,可以对每一个元素 key 存一个值 value。在某些情况下,如果 key 的范围已知且较小,我们也可以用 vector 代替 unordered_map,用位置表示 key,用每个位置的值表示 value
详情见:
添加链接描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
matrix.h: Simple matrix class dsexceptions.h: Simple exception classes Fig01_02.cpp: A simple recursive routine with a test program Fig01_03.cpp: An example of infinite recursion Fig01_04.cpp: Recursive routine to print numbers, with a test program Fig01_05.cpp: Simplest IntCell class, with a test program Fig01_06.cpp: IntCell class with a few extras, with a test program IntCell.h: IntCell class interface (Fig 1.7) IntCell.cpp: IntCell class implementation (Fig 1.8) TestIntCell.cpp: IntCell test program (Fig 1.9) (need to compile IntCell.cpp also) Fig01_10.cpp: Illustration of using the vector class Fig01_11.cpp: Dynamically allocating an IntCell object (lame) BuggyIntCell.cpp: Buggy IntCell class implementation (Figs 1.16 and 1.17) Fig01_18.cpp: IntCell class with pointers and Big Five FindMax.cpp: Function template FindMax (Figs 1.19 and 1.20) Fig01_21.cpp: MemoryCell class template without separation Fig01_25.cpp: Using function objects: Case insensitive string comparison LambdaExample.cpp: (Not in the book): rewriting Fig 1.25 with lambdas MaxSumTest.cpp: Various maximum subsequence sum algorithms Fig02_09.cpp: Test program for binary search Fig02_10.cpp: Euclid's algorithm, with a test program Fig02_11.cpp: Recursive exponentiation algorithm, with a test program RemoveEveryOtherItem.cpp: Remove every other item in a collection Vector.h: Vector class List.h: List class BinarySearchTree.h: Binary search tree TestBinarySearchTree.cpp: Test program for binary search tree AvlTree.h: AVL tree TestAvlTree.cpp: Test program for AVL trees mapDemo.cpp: Map demos WordLadder.cpp: Word Ladder Program and Word Changing Utilities SeparateChaining.h: Header file for separate chaining SeparateChaining.cpp: Implementation for separate chaining TestSeparateChaining.cpp: Test program for separate chaining hash tables (need to compile SeparateChaining.cpp also) QuadraticProbing.h: Header file for quadratic probing hash table QuadraticProbing.cpp: Implementation for quadratic probing hash table TestQuadraticProbing.cpp: Test program for quadratic probing hash tables (need to compile QuadraticProbing.cpp also) CuckooHashTable.h: Header file for cuckoo hash table CuckooHashTable.cpp: Implementation for cuckoo hash table TestCuckooHashTable.cpp: Test program for cuckoo hash tables (need to compile CuckooHashTable.cpp also) CaseInsensitiveHashTable.cpp: Case insensitive hash table from STL (Figure 5.23) BinaryHeap.h: Binary heap TestBinaryHeap.cpp: Test program for binary heaps LeftistHeap.h: Leftist heap TestLeftistHeap.cpp: Test program for leftist heaps BinomialQueue.h: Binomial queue TestBinomialQueue.cpp: Test program for binomial queues TestPQ.cpp: Priority Queue Demo Sort.h: A collection of sorting and selection routines TestSort.cpp: Test program for sorting and selection routines RadixSort.cpp: Radix sorts DisjSets.h: Header file for disjoint sets algorithms DisjSets.cpp: Efficient implementation of disjoint sets algorithm TestFastDisjSets.cpp: Test program for disjoint sets algorithm WordLadder.cpp: Word Ladder Program and Word Changing Utilities Fig10_38.cpp: Simple matrix multiplication algorithm with a test program Fig10_40.cpp: Algorithms to compute Fibonacci numbers Fig10_43.cpp: Inefficient recursive algorithm (see text) Fig10_45.cpp: Better algorithm to replace fig10_43.c (see text) Fig10_46.cpp: Dynamic programming algorithm for optimal chain matrix multiplication, with a test program Fig10_53.cpp: All-pairs algorithm, with a test program Random.h: Header file for random number class Random.cpp: Implementation for random number class TestRandom.cpp: Test program for random number class UniformRandom.h: Random number class using standard library Fig10_63.cpp: Randomized primality testing algorithm, with a test program SplayTree.h: Top-down splay tree TestSplayTree.cpp: Test program for splay trees RedBlackTree.h: Top-down red black tree TestRedBlackTree.cpp: Test program for red black trees Treap.h: Treap TestTreap.cpp: Test program for treap SuffixArray.cpp: Suffix array KdTree.cpp: Implementation and test program for k-d trees PairingHeap.h: Pairing heap TestPairingHeap.cpp: Test program for pairing heaps MemoryCell.h: MemoryCell class interface (Appendix) MemoryCell.cpp: MemoryCell class implementation (Appendix) MemoryCellExpand.cpp: MemoryCell instantiation file (Appendix) TestMemoryCell.cpp: MemoryCell test program (Appendix)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值