Basic application of binary tree (PTA question type as an example)

Posted by lynwell07 on Fri, 05 Nov 2021 04:43:34 +0100

We have a deeper understanding of binary trees according to the above questions of PTA

 

7-1 creation and recursive traversal of binary tree (20 points)

Accept input from the keyboard to expand the sequence, and use the binary linked list as the storage structure to establish a binary tree. And output the pre order, middle order and post order traversal sequences of the binary tree. The data of binary tree node is character type data, where # represents space character.

Input format:

Enter the extended precedence sequence. The data of binary tree node is character type data, where # represents space character.

Output format:

The first line outputs the preorder traversal sequence; The second line outputs the middle order traversal sequence; The third line outputs the post order traversal sequence.

Input example:

ABC##DE#G##F### 

Output example:

ABCDEGF
CBEGDFA
CGEFDBA
 // Parsing: simple recursive traversal
//It mainly uses the extended preorder sequence to create a binary tree
#include<stdio.h>
#include<stdlib.h>

typedef struct node{
    char data;
    struct node *Lchild;
    struct node *Rchild;
}BiNode, *BiTree;

//Extension precedence to create binary tree
BiTree Creat_Pre_Bitree(BiTree root)
{
    char c;
    c = getchar();
    if(c=='#')
        return NULL;
    else{
        root = (BiTree)malloc(sizeof(BiNode));
        root->data = c;
        root->Lchild = Creat_Pre_Bitree(root->Lchild);
        root->Rchild = Creat_Pre_Bitree(root->Rchild);
    }
    return root;
}
//Preorder traversal 
void PreOrder(BiTree root)
{
    if(root)
    {
        printf("%c", root->data);
        PreOrder(root->Lchild);
        PreOrder(root->Rchild);
    }
}
//Medium order traversal
void InOrder(BiTree root)
{
    if(root){
        InOrder(root->Lchild);
        printf("%c", root->data);
        InOrder(root->Rchild);
    }
}
//Postorder traversal
void PostOrder(BiTree root)
{
    if(root){
        PostOrder(root->Lchild);
        PostOrder(root->Rchild);
        printf("%c", root->data);
    }
}

int main()
{
    BiTree root = Creat_Pre_Bitree(&root);
    PreOrder(root);
    printf("\n");
    InOrder(root);
    printf("\n");
    PostOrder(root);
    printf("\n");

    return 0;
}

 

 

 

7-2 non recursive preorder and middle order traversal (20 points)
 

The extended preorder sequence is received from the keyboard, and a binary tree is established with a binary linked list as the storage structure. The non recursive method is used to output the preorder and middle order traversal sequences of the binary tree.

Input format:

Enter the extended precedence sequence. The data of binary tree node is character type data, where # represents space character.

Output format:

The first line outputs the first order traversal sequence, and the second line outputs the middle order traversal sequence.

Input example:

ABC##DE#G##F### 

Output example:

ABCDEGF
CBEGDFA
 
//This topic mainly focuses on non recursive preorder and middle order traversal,
Algorithm implementation: most non recursive algorithms for recursive problems need to use stack to eliminate recursion
Implementation of preorder traversal:
1) Access root, enter the stack and enter its left subtree, and then access the root of the left subtree into the stack. After entering the left subtree of the next layer,... Until it is empty
2) If the stack is not empty, exit the node of the upper layer from the top of the stack and enter the right subtree of the node
 
//See the following for the basic operation of stack:
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
typedef struct node{
    char data;
    struct node *Lchild;
    struct node *Rchild;
}BiNode, *BiTree;

//Extension precedence to create binary tree
void Creat_Pre_Bitree(BiTree *root)
{
    char c;
    c = getchar();
    if(c=='#')
        *root = NULL;
    else
    {
        *root = (BiTree)malloc(sizeof(BiNode));
        (*root)->data = c;
        Creat_Pre_Bitree(&((*root)->Lchild));
        Creat_Pre_Bitree(&((*root)->Rchild));
    }
}

