Learning data structure-Chapter 4: Trees and Binary Trees (Binary Tree Traversal and Cue Binary Tree)

Chapter 4: Trees and Binary Trees (Binary Tree Traversal and Cue Binary Tree)

Last article talked about learning data structures - Chapter IV: tree and binary tree (binary tree stored in order and chain store) the following clues and learn binary tree traversal binary tree

1. Traversal of Binary Tree

The traversal of the binary tree : each node in the tree is visited according to a certain search path, and each node of the tree is visited once, and only once.

Insert picture description here
We are divided into the order of visiting the root node

  • Preorder traversal: first root -> left subtree -> right subtree
  • Middle-order traversal: first left subtree -> root -> right subtree
  • Post-order traversal: first left subtree -> right subtree -> root

Note that no matter when the root is visited, the left subtree is visited first and then the right subtree is visited.

1.1 Pre-order traversal

First-order traversal:

  • Visit the root node;
  • Use pre-order recursion to traverse the left subtree;
  • Use pre-order recursion to traverse the right subtree;

: The branches of each node follow the above access sequence, reflecting "recursive call"

Time complexity : O(n)

The first order traversal result of the above figure : A BDFE CGHI

Thinking process:

  • (1) Visit root node A first,
  • (2) A is divided into left and right subtrees. Because it is a recursive call, the left subtree also follows the order of "root node first-then left-then right", so visit node B,
  • (3) Then visit the D node,
  • (4) There are branches when visiting the F node, which also follows the order of "root node first-then left-then right",
  • (5) Visit the E node, at this time the large subtree on the left has been visited,
  • (6) Then follow the order of the last visit to the right subtree, visit the large subtree on the right, and the large subtree on the right also visits the root node C first,
  • (7) Visit the left subtree G,
  • (8) Because there is no left subtree of G, the next two visits to the right subtree H of G,
  • (9) Last visit to the right subtree I of C

Recursive algorithm for pre-order traversal:

void PreOrder(BiTree T){
    
    
    if(T!=null){
    
    
       visit(T);
       PreOrder(T->lchild);
       PreOrder(T->rchild);
    }
}

1.2 In-order traversal

Follow the order of left subtree -> root node -> right subtree


In-order traversal:

  • Use middle order to traverse the left subtree;
  • Visit the root node;
  • Traverse the right subtree in middle order

Time complexity : O(n)

Sequence traversal result in the above figure : DBEFAGHCI

Recursive algorithm for middle-order traversal:

void PreOrder(BiTree T){
    
    
    if(T!=null){
    
    
       PreOrder(T->lchild);
       visit(T);
       PreOrder(T->rchild);
    }
}

1.3 Post-order traversal

Follow the order of left subtree -> right subtree -> root node

Post-order traversal:

  • Recursively traverse the left subtree in post-order;
  • Recursively traverse the right subtree in post-order;
  • Visit the root node;

Time complexity : O(n)

The result of the post-order traversal in the above figure : DEFB HGIC A

Recursive algorithm for post-order traversal:

void PreOrder(BiTree T){
    
    
    if(T!=null){
    
    
       PreOrder(T->lchild);
       PreOrder(T->rchild);
       visit(T);
    }
}

2. Non-recursive traversal of binary trees

The three traversal methods mentioned above all use recursion to traverse. The following is how to use non-recursive algorithm traversal, we need to use it , take the middle-order traversal as an example:

Algorithm idea

  • Initially, the 扫描root node and all the left nodes of the root node are sequentially pushed into the stack
  • Pop a node, 访问it
  • 扫描The right child node of the node and push it to the stack
  • 扫描All left nodes of the right child node in turn and-into the stack
  • Repeat the process until the stack is empty

Pay attention to distinguish scanning and access


According to the above algorithm idea to explain the binary tree as shown in the figure above, we use a non-recursive algorithm to traverse:

1: 扫描Root node and all left nodes of the root node in turn and push them to the stack in turn

