预备知识(可以不看):
无向图可以理解为是特殊的有向图
1. 图的遍历(因为树可以理解为是特殊的图,因此这里不考虑树的遍历,只考虑图的遍历)
给定一个具体的图,便于分析
下面是树的结构
1:->4->7->2
2:->5->8->1
3:->9->4
4:->6->3->1
5:->2
6:->4
7:->1
8:->2
9:->3
(1)图的建立
const int N;
const int M = 2*N;
int e[M];//e[M]数组中存储的是结点的值(也可以理解为结点的编号)
//这里的e[M]数组之所以用M,而不是N,是因为这是无向图,
//每个结点所连的结点编号会有重复
int ne[M];//ne[M]存储的是下标为 i 的结点的下一个节点的下标
//用M同样是因为无向图,无向图可以理解为是双向图
int h[N];//h[N]存储的是编号为 i 的结点的下一个结点的下标
int idx = 0;//idx表示要插入的点的下标
bool st[N];//用来判断编号为 i 的结点是否被搜索过
void add(int a,int b)//表示在编号为 a 的结点后面插入一个编号为 b 的结点
//这里的 a 和 b 代表结点的编号
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx;
idx++;
}
int main()
{
cin >> n;
memset(h,-1,sizeof(h));//此时还没有加入任何元素,也没有创建任何一条边
//则 h[N] 中任意编号的结点都只是指向-1
//接下来题目会输入n-1行数据
//因为对于有n个结点的树,必定是n-1条边
for (int i = 0;i<n-1;++i)
{
int a,b;
cin >> a >> b;
add(a,b);
add(b,a);//因为是无向图,即双向图,两个结点互相指向,所以要创建两条反向的有指向的边
//以达到无指向的边
}
return 0;
}
在图中表示一下插入的过程
(2)深度优先搜索
void dfs(int u )
{
st[u] = true;//首先标记编号 u 结点已经被搜索过了
for (int i = h[u];i!=-1;i = ne[i])
{
int j = e[i];
if (!st[j])
dfs(j);
}
}