/*non-recursive */
//Stack correlation
typedef struct {
    BiTree stdata[MaxSize];
    int top;
} sqstack;
//Create stack
sqstack* Init_Stack()
{
    sqstack *s;
    s = (sqstack *)malloc(sizeof(sqstack));
    s->top = -1;
    return s;
}

//Air judgment
int IsEmpty(sqstack *s)
{
    if(s->top==-1)
        return 1;
    else
        return 0;
}

//Push 
void Push(sqstack*s,BiTree root){

    if(s->top<MaxSize){
        s->top++;
        s->stdata[s->top] = root;
        
    }
    return;
}

//Out of stack
int Pop(sqstack*s,BiTree *x){
    if(IsEmpty(s))
    {
        return 0;
    }
    else
    {
        *x = s->stdata[s->top];
        s->top--;
        return 1;
    }

}
//Non recursive preorder
void LPreOrder(BiTree root)
{
    sqstack* s;
    s = Init_Stack();
    BiTree p;
    p = root;
    while(p!=NULL||!IsEmpty(s)){
        while(p!=NULL){
            printf("%c", p->data);
            Push(s, p);
            p = p->Lchild;
        }
        if(!IsEmpty(s)){
            Pop(s,&p);
            p = p->Rchild;
        }
    }

}
//Non recursive middle order
void LInOrder(BiTree root)
{
    sqstack* s;
    s = Init_Stack();
    BiTree p = root;
    while(p!=NULL||!IsEmpty(s)){
        while(p!=NULL){
            Push(s, p);
            p = p->Lchild;
        }
        if(!IsEmpty(s)){
            Pop(s,&p);
            printf("%c", p->data);
            p = p->Rchild;
        }
    }

}


int main()
{
    BiTree root;
    Creat_Pre_Bitree(&root);
    LPreOrder(root);
    printf("\n");
    LInOrder(root);
    printf("\n");

    return 0;
}

 

7-3 non recursive postorder traversal (15 points)
 

The extended preorder sequence is received from the keyboard, and a binary tree is established with a binary linked list as the storage structure. The post order traversal sequence of the binary tree is output by non recursive method.

Input format:

Enter the extended precedence sequence. The data of binary tree node is character type data, where # represents space character.

Output format:

Output post order traversal sequence.

Input example:

ABC##DE#G##F### 

Output example:

CGEFDBA
 
//The latter order non recursive traversal method can not be used because when the left and right subtrees are accessed and the subtree returns after accessing the node, we can not effectively judge whether it is returned by the left subtree or the right subtree. At this time, we need to make another judgment
/*Algorithm implementation*/
1. Enter the current node into the stack and its left subtree, and repeat until the current node is empty;
2. If the stack is not empty, judge whether the right subtree of node P at the top of the stack is empty and whether the right subtree has been accessed. If yes, exit the stack and access node P, assign p to q, and set p to empty; If not, enter the right subtree of P.
 
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
typedef struct node{
    char data;
    struct node *Lchild;
    struct node *Rchild;
}BiNode, *BiTree;

//Extension precedence to create binary tree
void Creat_Pre_Bitree(BiTree *root)
{
    char c;
    c = getchar();
    if(c=='#')
        *root = NULL;
    else
    {
        *root = (BiTree)malloc(sizeof(BiNode));
        (*root)->data = c;
        Creat_Pre_Bitree(&((*root)->Lchild));
        Creat_Pre_Bitree(&((*root)->Rchild));
    }
}
/*
//recursion
void PreOrder(BiTree root)
{
    if(root)
    {
        printf("%c", root->data);
        PreOrder(root->Lchild);
        PreOrder(root->Rchild);
    }
}

void InOrder(BiTree root)
{
    if(root){
        InOrder(root->Lchild);
        printf("%c", root->data);
        InOrder(root->Rchild);
    }
}

void PostOrder(BiTree root)
{
    if(root){
        PostOrder(root->Lchild);
        PostOrder(root->Rchild);
        printf("%c", root->data);
    }
}
*/

