Tree and binary tree (including pre-order traversal and post-order traversal case implementation)

The definition of the node structure of the parent representation of the tree

Advantages : It is easy to find its parent node according to the parent pointer of the node, and the time complexity is o(1)

#include <stdio.h>
#include <stdlib.h>
#define MAX_TREE_SIZE 100
typedef int TElemType; //树结点的数据类型,目前暂定为整型
typedef struct PTNode //结点结构
{
    
    
    TElemType data; //结点数据
    int parent; //双亲位置
} PTNode;
typedef struct  //树结构
{
    
    
    PTNode nodes[MAX_TREE_SIZE]; //结点数组
    int r,n; //根的位置和结点数
} PTree;

The definition of the node structure of the child representation of the tree

There are root nodes of multiple subtrees in the tree. Consider using multiple linked lists, that is, each node has multiple pointer fields, and each pointer points to the root node of a subtree. This is called multiple linked list representation
scheme 1: The number of pointer fields is equal to the degree of the tree.
Disadvantage: When the degree of each node in the tree differs greatly, it is obviously a waste of time, because the pointer fields of many nodes are empty, but if the nodes of the tree The small difference in point degree means that the space is fully utilized.
Solution 2: Allocate space on demand, the number of pointer fields of each node is equal to the degree of the node, and a location is specially selected to store the number of node pointer fields. number of
advantages: overcomes the drawbacks of wasted space; disadvantages: since each linked list node structure is not the same, together with the value to be maintained node degrees, the loss of time will bring computationally
children notation

  • Arrange the nodes of each child and use the singly linked list as the storage space. Then there are n child linked lists for n nodes. If it is a leaf node, the singly linked list is empty, and then n head pointers form a linear list. Sequential storage structure, put into a one-dimensional array
  • The child node of the child linked list (store the subscript of a node in the header array; the pointer field is used to store the pointer to the next child node of a node), the header node of the header array ( Data field, the head pointer field stores the head pointer of the child linked list of the node)
  • Advantages: To find the children/brothers of a node, you only need to find the singly linked list of children of that node, which is more convenient
  • Disadvantages: You need to traverse the entire tree to reach the parent of the node. You can add the parent pointer of the node in the header structure*/
//树的孩子表示法结构定义
#define MAX_TREE_SIZE 100
typedef struct CTNode // 孩子结点
{
    
    
    int child;
    struct CTNode *next;
}*ChildPtr;
typedef struct  //表头结构
{
    
    
    TElemType data;
    ChildPtr firstchild;
}CTBox;
typedef struct  //树结构
{
    
    
    CTBox nodes[MAX_TREE_SIZE]; //结点数组
    int r,n;  //根的位置和结点数
}CTree;

Child brother notation

  • Principle: For any tree, the first child of a node is unique if it exists, and the right brother is also unique. Two pointers can be set to point to the first child of the node and the right brother of the node.
  • Advantages: easy to find a child of a node, only need to find the eldest son of the node through firstchild, and then find the second brother through the rightsib of the eldest child node
  • Disadvantages: It is not easy to find the parents of the node, but the problem of quickly finding the parents can be solved by adding a parent pointer field
typedef struct CSNode
{
    
    
    TElemType data;
    struct CSNode *firstchild, *rightsib;
}CSNode,*CSTree;

Binary tree

1. Sequential storage structure: Use a one-dimensional array to store the nodes of the binary tree, and the storage location of the node, that is, the subscript of the array, must reflect the logical relationship between the nodes
2. Binary linked list: each node of the binary tree A point has only two children at most, so a data field and two pointer fields are designed, which is called a linked list. If necessary, you can add a pointer field to its parents, which is called a three-pronged list

