这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记.
什么是数据结构?
- 数据结构是计算机存储、组织数据的方式
链表与邻接表
拿数组模拟
1、 单链表 用的最多的是邻接表,最主要的应用是存储图、树,空集的下标-1
#include <iostream>
using namespace std;
const int N = 100010;
//head表示头节点的下标
//e[i]表示节点i的值
//ne[i]表示节点i的next指针是多少
//idx存储当前已经用到了哪个点
int head, e[N], ne[N], idx;
//初始化
void init()
{
head = -1;
idx = 0;
}
//在头节点添加
void add_to_head(int x)
{
e[idx] = x;
ne[idx] = head;
head = idx;
idx ++;
}
//添加到第k个节点的后面
void add(int k, int x)
{
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx;
idx ++;
}
//将下标是k的节点后面的点删掉
void remove(int k)
{
ne[k] = ne[ne[k]];
}
int main()
{
}
2、 双链表 用于优化某些问题
#include <iostream>
using namespace std;
const int N = 100010;
int e[N], r[N], l[N], idx;
void init()
{
r[0] = 1;
l[1] = 0;
idx = 2;
}
void add(int k, int x)
{
e[idx] = x;
r[idx] = r[k];
l[idx] = k;
r[k] = idx;
l[r[k]] = idx;
idx ++;
}
void remove(int k)
{
r[k-1] = k + 1;
l[k+1] = k - 1;
}
树形结构, 树
二叉树的遍历
- 遍历是数据结构中的常见操作, 把所有元素都访问一遍
- 线性结构的遍历比较简单, 正序遍历/逆序遍历
- 根据节点访问顺序的也不同, 二叉树的常见遍历方式有四种
-
- 前序遍历
-
- 中序遍历
-
- 后序遍历
-
- 层序遍历
hash(散列表)
- 1-10 找到7, 遍历
- 二分法 减少了时间复杂度
- 一次到位, 直接通过key找到value, 字典的底层就是hash 哈希函数:f
- 1 - key - f(key) -> index=1
- 哈希 把值1放到index=1的位置, 11 12 13 15 18
- 浪费资源, 哈希函数没有设计好
- f(key) = key - 10 = index 定义域key > 10
- 计算简单 + 分布均匀, 直接地址法, 数据分析法,
- 平方取中法(增大落差范围, 导致冲突降低), 哈希冲突
- 取余法
-
- 9 13 14 15 16 18 % 10
-
- 9 3 4 5 6 8 数据分析 - 位运算 - index - 取值 设计出一个合理的, 分布均匀的哈希函数(散列函数)很难