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、ノードトラバーサル完了を印刷します。

 空ではないので、前記第1のステップは、プリントノードB、ノードBトラバーサル完了、第2工程を呼び出しを開始し、PreorderTraversal(BT->左)を行い、印刷ノードを呼び出します。

 前記第2ステップでは、空ではないので、その後の印刷ノードD、ノードDトラバーサル完了、第3工程で始まる、PreorderTraversal(BT->左)を行い、印刷ノードを呼び出します。

 空ではないので、ノードを印刷した後4.第3のステップは、次に、第四のステップで始まる、プリントノードH、ノードHトラバーサル完了をPreorderTraversal(BT->左)を行います。

 前記第4ステップノードを印刷した後、次いで、空であるように、それが呼び出しPreorderTraversal第四工程(BT->左)、通話開始に戻り、第五のステップで始まる、PreorderTraversal(BT->左)を呼び出しますPreorderTraversal(BT->右)、BT-ため>右第四工程への即時復帰して、空である、この時間の終わりまで第四工程、第三工程に戻ります。第3のステップは、右は空です> BT-による、PreorderTraversal(BT->右)を開始したリターンはすぐに、また完成した第三ステップは、第二のステップは、呼び出し元に返され、第二段階はPreorderTraversal(BT->右)を開始しました空ではないので、ノードEは、Eノードトラバーサル完了の印刷を開始、との第3工程を開始します。

 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