/*non-recursive */
//Stack correlation
typedef struct {
    BiTree stdata[MaxSize];
    int top;
} sqstack;
//Create stack
sqstack* Init_Stack()
{
    sqstack *s;
    s = (sqstack *)malloc(sizeof(sqstack));
    s->top = -1;
    return s;
}

//Air judgment
int IsEmpty(sqstack *s)
{
    if(s->top==-1)
        return 1;
    else
        return 0;
}

//Push 
void Push(sqstack*s,BiTree root){

    if(s->top<MaxSize){
        s->top++;
        s->stdata[s->top] = root;
        
    }
    return;
}

//Out of stack
int Pop(sqstack*s,BiTree *x){
    if(IsEmpty(s))
    {
        return 0;
    }
    else
    {
        *x = s->stdata[s->top];
        s->top--;
        return 1;
    }

}
//Get stack top element
void Top(sqstack*s,BiTree*p)
{
    if(IsEmpty(s))
        return;
    else
        *p = s->stdata[s->top];
}
//Non recursive preorder
void LPreOrder(BiTree root)
{
    sqstack* s;
    s = Init_Stack();
    BiTree p;
    p = root;
    while(p!=NULL||!IsEmpty(s)){
        while(p!=NULL){
            printf("%c", p->data);
            Push(s, p);
            p = p->Lchild;
        }
        if(!IsEmpty(s)){
            Pop(s,&p);
            p = p->Rchild;
        }
    }

}
//Non recursive middle order
void LInOrder(BiTree root)
{
    sqstack* s;
    s = Init_Stack();
    BiTree p = root;
    while(p!=NULL||!IsEmpty(s)){
        while(p!=NULL){
            Push(s, p);
            p = p->Lchild;
        }
        if(!IsEmpty(s)){
            Pop(s,&p);
            printf("%c", p->data);
            p = p->Rchild;
        }
    }

}
//Non recursive subsequent traversal
void LPostOrder(BiTree root)
{
    sqstack *s;
    BiTree p, q;
    s=Init_Stack();
    p = root;
    q = NULL;
    while(p!=NULL||!IsEmpty(s))
    {
        while(p!=NULL)
        {
            Push(s, p);
            p = p->Lchild;
        }
        if(!IsEmpty(s))
        {
            Top(s, &p);
            if((p->Rchild==NULL)||(p->Rchild==q))
            {
                Pop(s, &p);
                printf("%c", p->data);
                q = p;
                p = NULL;
            }
            else
                p = p->Rchild;
        }
    }
}

int main()
{
    BiTree root;
    Creat_Pre_Bitree(&root);
    LPostOrder(root);

    return 0;
}

 

7-4 level traversal (10 points)
 

The extended preorder sequence is received from the keyboard, and a binary tree is established with a binary linked list as the storage structure. Output the hierarchical traversal sequence of the binary tree.

Input format:

Enter the extended precedence sequence. The data of binary tree node is character type data, where # represents space character.

Output format:

Output hierarchy traversal sequence.

Input example:

ABC##DE#G##F### 

Output example:

ABCDEFG

//Hierarchical traversal of binary tree
The so-called hierarchical traversal of binary tree refers to traversing layer by layer from top to bottom from the first layer (root node) of binary tree, and accessing the same layer from left to right one by one. From this, we can see that the characteristics of this access process are: the children of the first visited node will also visit first, and the children of the later visited node will also visit later,
This is consistent with the queue operation, so we use the queue to control the node access order
//Algorithm implementation
1. The queue head node is out of the queue and accesses the out of the queue node
2. Non empty left and right children at the outgoing node join the team in turn
 
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
typedef struct node{
    char data;
    struct node *Lchild;
    struct node *Rchild;
}BiNode, *BiTree;