2: Pop a node and visit

3: Then scan 7the right child node of the node number and push it to the stack. Its right child node is empty, so no node is pushed onto the stack.

4: Then continue to pop the stack 4number node and visit it

5: Then scan 4the right child node of the node number and push it to the stack. Its right child node is empty, so no node is pushed onto the stack.

6: Then continue to pop the stack 2number node and visit it

7: Then scan 2the right child node of 5the 5number node and push it into the stack. Its right child node is , so push the number node into the stack.

8: Then scan 5all the left nodes of the node number and push them to the stack in turn. Its left node is empty, so no node is pushed into the stack.

9: Then continue to pop the stack 5number node and visit it, and the node of his right child is empty, and no node is pushed into the stack.

10: Then pop the 1node and visit it.

11: Scan 1the right child node of the node in the same way, and then push it to the stack in turn

12: After the right child node is pushed into the stack, push the left node of the node into the stack one by one, and then continue to loop step two, knowing that the stack is empty


Code:

void InOrder2(BiTree T){
    
    
   InitStack(S);
   BiTree p=T;
   //循环判断
   while(p||!IsEmpty(S)){
    
     //栈非空 
      if(p){
    
    
         Push(S,p);
         p-p->lchild; //将p指向左孩子
      }else{
    
    
         Pop(S,p); //左孩子为空,出栈一个结点
         visit(p); //并访问它
         p=p->rchild; //指向右孩子
      }
   }
}

3. Level traversal

Hierarchical traversal : As the name implies, it traverses from top to bottom and from left to right, and the traversal sequence is in the order of labeling.

Hierarchical traversal needs help 队列, algorithm thought:

  • Initially join the root to the team and visit the root node
  • If there is a left subtree, put the root of the left subtree into the queue
  • If there is a right subtree, put the root of the right subtree into the queue
  • Then dequeue the node and visit
  • Repeat the process until the queue is empty

Code implementation :

void leveOrder(BiTree T){
    
    
    InitQueue(Q);
    BiTree p; //辅助变量
    EnQueue(Q,T); //根节点入队
    while(!isEmpty(Q)){
    
    
      DeQueue(Q,P); //出队队首元素
      visit(p); //并访问
      if(p->lchild!=NULL){
    
     //左孩子节点不为空,入队
         EnQueue(Q,p->lchild);
      }
      if(p->rchild!=NULL){
    
    //右孩子节点不为空,入队
         EnQueue(Q,p->rchild);
      }
    }
}

4. Reverse the traversal result

We can get the traversal sequence from a binary tree, so can we get a binary tree by traversing the sequence?

First of all, can we get a binary tree through only one traversal sequence? For example, the first-order traversal sequence: 124536, we must traverse the root node first, but whether 2 is the left node or the right node cannot be determined, so according to a traversal sequence, the whole process cannot be reversed.

In fact, the (later) pre-order traversal sequence and the middle-order traversal sequence can determine a binary tree, but the subsequent traversal sequence and the pre-order traversal sequence cannot determine a binary tree.

When learning to reverse the traversal results, please be sure to 清楚three traversal methods.

先序The 中序idea of traversal sequence and traversal sequence inversion:

  • In the preorder sequence, the first node is the root node;
  • The root node divides the middle-order traversal sequence into two parts;
  • Then determine the nodes of the two parts in the preorder sequence, and the first node of the two parts is the root of the left subtree and the root of the right subtree respectively;
  • Repeating this process recursively in the subtree can uniquely determine a binary tree.

For example: Pre-order sequence: 124536 Middle-order sequence: 425163, please draw the binary tree.

In the first order traversal we reach the root node of the first node, and in the post order traversal sequence we know that the last node is the root node, so the operation of the post order traversal sequence plus the middle order traversal sequence is similar.

In addition, a unique binary tree can also be determined based on the 层次遍历序列sum 中序遍历序列.

