手がかりとトラバースバイナリツリーのトレイル

概要

  • 定義とデータ構造
  • スレッド表示
  • トラバーサル

定義とデータ構造

  1. 定義された
    ノードを含むバイナリツリー構造は、ねじ付きバイナリキューをいいます。
    ノードは、左サブツリーを有する場合、それは、その左の子を示すフィールドをlchild、またはlchildフィールドは、その前駆体を表すように、ノードは、右サブツリーを有する場合、その右の子を示すフィールドをrchild、またはそうrchildフィールドは、その後継者を示します。
    避ける混乱に、それは、2つのフラグを増加させる必要があるとLTAG RTAGをフィールド、フラグフィールドは、ノードポインタに接続され、次にフラグビットを手がかり後にノードによって表され、0を示しています。

  2. データの構造

    typedef struct BiThrNode
    {
        ElemType data;
        struct BiThrNode *lchild, *rchild;
        PointerTag LTag, RTag;
    } BiThrNode, *BiThrTree;
    

    ここで、PointerTag定義されています

    typedef enum PointerTag
    {
        Link,
        Thread
    } PointerTag;
    

    リンク== 0 == 1のリードを表しスレッド、ポインタを表します。

スレッド表示

  TRAILの本質は、トラバース、プロセスの手がかりは、トラバース中のヌルポインタの修飾である場合に得られることができる先行または後続の手がかりと後継者または情報の前身を指すようにバイナリヌルポインタのリストでありますプロセス。だから、関係トラバーサルを記録するためにポイント、現在のアクセスノードへのポインタp点の場合は、それへの事前のポインティングだけのノードを訪問しているだけで訪問したノードに常に前のポインタに添付、アクセスノードを持っています。

void InThreading(BiThrTree p, BiThrTree *pre)
{
    if (p)
    {
        // 左子树线索化.
        InThreading(p->lchild, pre);

        // 前驱线索.
        // 若当前结点无左子,则修改标志域并使得 lchild 指向 p 的前驱.
        if (!(p->lchild))
        {
            p->LTag = Thread;
            p->lchild = (*pre);
        }

        // 后继线索.
        if (!((*pre)->rchild))
        {
            (*pre)->RTag = Thread;

            // 将前驱结点的后继结点设置为当前结点.
            (*pre)->rchild = p;
        }

        // 更新 pre, 使其始终指向刚访问过的结点.
        (*pre) = p;

        // 右子树线索化.
        InThreading(p->rchild ,pre);
    }

    return;
} // InThreading

  ちょうど訪問したノードを事前後継手がかりセットアップ失敗します。ここで私は学習の問題が発生しました。この本は、グローバル変数としてか擬似コードを事前言わなかった、と事前に、私の最初のローカル変数とInThreading、一見何の問題に渡される値として、事前定義されたので、しかし慎重にデバッグFOUND後に保存された何のデータ構造がありませんあなたは再帰アルゴリズムのこのフォームを呼び出すとき、システムはそれぞれ、再帰の新しい層に入る、関数呼び出しスタックを維持し、システムは、現在のコールのリターンアドレスを保存し、新鮮なコールリターンアドレスに押し込まれます。サブルーチンの戻りアドレスがスタックからポップされたサブ機能を実行した後、この時間は、すべての修正は、彼らがすべて消えて前に事前に行われ、更新されることはありません。

  改良された方法は2つである:
    1.予備グローバル変数を設定し、
    2ポインタは、値の転送に渡されます。
  本論文では、第二のアプローチ。

トラバーサル

  スレッド後、容易に得られた線形配列のトラバースに前駆体および後続ノードを得ることができ、それは容易に配列線形に得ることができます。

Status InOrderTraverse_Thr(BiThrTree T, Status (*Visit)(ElemType e))
{
    // p 指向根结点.
    BiThrNode *p = T->lchild;

    // 空树或遍历结束时.
    while (p != T)
    {
        while (p->LTag != Thread)
        {
            p = p->lchild;
        }

        if (!Visit(p->data))
        {
            return ERROR;
        }

        // 访问后继结点.
        // 找到最左叶结点, 就可以轻松地访问其后继结点.
        while ((p->RTag == Thread) && (p->rchild != T))
        {
            p = p->rchild;
            Visit(p->data);
        }

        p = p->rchild;
    }

    return OK;
} // InOrderTraverse_Thr

リファレンス

  1. データ構造:C言語のバージョン/ヤン魏分、呉Weiminは、編集 - 北京:清華大学プレス、2007年
  2. 詳細なスレッドのバイナリhttps://blog.csdn.net/s_999999/article/details/86157532
  3. 順番にねじバイナリ原理及びプリアンブルが、ねじ(Javaバージョン)https://blog.csdn.net/UncleMing5371/article/details/54176252
  4. 関数呼び出しスタック(コールスタック)の個人的な理解https://blog.csdn.net/VarusK/article/details/83031643

おすすめ

転載: www.cnblogs.com/tianshihao/p/12663611.html