//Extension precedence to create binary tree
void Creat_Pre_Bitree(BiTree *root)
{
    char c;
    c = getchar();
    if(c=='#')
        *root = NULL;
    else
    {
        *root = (BiTree)malloc(sizeof(BiNode));
        (*root)->data = c;
        Creat_Pre_Bitree(&((*root)->Lchild));
        Creat_Pre_Bitree(&((*root)->Rchild));
    }
}

/*queue*/
//Circular queue
typedef struct 
{
    BiTree data[MaxSize];
    int front, rear;
}Csqueue;

//Empty queue initialization
Csqueue* Init_Queue()
{
    Csqueue *q;
    q = (Csqueue *)malloc(sizeof(Csqueue));
    q->front = q->rear = MaxSize - 1;
    return q;
}

//Join the team
int EnterQueue(Csqueue*q,BiTree x)
{
    if((q->rear+1)%MaxSize==q->front)
    {
        //printf("FULL");
        return 0;
    }
    else
    {
        q->rear = (q->rear + 1) % MaxSize;
        q->data[q->rear] = x;
        return 1; 
    }
}
//Out of the team
int DelectQueue(Csqueue*q,BiTree*x)
{
    if(q->rear==q->front)
    {
        //printf("NUll");
        return 0;
    }
    else
    {
        q->front = (q->front + 1) % MaxSize;
        *x = q->data[q->front];
        return 1;
    }
}
//Air judgment
int isempty(Csqueue*q)
{
    if(q->front==q->rear)
        return 1;
    return 0;
}

void levelorder(BiTree root)
{
    Csqueue *q;
    BiTree p;
    q = Init_Queue();
    EnterQueue(q, root);
    while(!isempty(q))
    {
        DelectQueue(q, &p);
        printf("%c", root->data);
        if (p->Lchild != NULL)
            EnterQueue(q, p->Lchild);
        if(p->Rchild!=NULL)
            EnterQueue(q, p->Rchild);
    }
}

int main()
{
    BiTree root;
    Creat_Pre_Bitree(&root);
    levelorder(root);
    return 0;
}

 

 
7-5 number of nodes (20 points)
 

The extended preorder sequence is received from the keyboard, and a binary tree is established with a binary linked list as the storage structure. Count the number of leaf nodes, nodes with degree 1 and nodes with degree 2 in the binary tree, and output them.

Input format:

Enter the extended precedence sequence. The data of binary tree node is character type data, where # represents space character.

Output format:

The first row outputs the number of leaf nodes, the number of nodes with degree 1 and the number of nodes with degree 2, separated by spaces. The second row continuously outputs leaf nodes without interval.

Input example:

ABC##DE#G##F###
 

Output example:

3 2 2
CGF
 // The node calculation is very simple. We only need to traverse all nodes. If the degree is 1, just judge that one of the left and right subtrees exists and the other is empty. The node algorithm of other degrees is the same
//I write a lot of code here, mainly to review the methods as much as possible. Readers can modify them according to the comments!
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
typedef struct node{
    char data;
    struct node *Lchild;
    struct node *Rchild;
}BiNode, *BiTree;

//Extension precedence to create binary tree
void Creat_Pre_Bitree(BiTree *root)
{
    char c;
    c = getchar();
    if(c=='#')
        *root = NULL;
    else
    {
        *root = (BiTree)malloc(sizeof(BiNode));
        (*root)->data = c;
        Creat_Pre_Bitree(&((*root)->Lchild));
        Creat_Pre_Bitree(&((*root)->Rchild));
    }
}
int count = 0;//node
int onecount = 0;//node = 1
int leafcount = 0;//node = 0

//Count the number of nodes in the binary tree
/*  
No sequence requirements, any traversal method can be used
*/
void preOrder(BiTree root)
{
    if(root)
    {
        count++;
        preOrder(root->Lchild);
        preOrder(root->Rchild);
    }
}

