C data structures and algorithms - the basis of consolidation - Tree-02: the establishment of binary tree traversal and Different

Tree-02: the establishment of binary tree traversal and Different

整理了完全二叉树的建立方法以及四种遍历方式(多种方法实现)

After understanding this chapter, you can view:
C data structures and algorithms - the basis of consolidation - Tree-03: Schematic - by preorder traversal depth understanding of the principles of the recursive execution of
C data structures and algorithms - the basis of consolidation - Tree-04: Schematic - Tree inorder traversal of
C data structures and algorithms - basic consolidation - tree 05: Schematic - order traversal of the tree

在保证结构定义一样的前提下,代码可通用。

. 0x01 definition of binary tree structure:

typedef struct TreeNode
{
    char data;
    struct TreeNode* Left;//左孩子指针
    struct TreeNode* Right;//右孩子指针
}TreeNode,*BinTree;//定义了这个结构体为 TreeNode ,这个二叉树指针为 BinTree

. 0x02 binary tree establishment:

Simple point: a direct input data to create a node

A specific comment below.

void CtreateBiTree(BinTree *BT)
{
    char ch;
    scanf("%c",&ch);
    if(ch=='#')
    {
        *BT=NULL;
    }
    else
    {
        *BT=(BinTree)malloc(sizeof(TreeNode));
        if(!BT)
            exit(-1);
        (*BT)->data=ch;
        CreateBiTree(&(*BT)->Left);
        CreateBiTree(&(*BT)->Right);
    }
 }

A bit more complex: a quoted string to create a binary tree

//二叉树的建立:递归实现,先序遍历的创建方法
//注意此处BT为指针的指针,因为没有返回值,所以要把二叉树的指针完全改变掉,需要指针的指针
//str为传入的字符串,该字符串用于创建二叉树的数据域
//n为当前创建节点数据域时使用到str的位数
//返回值为记录二叉树创建完毕后,使用了多少字符
//一定需要输入合法的用于创建树的字符串数据,不然会出错
int CreateBiTTree(BinTree *BT,char *str,int n)
{
    printf("创建二叉树第  %d  个节点   ", n);
    char ch = str[n];//每次使用一个字符赋值数据域
    printf("%c\n", ch);//输出该数据
    n++;
    if (ch != '\0')//字符串没完就一直创建
    {
        if (ch == '#')//如果遇到字符 # ,说明下方没有了,是叶节点
        {
            *BT = NULL;//代表二叉树指针为空
        }
        else
        {
            *BT = (BinTree)malloc(sizeof(TreeNode));//*BT代表二叉树指针的值,BinTree表示这是一个指针,大小为一个二叉树结构体
            if (!*BT)
            {
                exit(-1);//若分配空间失败,异常退出
            }
            (*BT)->data = ch;
            n=CreateTree(&(*BT)->Left,str, n);//取指针的地址给此函数的第一个参数,因为此参数为二级指针
            n=CreateTree(&(*BT)->Right, str, n);
        } 
    }
 return n;
}

0x03. Binary tree traversal

Preorder traversal:

Traversal order Description:

First through all the left subtree, and then traverse the right subtree.

Recursive realization of ideas:

Each encountered a node, the first print information, and then turn left recursion, right recursion.

With the idea of ​​stack to achieve:

Save the nodes themselves and their children have visited the left with a stack, then the stack continue to access the right child.
Each encountered a node, the first stack, and then print the information, and then to traverse its left child, and other children left after traversing the complete return of the stack, access to the right child.

Illustrates a traversal order:

Here Insert Picture Description

Recursive:
//前序遍历,递归实现
void PreorderTraversal(BinTree BT)
{
    if (BT == NULL) return;
    printf(" %c", BT->data);
    PreorderTraversal(BT->Left);
    PreorderTraversal(BT->Right);
    return;
}
Stack implementation:
//前序遍历,栈实
//栈中元素分析:栈中保留的元素是自己和自己的左孩子已经访问过来,但右孩子还没访问的结点
void PreorderTraversal1(BinTree BT)
{
    if (BT == NULL) return;
    BinTree Stack[100];//存储结点的栈
    int top = -1;
    BinTree p = BT;//p指针用于遍历
    while (p || top != -1)//退出循环条件为BT不存在且栈为空
    {
        if (p)
        {
            Stack[++top] = p;//如果BT存在,那么BT入栈
            printf(" %c", p->data);//打印信息
            p = p->Left;//继续访问左孩子
        }
        else
        {
            p = Stack[top--];//若访问到空,则拿出栈的一个元素,此元素的自己和左孩子已遍历,现在开始遍历右孩子
            p = p->Right;
        }
    }
}

Preorder:

Traversal order Description:

From the root, has been to the leftmost leaf node, began a visit to the node, then visit his father, when his father left all children access to complete, and then access the right child.

With the idea of ​​recursive:

Has been found to the left of the leftmost node, and all nodes printing the left, the right to go visit the children.

With the idea of ​​stack to achieve:

Save the nodes themselves and their children have the right not visited with the stack.
Each encountered a node, the first stack, and then traverse to the left, when there is no left, and then print the node information, then traverse to the right, repeated cycle, until all the elements to complete the visit.

Illustrates a traversal order:

Here Insert Picture Description