5. Thread Binary Tree

The above mentioned binary linked list, we know that regardless of the shape of the binary tree, the number of empty chain domains is always more than the number of non-empty chain domains. To be precise, there are 2n chain domains in the binary linked list of each node of n, and there are n-1 non-empty chain domains, but there are n+1 empty chain domains.

Therefore, a method is proposed to use the original empty chain domain to store pointers and point to other nodes in the tree. Such pointers are called clues. At the same time, the search speed is improved.

We call the process of establishing the binary tree of clues : clueing

If there is no left subtree, point the left pointer to its predecessor node.
If there is no right subtree, point the right pointer to its successor node.

5.1 Precedence Threading

Node 1 has a left child 2->node 2 has a left child -> node 4 has no left child, so the left pointer points to the predecessor node 2->node 4 has no right child, so the right pointer points to the successor node 5->node Point 5 has no left child, so the left pointer points to the predecessor node -> node 5 has no right child, so the right pointer points to the successor node 3->node 3 has a left child 6->node 6 has no left child, so the left pointer points to the predecessor node Node 3->Node 6 has no right child and no successor node -> Then look at node 3, if it has no right child, point the right pointer to successor node 6.

5.2 In-order threading

5.3 Post-order threading

The most commonly used is the in-order clue binary tree

Obviously, in deciding whether lchild points to the left child or the predecessor, and whether rchild points to the right child or the successor, a distinguishing sign is needed. Therefore, we add two more flag fields ltagandrtag

Node structure of clue binary tree


typedef struct ThreadNode{
    
    
    ElemType data;
    struct ThreadNode *lchild,*rchild;
    int ltag,rtag;
}ThreadNode,*ThreadTree;

The binary linked list composed of this kind of node structure is used as the storage structure of the binary tree and is called the clue linked list . For points to the predecessor and successor pointers called clues , clues of a binary tree is called: threaded binary

5.4 Binary tree with middle-order clues

In-order clue binary tree clue code

//传入一个根节点和前驱结点
void InThread(ThreadTree &p,ThreadTree &pre){
    
    
    if(p!=NULL){
    
    
        InThread(p->lchild,pre);  //递归左子树线索化
        if(p->lchild==NULL){
    
     //没有左孩子
            p->lchild = pre; //左孩子指针指向前驱
            p->ltag = 1;    //前驱线索
        }
        if(pre!=NULL && pre->rchild==NULL){
    
     //没有右孩子
            pre->rchild = p; //前驱右孩子指针指向后继(当前结点p)
            pre->rtag = 1;  //后继线索
        }
        pre = p; //修改前驱结点为当前结点
        InThread(p->rchild,pre);  //递归右子树线索化
    }
}

Initialization and finishing

//传入线索二叉树的根节点
void CreateInThread(ThreadTree T){
    
    
     ThreadTree pre=NULL;
     if(T!=NULL){
    
    
        InThread(T,pre); //实现线索化
        pre->rchild=NULL; //收尾 最后遍历的结点的右孩子至为空
        pre->rtag=1;
     }
}

Introducing the clue binary tree of the head node

Traversal of binary tree with middle-order clues

//找最左侧的孩子结点
ThreadNode *Firstnode(ThreadNode *p){
    
    
     while(p->ltag==0){
    
    
          p=p->lchild;
     }
     return p;
}
//找后继结点
ThreadNode *Nextnode(ThreadNode *p){
    
    
     if(p->rtag == 0){
    
    
          return Firstnode(p->rchild);
     }
     return p->rchild;
}
void InOrder(ThreadNode *T){
    
    
     for(ThreadNode *p=Firstnode(T);p!=NULL;p=Nextnode(p)){
    
    
         visit(p);
     }
}

No knowledge of public data structure processing wood off the synchronous update, the next time will explain: Trees and forest-related knowledge , welcome everyone's attention

Guess you like

Origin blog.csdn.net/qq_41941875/article/details/106432141