Thorough understanding of clues two fork tree

Source: Internet
Author: User

First, clue two the principle of the fork tree

By examining various binary linked lists, the number of empty chain fields is always more than the number of non-empty chains, regardless of the shape of the child fork tree. To be exact, n each node of the two-linked list has a total of 2n chain domain, non-empty chain domain is n-1, but the empty chain domain has n+1. As shown in the following figure.


Therefore, a method is proposed, which uses the original empty chain field to hold the pointer and points to the other nodes in the tree. This pointer is called a clue.

Remember PTR points to a node in a binary list, and here are the rules for creating clues:

(1) If the ptr->lchild is empty, it holds the precursor node pointing to the node in the middle sequence traversal sequence. This node is called the middle sequence precursor of PTR;

(2) If the ptr->rchild is empty, it holds the subsequent node of the node in the middle sequence traversal sequence. This node is called the secondary sequence of PTR;

Clearly, in deciding whether lchild refers to the left child or the precursor, rchild refers to the right child or successor, requiring a distinguishing mark. Therefore, we add two additional flag domains Ltag and Rtag at each node, noting that Ltag and Rtag are only Boolean variables that distinguish between 0 or 1 numbers, and that occupy less memory space than pointer variables like Lchild and Rchild. The node structure is shown below.


which

(1) Ltag is 0 o'clock the left child pointing to the node, which is the precursor of the 1 o'clock point;

(2) Rtag is 0 o'clock to the right child pointing to the node, which points to the successor of the node at 1 o'clock;

(3) Therefore for the above diagram of the two-linked list can be modified to the following image of the adopted child.



Second, the Clue two fork tree structure realizes

The binary clue tree storage structure is defined as follows:

/* Two fork Tree two fork clue storage structure Definition */
typedef enum{link, Thread}pointertag;    link = 0 means pointing to the left and right child pointer; thread = 1 indicates a precursor or successor to a
 
typedef struct BITNODE
{
       char data;                                      Node data
       struct Bitnode *lchild, *rchild;                Left and right child hands
       Pointertag  Ltag;                               Left and right signs
       pointertag  rtal;
} Bitnode, *bitree;

The essence of the clue is to change the null pointer in the two-fork list to a precursor or a subsequent clue. Because the precursor and the successor information can only be obtained when traversing the two-fork tree, the clue process is the process of modifying the null pointer during the traversal.

The recursive function code for the sequential traversal of the thread is as follows:

Bitree Pre;                 A global variable that always points to a node that has just been visited
//middle-order traversal for sequencing-threaded
void inthreading (Bitree p) {
    if (p)
    {
        inthreading (P- >lchild);          Recursive left subtree thread
                //===
        if (!p->lchild)           //No left child
        {
            p->ltag = Thread;    Precursor clue
            p->lchild = pre;//left child pointer pointing to precursor
        }
        if (!pre->rchild)     //No right child
        {
            Pre->rtag = Thread;  Subsequent clues
            pre->rchild = p;//precursor right child pointer to successor (current node P)
        }
        pre = P;
                = = =
        inthreading (p->rchild);      Recursive right subtree thread
    }
}

The code above, in addition to the code between//===, is exactly the same as the recursive code traversal in the two-fork tree. It just changes the function of the print node to a clue.


The middle part of the code does something like this:

Because the successor of P node is not accessible at this time, it can only be judged by the right pointer of its predecessor Rchild, if (!pre->rchild) indicates if NULL, then P is the successor of the pre, so Pre->rchild = P, and set pre- >rtag = Thread, which completes the subsequent node's cue. As shown in figure:


if (!p->lchild) indicates that the left pointer field of a node is empty because its predecessor has just been accessed and assigned the pre, you can assign the pre to P->lchild and modify P->ltag = Thread (which is defined as 1) to complete the cue of the precursor node.



After completing the precursor and subsequent judgment, do not forget that the current node P is assigned to the pre for the next use.

With a clue to the two fork tree, when it is traversed, it is actually equivalent to manipulating a doubly linked list structure.


As with the doubly linked list node, add a head node to the binary tree list, as shown in the following figure, and make its lchild field pointer point to the root node of the binary tree (the first step in the diagram), whose Rchild field pointer points to the last node in the middle order traversal visit (the second step in the figure). Conversely, in the first node of the middle sequence of a binary tree, the Lchild field pointer and the Rchild field pointer of the last node point to the Head node (the third and fourth steps in the figure). The advantage is that we can traverse from the first node to the next, or from the last node.



The traversal code is shown below.