//Nodes with statistical degree of 1
/*
If the node has a left (right) node but no right (left) node, onecount + +;
*/
void LfOrder(BiTree root)
{
    if(root)
    {
        if(((root->Lchild==NULL)&&(root->Rchild!=NULL))||((root->Rchild==NULL)&&(root->Lchild!=NULL)))
            onecount++;
        LfOrder(root->Lchild);
        LfOrder(root->Rchild);
    }
}

//Count the number of leaf nodes
/*
Method 1: use global variables
*/
void LeafOrder(BiTree root)
{
    if(root)
    {
        if((root->Lchild==NULL)&&(root->Rchild==NULL))
        {
            printf("%c", root->data);
        }
        LeafOrder(root->Lchild);
        LeafOrder(root->Rchild);
    }
}
/*
Method 2
 Using the recursive idea, if it is an empty tree, it returns 0. If it is a leaf, it returns 1. If it is a dog, it returns the sum of the leaf nodes of the left and right subtrees.
Key and difficult points: this method can only calculate the number of leaf nodes of the tree after the leaf nodes of the left and right subtrees are calculated. So, we have to choose postorder traversal
*/
int leaf(BiTree root)
{
    int nl, nr;
    if(root == NULL)
        return 0;
    if((root->Lchild==NULL)&&(root->Rchild==NULL))
         return 1;
    nl = leaf(root->Lchild);
    nr = leaf(root->Rchild);
    return (nl + nr);
}



int main()
{
    BiTree root;
    Creat_Pre_Bitree(&root);
    int n = leaf(root);
    preOrder(root);
    LfOrder(root);
    printf("%d %d %d\n", n, onecount, count - onecount - n);
    LeafOrder(root);
    return 0;
}
7-6 height of binary tree (15 points)
 

The extended preorder sequence is received from the keyboard, and a binary tree is established with a binary linked list as the storage structure. Calculate the height of the binary tree and output it.

Input format:

Enter the extended precedence sequence. The data of binary tree node is character type data, where # represents space character.

Output format:

Output an integer.

Input example:

ABC##DE#G##F###

Output example:

5
 
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
typedef struct node{
    char data;
    struct node *Lchild;
    struct node *Rchild;
}BiNode, *BiTree;
int count=0;
//Extension precedence to create binary tree
void Creat_Pre_Bitree(BiTree *root)
{
    char c;
    c = getchar();
    if(c=='#')
        *root = NULL;
    else
    {
        *root = (BiTree)malloc(sizeof(BiNode));
        (*root)->data = c;
        Creat_Pre_Bitree(&((*root)->Lchild));
        Creat_Pre_Bitree(&((*root)->Rchild));
    }
}

/*Find the height of binary tree*/
/**
 * Method 1. Using the global variable method, the root node of the binary tree is the node of the first layer, and the child of the h-th node is h+1
 * 
*/

void Treedepth(BiTree root,int h)
{
    if(root)
    {
        if(h>count)
            count = h;
        Treedepth(root->Lchild, h + 1);
        Treedepth(root->Rchild, h + 1);

    }
}
/*Method 2*/
/*
Function value return: if it is an empty tree, its height is 0, otherwise its height should be the maximum height of the left and right subtrees + 1, which is traversed in sequence

*/
int PostTreedepth(BiTree root)
{
    int hl, hr, h;
    if(root==NULL)
        return 0;
    else
    {
        hl = PostTreedepth(root->Lchild);
        hr = PostTreedepth(root->Rchild);
        h = (hl > hr ? hl : hr) + 1;
        return h;
    }
}

int main()
{
    BiTree root;
    Creat_Pre_Bitree(&root);
    Treedepth(root, 1);
    printf("%d", count);
    return 0;
}

These are the basic applications of binary tree. Other operations will be released slowly. There are errors in the content. I hope the boss will correct!!