C数据结构与算法-基础整理-树-03:图解-通过前序遍历对递归执行原理的深入理解

通过树的递归实现前序遍历的例子,深入理解递归的执行原理

本章建立在一下章节基础上:

C数据结构与算法-基础整理-树-02:二叉树的建立及四种遍历方式

在理解本章后,还可查看:

C数据结构与算法-基础整理-树-04:图解-树的中序遍历

C数据结构与算法-基础整理-树-05:图解-树的后序遍历

前序遍历函数递归执行过程图解

代码如下:

//前序遍历,递归实现
void PreorderTraversal(BinTree BT)
{
    if (BT == NULL) return;
    printf(" %c", BT->data);
    PreorderTraversal(BT->Left);
    PreorderTraversal(BT->Right);
    return;
}

递归执行原理图解:

原始二叉树:

1.第一步调用 PreorderTraversal,先打印A结点,A结点遍历完成。

 2.第一步调用打印结点后,接着执行 PreorderTraversal(BT->Left),开始第二步调用,由于不为空,所以打印B结点,B结点遍历完成。

 3.第二步调用打印结点后,接着执行 PreorderTraversal(BT->Left),开始第三步调用,由于不为空,所以打印D结点,D结点遍历完成。

 4.第三步调用打印结点后,接着执行PreorderTraversal(BT->Left),开始第四步调用,由于不为空,所以打印H结点,H结点遍历完成。

 5.第四步调用打印结点后,接着调用 PreorderTraversal(BT->Left),开始第五步调用,由于为空,所以返回至第四步的调用PreorderTraversal(BT->Left)后,开始调用PreorderTraversal(BT->Right),由于BT->Right为空,立刻返回至第四步调用,此时第四步调用结束,返回至第三步。第三步开始执行PreorderTraversal(BT->Right),由于BT->Right为空,立刻返回,第三步也执行完毕,返回至第二步调用,第二步开始执行PreorderTraversal(BT->Right),开始新的第三步调用,由于不为空,开始执行打印结点E,结点E遍历完成。

 6.新的第三步调用打印结点后,开始执行PreorderTraversal(BT->Left),由于BT->Left 为空,立刻返回至第三步,第三步开始执行PreorderTraversal(BT->Right),开始执行第四步调用,由于不为空,打印 I 结点,I 结点遍历完成。

 7.第四步打印结点后,开始执行PreorderTraversal(BT->Left),由于BT->Left为空,返回至第三步,这个第四步执行完毕,此时第三步执行到函数末尾,执第三步行完毕,返回至第二步,此时的第二步也执行到末尾,第二步执行完毕,返回至第一步,此时第一步已经调用了PreorderTraversal(BT->Left)打印了B结点,开始执行PreorderTraversal(BT->Right),新的第二步调用,由于BT->Right不为空,开始打印C结点,C结点遍历完成。

8.新的第二步调用打印结点后,开始执行PreorderTraversal(BT->Left),开始第三步调用,由于不为空,开始打印结点F,F结点遍历完成。

9.第三步调用打印完毕后,开始执行PreorderTraversal(BT->Left),由于为空,立刻返回,开始执行PreorderTraversal(BT->Right),由于为空。立刻返回,第三步执行到末尾,返回至第二步,第二步开始执行PreorderTraversal(BT->Right),开始新的第三步调用,由于BT->Right 不为空,开始打印G,结点G遍历完成。

10.新的第三步打印结点后,开始执行PreorderTraversal(BT->Left),由于BT->Left为空,开始执行PreorderTraversal(BT->Right),开始执行第四步调用,由于不为空,执行打印结点J,结点J遍历完成。

11.第四步执行完打印后,开始执行PreorderTraversal(BT->Left),由于BT->Left为空,立刻返回,开始执行PreorderTraversal(BT->Right),由于BT->Right为空,立刻返回,此时第四步执行完毕,返回至第三步,第三步已经调用了PreorderTraversal(BT->Right)打印了J,所以第三步执行完毕,返回至第二步,第二步已经调用了PreorderTraversal(BT->Right)打印了G,所以第二步执行完毕,返回至第一步,此时第一步已经调用了PreorderTraversal(BT->Right)打印了C,第一步调用结束,整个递归过程也随之结束,遍历完了所以结点。

遍历顺序为:A->B->D->H->E->I->C->F->G->J

感悟:

1.递归的实质就是不断调用自身,来实现某些功能,递归的结束标志就是第一次函数调用结束。

2.在明白原理后,思考理解就不要一直想象它的具体调用过程,只需要看在哪里执行遍历,在哪里调用自身,一直往下调用的结束条件是什么,如何才会完成第一步调用。

3.关于树的调用次数问题,可以直接看树的层数,可以这样理解,当前是第几层,就是第几次在调用,不过有着先左后右的顺序。

6.树的前序遍历的递归原理其实就是深度优先搜索的原理:一个结点有一条路就走一条路,等所有的路走完了,就返回至上一个结点。

此章结束。

发布了19 篇原创文章 · 获赞 7 · 访问量 422

猜你喜欢

转载自blog.csdn.net/ATFWUS/article/details/104274512