且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

树的遍历与图的遍历

更新时间:2022-08-18 11:03:18

  研发时候,不要受原来的术语的影响,其实就是想着原来学过的或者看过的可以解决新遇到的问题,这其实是侥幸心理,忘记原来的术语吧,那只是你创新的源泉。

  遍历就是把节点按一定规则构成一个线性序列,不同的规则得到不同顺序的线性序列,仅此而已 。

  算法是实际问题工作步骤的抽象,不要一味想算法,想想实际情况怎么做的,然后提取算法,然后优化。

  不论怎样,要和具体的数据结构结合在一起。

一、树的遍历

  对于树的遍历,有三种,就拿前序遍历来说,得到的序列不论怎么拆分(子串,就是要连续),始
终要是根左右,跟在左右前面,左在右前面,有点DP类似最优子结构。

//中序 LDR
if(null)
{
    return ;
}
else
{
    //分别输出左 根  右      
}

  无论前中后都是dfs,不过树的话,由于有了明确的children字段,不需要设置vis数组来确保只遍历一次,因为肯定知识便利了一次。

travel(node)
{
    for(i=1:lengh)
    {
        //.....处理node节点    
      if(null!=children)
          travel(children);
    }
}
另一种写法是把for循环写在函数外面

  树的层次遍历和BFS就很像了,总的来说就是DFS用栈,只不是栈是隐式栈,BFS用队列,用的是显式列。

1.初始化一个队列,根入队
2.取对头,并访问
3.若左节点非空,入队;右节点非空入队
4.队不空,循环2 - 3,否则结束

二、图的遍历

2.1 BFS

  自上而下,从左到右,也需要vis。是树层次的推广。

2.2 DFS

  需要vis数组。是树的先跟的推广。

2.3 树和图区别与联系

  图需要需要vis是怕循环遍历,这和树不一样,数不可能循环遍历。

  相同点:从一点出发遍历相邻节点,对树来说是左右孩子。

  不同点:图有多个相邻点,二叉树只有左右孩子,bfs需要vis记录访问过的节点。

  比如a,左b右c,访问a,然后bc如队,然后访问b,a和b相邻,没有vis的话a又要被访问。

  图有不连通情况,树的的dfs和bfs都不需要vis。

  树是一种特殊的图。

三、线索树

  每个节点增加2个字段分别指向节点的前驱和后继。前驱好搞,直接在travel增加一个参数parentID,初始为null,在for内,if外直接指向该parentID,后继应该也不难,在if内,主要要看树的数据结构。

四、非递归遍历

  BFS利用队列保存尚未遍历的节点或者子树,DFS用栈。