T points to the head node, the head node left chain lchild points to the root node, and the head node right chain rchild points to the last node in the middle sequence traversal.
//Middle sequence traverse binary clue tree means binary tree t
int inorderthraverse_thr (Bitree t)
{
    bitree p;
    p = t->lchild;                               P refers to the root node
    while (P! = t)                               //empty tree or traversal ends p = = T
    {while
        (P->ltag = = Link)                       //When Ltag = 0 o'clock loops to the first node of the middle sequence sequence
        {
            p = p->lchild;
        }
        printf ("%c", p->data);                      Displays the node data, which can be changed to other node operations while
        (P->rtag = = Thread && p->rchild! = t)
        {
            p = p->rchild;
            printf ("%c", P->data);
        }
 
        p = p->rchild;                         P Enter its right subtree
    }
 
    return OK;
Description


(1) in the code, p = t->lchild; means the first step in the diagram above, so that P points to the root node to begin the traversal;
(2) while (P! = t) actually means that the loop until the fourth step in the diagram appears, which means that P points to the head node, so it is equal to T (T is a pointer to the head node), end the loop, or the loop continues to traverse the operation;
(3) while (P-ltag = = link) This cycle, is by a->b->d->h, at this time H node Ltag is not Link (is not equal to 0), so the end of this cycle;
(4) then print H;
(5) while (P->rtag = = Thread && p->rchild! = t), because node H's Rtag = Thread (equals 1), and does not point to the head node. Therefore the subsequent d of the H is printed, and since the Rtag of D is the link, the exit loop is therefore exited;
(6) p=p->rchild; means that P points to the right child I of the end point D;
(7)..., so it loops through the loop until it prints out the HDIBJEAFCG and ends the traversal operation.


As can be seen from this code, it is equal to a list of scans, so the time complexity is O (n).
Due to the full use of space in the null pointer domain (which is equal to space savings), it ensures that a traversal at the time of creation can be useful for a lifetime of subsequent information (meaning saving time). So in the actual problem, if the two-fork tree needs to traverse or find the node to need some kind of traversal sequence of the precursor and successor, then the use of the clue two-linked list of the storage structure is a very good choice.

#include <stdio.h> #include <stdlib.h> #define ERROR 0 #define OK 1 typedef enum{link, Thread} pointerta      G link = 0 means pointing to the left and right child pointer//thread = 1 indicates a precursor or successor to a typedef struct BITNODE {Cha                              R data;                 Node data struct Bitnode *lchild; 
    Left and right child pointer struct Bitnode *rchild;                        Pointertag Ltag;
Left and right signs Pointertag rtag;
 
}bitnode, *bitree;                                 Bitree Pre;
    Global variable, always point to the node just visited//pre-order Create two fork tree void Createtree (Bitree *t) {char ch;
     
    scanf ("%c", &ch);
    if (ch = = ' # ') {*t = NULL;
        } else {(*t) = (bitree) malloc (sizeof (Bitnode));
        if ((*t) = = NULL) {return;
        } (*t)->data = ch;
        Createtree (& (*t)->lchild);
    Createtree (& (*t)->rchild);
}}//t points to the head node, the head node left chain lchild points to the root node, and the head node right chain rchild points to the last node in the middle sequence traversal. The two-tree T int represented by the middle sequence traverse binary clue tree Inorderthraverse_thr (Bitree t) {Bitree p;           p = t->lchild; P points to the root node while (P! = t) {while (P->ltag = = Link)//When Ltag = 0 o'clock loops to the first node of the middle order sequence {p = P
        ->lchild;  } printf ("%c", p->data); Displays the node data, which can be changed to other node operations while (P->rtag = = Thread && p->rchild! = t) {p = P-&GT;RC
            Hild;
        printf ("%c", p->data);           } p = p->rchild;
P enter its right subtree} return OK;              }//middle sequence traversal for the middle sequence of the threaded void inthreading (Bitree p) {if (p) {inthreading (p->lchild);                Recursive left sub-tree thread if (!p->lchild)//No left child {P->ltag = Thread;             Precursor clue p->lchild = pre; Left child pointer pointing to precursor, here is 3rd step} if (!pre->rchild)//No right child {Pre->rtag = thre              Ad             Subsequent clues pre->rchild = p; Precursor right child pointer pointing to successor (Current node P)} pre = P;              Inthreading (P->rchild); Recursive right Subtree Thread}}//Establish head node, middle sequence clue two fork tree int inorderthread_head (bitree *h, Bitree t) {(*H) = (bitree) malloc (sizeof (Bitnode)
    );
    if ((*h) = = NULL) {return ERROR;
    } (*h)->rchild = *h;
 
    (*h)->rtag = Link;
        if (!t)//If NULL {(*h)->lchild = *h;
    (*h)->ltag = Link;
        } else {pre = *h;        (*h)->lchild = t;
        The first step (*h)->ltag = Link;         Inthreading (t);        Find the last node pre->rchild = *h;
        Fourth Step Pre->rtag = Thread;      (*h)->rchild = pre;
    Second Step}} int main (int argc, char **argv) {Bitree T;
 
    Bitree temp;
    printf ("Please enter the contents of the pre-order binary tree: \ n");                 Createtree (&t);       Build two fork Tree Inorderthread_head (&temp, T);
    Join the head node and lead printf ("Output binary tree content: \ n");
     
    Inorderthraverse_thr (temp);
    printf ("\ n");
return 0; }

This article is based on http://blog.chinaunix.net/uid-26548237-id-3476920.html to perfect.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.