//二叉树的二叉链表结点结构
typedef struct BiTNode //结点结构
{
    
    
    TElemType data;  //结点数据
    struct BiTNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;

Traverse the binary tree

Principle: Starting from the root node, visit all nodes in the binary tree at a time in a certain order, so that each node is visited once and visited once (visit, order)
1. Visit: Determine what to do according to the needs of time What, such as calculation/printing of each node, etc.
2. Traversal method
We use graphics to express the structure of the tree, which is more intuitive and easy to understand, but for the computer, it has only loops, judgments, etc., and only processes Linear sequence, the traversal method is to turn the nodes in the tree into a linear sequence with a certain meaning

  • Preorder traversal: If the binary tree is empty, the no operation returns, otherwise the root node is visited first, then the left subtree is traversed in preorder, and the right subtree is traversed in preorder, eg. The preorder traversal of the binary tree ABCDEFGHI is ABDGHCEIF
  • Hierarchical traversal: If the binary tree is empty, the no operation returns, otherwise the root node is visited first, and the traversal is layer by layer from top to bottom. In the same layer, the nodes are visited one by one in the order from left to right. The binary tree ABCDEFGHI The sequence traversal is ABDGHCEIF
  • Post-order traversal: If the binary tree is empty, the no-op returns, otherwise the left and right subtrees are traversed to visit the left and right subtrees, and finally the root node is visited.
  • Middle-order traversal: If the binary tree is empty, then no operation returns, otherwise starting from the root node (note that the root node is not visited first), middle-order traverses the left subtree of the root node, then visits the follow node, and finally Orderly traverse the right subtree
  • Code use cases
    Image source: Dahua Data Structure P187
//以下代码都是递归函数
//前序遍历:eg.二叉树ABCDEFGHI的前序遍历为ABDGHCEIF
void PreOrderTraverse(BiTree T)
{
    
    
    if (T==NULL)
        return;
    printf("%c",T->data); //显示结点数据,可以更改为其他对结点操作
    PreOrderTraverse(T->lchild); //前序遍历左子树
    PreOrderTraverse(T->rchild); //前序遍历右子树
}
//中序遍历
void InOrderTraverse(BiTree T)
{
    
    
    if (T==NULL)
        return;
    InOrderTraverse(T->lchild); //中序遍历左子树(遍历直到碰到一个左子树的叶子结点)
    printf("%c",T->data); //显示结点数据,可以更改为其他对结点操作
    InOrderTraverse(T->rchild); //中序遍历右子树
}
//后序遍历
void PostOrderTraverse(BiTree T)
{
    
    
    if (T==NULL)
        return;
    PostOrderTraverse(T->lchild); //后序遍历左子树(遍历直到碰到一个左子树的叶子结点)
    PostOrderTraverse(T->rchild); //后序遍历右子树
    printf("%c",T->data); //显示结点数据,可以更改为其他对结点操作
}
//二叉树的建立,将二叉树中每个空指针引出一个虚结点,其值为一特定值如#
void Create_BiTree(BiTree * T){
    
    
    TElemType ch;
    scanf("%c",&ch);  //“%c”表示输入数据的类型格式 &表示取地址 &ch表示输入数据后存到ch里面等于给ch赋值。
    if(ch == '@'){
    
    
        *T = NULL;
    }
        //# 表示构造结束
    else if(ch == '#'){
    
    
        return ;
    }
        //排除以上两种情况,则为有数据的结点,对其进行构造
    else{
    
    
        *T = (BiTree)malloc(sizeof(BiTNode));
        (*T)->data = ch;  //生成根结点
        //继续构造其左右孩子结点
        Create_BiTree(&(*T)->lchild);
        Create_BiTree(&(*T)->rchild);
    }
}

int main(){
    
    
    BiTree T;
    printf("input PreOrder str:");
    //AB@D@@C@@#
    //构造二叉树
    Create_BiTree(&T);
    printf("\n");
    //分别按照先序、中序、后序的方式遍历二叉树
    printf("preorder list of  T :");
    PreOrderTraverse(T);
    printf("\nInOrder list of T :");
    InOrderTraverse(T);
    printf("\nPostOrder list of T:");
    PostOrderTraverse(T);

Guess you like

Origin blog.csdn.net/weixin_43464554/article/details/113590888