数据结构
0、vector
理解为动态数组,作为一个动态数组,vector 有一个指针指向一片连续的内存空间,但是这片空间不是无限的,当内存装不下数据时,系统会自动申请一片更大的空间把原来的数据拷贝过去,释放原来的内存空间。 vector 的内存非常重要,一旦内存重新配置,与之相关的所有指针、迭代器都会失效,而且配置内存非常耗时。
一、queue ,deque(双端队列)
#include<queue>即可使用队列类:
(1). push
(2). pop
(3). size
(4). empty() //判断队列是否为空的,如果为空则返回true
(5). front
(6). back
二、stack:#include<stack>头文件;
1.入栈:如s.push(x);
2.出栈:如 s.pop().注意:出栈操作只是删除栈顶的元素,并不返回该元素。
3.访问栈顶:如s.top();
4.判断栈空:如s.empty().当栈空时返回true。
5.访问栈中的元素个数,如s.size();
三、string:
string &insert(int p,const string &s); //在p位置插入字符串s
string &replace(int p, int n,const char *s); //删除从p开始的n个字符,然后在p处插入串s
string &erase(int p, int n); //删除p开始的n个字符,返回修改后的字符串
string substr(int pos = 0,int n = npos) const; //返回pos开始的n个字符组成的字符串 void swap(string &s2); //交换当前字符串与s2的值
string &append(const char *s); //把字符串s连接到当前字符串结尾
void push_back(char c) //当前字符串尾部加一个字符c
const char *data()const; //返回一个非null终止的c字符数组,data():与c_str()类似,用于string转const char*其中它返回的数组是不以空字符终止,
const char *c_str()const; //返回一个以null终止的c字符串,即c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同,用于string转const char*
四、List:List是stl实现的双向链表,与向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢。
Lst1.assign() 给list赋值
Lst1.back() 返回最后一个元素
Lst1.begin() 返回指向第一个元素的迭代器
Lst1.clear() 删除所有元素
Lst1.empty() 如果list是空的则返回true
Lst1.end() 返回末尾的迭代器
Lst1.erase() 删除一个元素
Lst1.front() 返回第一个元素
Lst1.get_allocator() 返回list的配置器
Lst1.insert() 插入一个元素到list中
Lst1.max_size() 返回list能容纳的最大元素数量
Lst1.merge() 合并两个list
Lst1.pop_back() 删除最后一个元素
Lst1.pop_front() 删除第一个元素
Lst1.push_back() 在list的末尾添加一个元素
Lst1.push_front() 在list的头部添加一个元素
Lst1.rbegin() 返回指向第一个元素的逆向迭代器
Lst1.remove() 从list删除元素
Lst1.remove_if() 按指定条件删除元素
Lst1.rend() 指向list末尾的逆向迭代器
Lst1.resize() 改变list的大小
Lst1.reverse() 把list的元素倒转
Lst1.size() 返回list中的元素个数
Lst1.sort() 给list排序
Lst1.splice() 合并两个list
Lst1.swap() 交换两个list
Lst1.unique() 删除list中重复的元素
五、Array
at() | Access element |
front() | Access first element |
back() | Access last element |
六、Binary tree
1、二叉树分类:
满二叉树:从高到低,除了叶节点外,所以节点左右节点都存在。
完全二叉树:比满二叉树少几个叶节点,从左向右放子节点。
平衡二叉树(AVL):空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树也都是平衡树。
二叉搜索/查找/排序(sort)树:空树或者二叉树的所有节点比他的左子节点大,比他的右子节点小。
线索二叉树:在节点的结构中增加了两个数据标志位:int itag ,rtag
最优二叉树/哈夫曼树(Huffman Tree):若带权路径(WPL = W*L)长度达到最小,称这样的二叉树为最优二叉树;
红黑树(平衡二叉搜索树):不仅是具有二叉搜索树的属性,还具有平衡树的属性,有序且子树差不超过1,颜色规则:根节点和特殊节点(即叶节点下面两个虚无的节点和未填写的节点)是黑的,红节点的左右子节点是黑的,最重要的是对于每个节点,从该节点到子孙叶节点的所有路径包含相同数目的黑节点。
七、图 Graph
图的存储结构主要分两种,一种是邻接矩阵(顺序存储结构),一种是邻接表(链式存储结构)。
1.邻接矩阵
邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边。
从这个矩阵中,很容易知道图中包含的信息:
(1)要判断任意两顶点是否有边无边就很容易了;
(2)要知道某个顶点的度,其实就是这个顶点vi在邻接矩阵中第i行或(第i列)的元素之和;
(3)求顶点vi的所有邻接点就是将矩阵中第i行元素扫描一遍,arc[i][j]为1就是邻接点;
2. 邻接表
邻接矩阵是不错的一种图存储结构,但是,对于边数相对顶点较少的图,这种结构存在对存储空间的极大浪费。因此,找到一
种数组与链表相结合的存储方法称为邻接表。
(1)图中顶点用一个一维数组存储,也可以用单链表来存储,不过,数组可以较容易的读取顶点的信息,更加方便。
(2)图中每个顶点vi的所有邻接点构成一个线性表,由于邻接点的个数不定,所以,用单链表存储,无向图称为顶点vi的边表,有向图则称为顶点vi作为弧尾的出边表。
从图中可以看出,顶点表的各个结点由data和firstedge两个域表示,data是数据域,存储顶点的信息,firstedge是指针域,指向边表的第一个结点,即此顶点的第一个邻接点。
边表结点由adjvex和next两个域组成。adjvex是邻接点域,存储某顶点的邻接点在顶点表中的下标,next则存储指向边表中下一个结点的指针。
3、根据搜索路径的不同,我们可以将遍历图的方法分为两种:广度优先搜索和深度优先搜索。
https://blog.csdn.net/weixin_40953222/article/details/80544928
广度优先搜索类似于树的层次遍历过程,需要借助一个队列来实现。
搜索过程如下:
(1).准备工作:创建一个visited数组,用来记录已被访问过的顶点;创建一个队列,用来存放每一层的顶点;初始化图G。
(2).从图中的v0开始访问,将的visited[v0]数组的值设置为true,同时将v0入队。
(3).只要队列不空,则重复如下操作: (1)队头顶点u出队。 (2)依次检查u的所有邻接顶点w,若visited[w]的值为false,则访问w,并将visited[w]置为true,同时将w入队。
3.2、深度优先搜索
深度优先搜索类似于树的先序遍历。
搜索过程:创建一个visited数组,用于记录所有被访问过的顶点。
八、HashTable
建立Hash 函数,
处理冲突的方法:链地址法,将每个hash地址作为一个指针,指向一个链表。
九、C++ 的容器类型可以分为顺序容器和关联容器两大类。顺序容器我们前面的使用已经介绍了 vector、list 和 deque;
关联容器支持通过键值来高效的查找和读取元素,这是它和顺序容器最大的区别。两种基本的关联容器类型是 map 和 set,衍生类型有 multimap 和 multiset。
Map 是 STL 的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字 key 只能在map中出现一次,第二个可能称为该关键字的值data)的数据处理能力,由于这个特性,它完全有可能在我们处理一对一数据的时候,在编程上提供快速通道。
十、排序算法:
每个算法用一句话总结:
1、冒泡排序:
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
- 针对所有的元素重复以上的步骤,除了最后一个 :len - 1 - i ;
for (var i = 0; i < len - 1; i++) {
for (var j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j+1]) { // 相邻元素两两对比
var temp = arr[j+1]; // 元素交换
arr[j+1] = arr[j];
arr[j] = temp;
} } }
2、选择排序(Selection Sort)
工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。设置一个最小下标 :
minIndex = i;
for (var i = 0; i < len - 1; i++) {
minIndex = i;
for (var j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) { // 寻找最小的数
minIndex = j; // 将最小数的索引保存
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
3、
插入排序(Insertion Sort)
工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
4、希尔排序(Shell Sort)
是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。
5、归并排序(Merge Sort)
采用分治法(Divide and Conquer)。长度为n的输入序列分成两个长度为n/2的子序列;对这两个子序列分别采用归并排序;对这两个子序列分别采用归并排序;
6、快速排序(Quick Sort)
使用分治法来把一个串(list)分为两个子串(sub-lists),使用分治法来把一个串(list)分为两个子串(sub-lists)。
7、堆排序(Heap Sort)
堆排序(Heapsort)指利用堆这种数据结构所设计的一种排序算法。
8、计数排序(Counting Sort)
计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。
9、桶排序(Bucket Sort)
桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序。
10、基数排序(Radix Sort)