Recursive:
//中序遍历,递归实现
void InorderTraversal(BinTree BT)
{
    if (BT == NULL) return;
    InorderTraversal(BT->Left);
    printf(" %c", BT->data);
    InorderTraversal(BT->Right);
    return;
}
//中序遍历,栈实现
//栈中元素分析:栈中保留的元素是自己和自己的右孩子都没访问过的结点
void InorderTraversal(BinTree BT)
{
    if (BT == NULL) return;
    BinTree Stack[100];
    int top = -1;
    BinTree p = BT;//p指针用于遍历
    while (p || top != -1)//退出循环条件为BT不存在且栈为空
    {
           if (p)
           {
               Stack[++top] = p;//如果BT存在,那么BT入栈
               p = p->Left;//继续访问左孩子
           }
           else
           {
               p = Stack[top--];//若访问到空,则拿出栈的一个元素,此元素的左孩子已遍历,现在开始遍历右孩子
               printf(" %c", p->data);//打印信息
               p = p->Right;
           }
    }
}

Postorder:

Traversal order Description:

From left to right, the first leaves, the nodes.

Recursive realization of ideas:

The left child, right child to complete all recursive then print specific information.

Stack realization of ideas:

Setting a flag stack, for storing the amount of marker stack node, return many times.
After each encounter a junction, go left first, set the flag to the 1, then left to return to the child traversed, set the flag to the 2, then go to traverse the right child, right after the children returned, print the stack node information, the node then the stack.

Illustrates a traversal order:

Here Insert Picture Description

Recursive:
//后序遍历,递归实现
void PostorderTraversal(BinTree BT)
{
    if (BT == NULL) return;
    PostorderTraversal(BT->Left);
    PostorderTraversal(BT->Right);
    printf(" %c", BT->data);
    return;
}
Stack implementation:
//后序遍历,栈实现
//栈中元素分析:右孩子和自身都没有访问过的元素,第一次访问,继续访问左孩子,第二次访问,继续向右孩子访问,等左右孩子都访问完了,访问自身
void PostorderTraversal1(BinTree BT)
{
    if (BT == NULL) return;
    BinTree Stack[100];
    int top = -1;
    int flagStack[100];//此栈用于记录访问结点的次数,访问一次记1,访问两次记2,第三次访问输出结点值。
    BinTree p = BT;
    while (p || top != -1)
    {
        if (p)//第一次访问结点,flag=1
        {
            Stack[++top] = p;
            flagStack[top] = 1;
            p = p->Left;
        }
        else
        {
            if (flagStack[top] == 1)//第二次访问,说明从左孩子退回,继续去访问右孩子,取出栈中元素,但不出栈
            {
                p = Stack[top];
                flagStack[top] = 2;
                p = p->Right;
            }
            else//不等于1,那么一定是第三次访问,从右孩子退回,该输出自己的元素值了。
            {
                p = Stack[top--];
                printf(" %c", p->data);//打印信息
                p = NULL;//说明此结点的左右孩子均已完成遍历,那么将p置空,继续回退。
            }
        }
    }
}

Sequence traversal - queue implementation

Traversal order Description:

Start from the root, layer by layer, from left to right to access.

Queue realization of ideas:

Each element encountered a first print information, and then into the team, if the left child exists, then left the child into the right, the right child exists, and right after the children into the team, and other teams there is no element is all traverse completed.

Traversal order Description:

Here Insert Picture Description

//层序遍历,队列实现
//队中元素分析:自身访问过,左右孩子未访问过
void LevelorderTraversal(BinTree BT)
{
    BinTree Queue[100];//创建一个二叉树指针类型的队列
    int head = -1;
    int tail = -1;
    if (BT)
    {
        Queue[++tail] = BT;//如果头结点非空,头结点入队
    }
    while (head < tail)//队列为空是遍历完成的条件
    {
        BinTree tmp = Queue[++head];//队头出队,打印信息
        printf("%c -> ", tmp->data);
        if (tmp->Left)//如果左孩子存在,左孩子先入队
        {
            Queue[++tail] = tmp->Left;
        }
        if (tmp->Right)
        {
            Queue[++tail] = tmp->Right;
        }
    }
}

0x04. Write main function test

#include<stdio.h>
#include<stdlib.h>
int main()
{
   BinTree BT;//注意BT为指针
   int k;//记录创建函数的返回值
   char str[100];
   printf("\n\n**********\t请输入一串字符用于创建二叉树:");
   gets_s(str);
   k = CreateTree(&BT, str, 0);
   printf("\n\n**********\t二叉树创建成功!!!共使用了  %d  个字符",k);
   printf("\n\n**********\t开始该二叉树的前序遍历......");
   PreorderTraversal(BT);
   printf("\n\n**********\t开始该二叉树的中序遍历......");
   InorderTraversal(BT);
   printf("\n\n**********\t开始该二叉树的后序遍历......");
   PostorderTraversal(BT);
   printf("\n\n**********\t开始该二叉树的层序遍历......");
   LevelorderTraversal(BT);
   return 0;
}

Test Data: AB # D ## C ##
test shots:
Here Insert Picture Description

This chapter end.
Published 19 original articles · won praise 7 · views 425

Guess you like

Origin blog.csdn.net/ATFWUS/article/details/104262585