Tree and two-fork tree C language Implementation __c language

Source: Internet
Author: User
Tags array length
1. Basic Concepts

Tree is the abbreviation of tree structure, it is an important non-linear data structure.

Representation of a tree: a generalized table representation is usually used, where the root of each tree is placed in front of the table as the name of the table that is the child tree, and the corresponding generalized table for the tree of the following graph is expressed as:

A (B (D,e (h,i), F), C (G))

The degree of the node: the number of nonempty trees each node in the tree or the subsequent node is defined as the degree of the node. (as in the above figure, the B node degree is 3,a and e node degree is 2,c node degree is 1, the remaining node degree is 0).

Degree of the tree: the maximum value of the degree of all nodes in the tree is defined as the degree of the tree. (The tree's degree is 3 in the above figure)

Leaf nodes: Nodes with degrees equal to 0 are called leaf nodes or terminal nodes.

Branch nodes: nodes with degrees greater than 0 are called branch nodes or non terminal nodes. The number of branches per node is the degree of the node.

In a tree, the root of each node's subtree (or the successor of each node) is called the child node, which is called the Father node.

The layer of the node is defined from the root, the root node is the first layer, the child node is the second layer, and so on. The maximum number of nodes in a tree is called the depth or height of the tree . The depth of the graph tree is 4.


Binary tree: Refers to the tree's degree of 2 ordered trees.

Full two fork tree: when each layer in the binary tree is full (the node number is 2^ (i-1)), the tree is said to be full of two fork trees.

Complete binary tree: Two fork tree, except the last layer, the remaining layer is full, and the last layer or full, or at the far right is missing a number of consecutive nodes, the tree is called a complete binary tree.

Ideal Balance binary tree: Two fork tree, in addition to the last layer, the remaining layer is full, and the last layer of the node can be arbitrarily distributed, it is called the ideal balance binary tree. The ideal balanced binary tree contains two fork trees and complete binary trees.


2, Binary tree storage structure

A, sequential storage structure

Sequentially stores a binary tree, numbering each node first, and then storing the nodes in a bunch of arrays by numbering as subscript.

The following figure is a binary tree and its corresponding sequential storage structure

The two-fork tree sequential storage structure is suitable for storing the complete binary tree, but it is not suitable for the general binary tree and wastes the storage space, so the following link storage structure is generally used.

b, linked storage structure

Each node is set to three fields: the Left pointer field, the range, and the right pointer field.

Node type definition:

struct Btreenode  //node type definition
{
    elemtype data;            Domain
    struct btreenode* left;   Left pointer field
    struct btreenode* right;  Right pointer field
};


The following figure is a binary tree and its corresponding linked storage structure


3, the traversal of the binary tree

A, pre-sequence traversal: Access to root node operations before traversing the left and right subtrees, the preceding sequence traversal is: a,b,c,d,e,f,g

b, in-order traversal: access to the root node operation after traversing the Zuozi and the right subtree, the sequence traversal sequence in the above figure is: C,b,d,a,e,g,f

C, sequential traversal: access to the operation of the root node in the traversal of the left and right subtree, the following sequence of traversal: c,d,b,g,f,e,a

D, by layer traversal algorithm: that is, from top to bottom, the same level from left to right order access to each node, the above figure by layer traversal order: a,b,e,c,d,f,g

Detailed implementation see the details of the procedure later.


4, Binary tree operation and operation

The following is a detailed program to show the operation of the binary tree and operations, according to the graph of the binary tree as an example, the generalized table is expressed as:A (B (c,d), E (, F (G) )

#include <stdio.h> #include <stdlib.h> #define QUEUEMAXSIZE 20//define Queue array length #define STACKMAXSIZE 10//define stack array length   typedef char ELEMTYPE;            Defines the elemtype type struct Btreenode//node type definition {elemtype data;   domain struct btreenode* left;  Left pointer field struct btreenode* right;

Right pointer field}; 
1, initialize binary tree void initbtree (struct btreenode** BT) {*BT = null;//////2, set up two fork tree, input method with generalized table, such as: A (B (c,d), E (, F (G))
    void Createbtree (struct btreenode** BT, char* string) {struct btreenode* p; struct btreenode* s[stackmaxsize]; The stack that defines the S array as a pointer to the storage root node uses the int top =-1; The top of the stack pointer is set to-1, which indicates an empty stack int k; K as a sign of processing nodes, k=1 processing left subtree, k=2 processing right subtree int i = 0; Use I to scan the two-fork tree Generalized table string stored in array string with initial value of 0 *bt = NULL;
            Set the root pointer empty, that is, starting from the empty tree two-fork tree while (String[i]) {switch (String[i]) {case ": break; Case ' (': {if (top = StackMaxSize-1) {printf ("stack
                    Space is too small, need to increase stackmaxsize!\n "); Exit1);
                } top++;
                S[top] = p;
                K = 1;
            Break Case '] ': {if (top = 1) {printf ("Binary Tree Generalized table String error.
                    \ n ");
                Exit (1);
                } top--;
            Break
            Case ', ': K = 2;break;
                Default: {p = malloc (sizeof (struct btreenode));
                P->data = String[i];
                P->left = P->right = NULL;
                if (*BT = = NULL) *BT = p;
                    else {if (k = = 1) s[top]->left = p;
                else s[top]->right = p;
    }}//switch end i++; }//while End}//3, check if the two fork tree is an empty int btreeempty (struct btreenode* bt) {if (BT = NULL) REturn 1;
else return 0;
    }//4, find the binary tree depth int btreedepth (struct btreenode* bt) {if (BT = NULL) return 0;
        else {int dep1 = btreedepth (bt->left);//Compute the left subtree depth int dep2 = btreedepth (bt->right);//compute the right subtree depth
        if (Dep1 > Dep2) return dep1 + 1;
    else return DEP2 + 1; }//5, find the node with X in the two fork tree, if present, return the element storage location, otherwise return null value (the algorithm is similar to the preceding sequence traversal) elemtype* findbtree (struct btreenode* bt, Elemtype x) {if (BT =
    = null) return null;
        else {if (Bt->data = = x) return & (Bt->data);
            else {elemtype* p;
            if (p = findbtree (Bt->left, x)) return p;
            if (p = findbtree (Bt->right, x)) return p;
        return NULL; }}//6, output binary tree, can be modified on the basis of the preceding sequence traversal. Use generalized table output format: A (B (c,d), E (, F (G))) void Printbtree (struct btreenode* bt) {if (BT!= NULL) {printf ("%c", Bt-&gt ;d ATA); Output root node value IF (bt->left!= NULL | |
            Bt->right!= NULL) {printf ("()"); Printbtree (Bt->left);
            Output left subtree if (bt->right!= NULL) printf (","); Printbtree (Bt->right);
        Output right subtree printf (")"); }}//7, clear the binary tree, make it into an empty tree, the algorithm is similar to the subsequent recursive traversal of the void Clearbtree (struct btreenode** BT) {if (*BT!= NULL) {Clea            Rbtree (& ((*BT)->left))//delete left subtree Clearbtree ((*BT)->right);//Delete right subtree free (*BT);           Free root node *bt = NULL; The root pointer is null}//8, pre-ordered traversal void preorder (struct btreenode* bt) {if (BT!= NULL) {printf ("%c,", Bt->da
        TA);
        Preorder (Bt->left);
    Preorder (bt->right);
        }//9, middle-order traversal void inorder (struct btreenode* bt) {if (BT!= NULL) {inorder (bt->left);
        printf ("%c,", bt->data);
    Inorder (Bt->right);
   }//10, subsequent traversal of void Postorder (struct btreenode* bt) {if (BT!= NULL) {postorder (bt->left);
        Postorder (Bt->right);
    printf ("%c,", bt->data);
}//11, traversal by layer//Layer traversal algorithm requires the use of a queue, start with the entire tree's root node in the team, and then every time you delete a node from the queue and output the node,//All of its non-empty left and right child nodes, when the queue is empty, the algorithm ends. In the algorithm, the maximum length of the queue does not exceed the maximum number of nodes in the two adjacent layers in the two-fork tree, and//So the maximum queue length is defined in advance at the beginning of the program Queuemaxsize is greater than the maximum length of the queue, so there is no need to consider the overflow of the
    btreenode* BT) {struct btreenode* p;
    The struct btreenode* q[queuemaxsize];//defines the array space used by the queue, and the element type is pointer type int front = 0 that points to the node;
    int rear = 0;
        if (BT!= NULL)//will be the root pointer team {Q[rear] = BT;
    Rear = (rear + 1)% Queuemaxsize; while (front!= rear)//When queue is not empty execute loop {p = q[front];//Save team first element front = (front + 1)% queuemaxsize;//Delete
        In addition to the team head element, make the team head pointer point to the team first element printf ("%c,", p->data);/output team first element if (p->left!= NULL)//If the node exists left child, then left child node pointer teams
            {Q[rear] = p->left;
        Rear = (rear + 1)% Queuemaxsize; } if (P->right!= NULL)//If the node exists right child, the left child node pointer team {Q[rear] = P->right;
        Rear = (rear + 1)% Queuemaxsize;
    }}//main function void main () {struct btreenode* bt;
    Char b[50];
    Elemtype x, *px;
    Initbtree (&AMP;BT);
    printf ("Input binary tree Generalized table string: \ n");
    scanf ("%s", b);
    Createbtree (&AMP;BT, b);
    Printbtree (BT);

    printf ("\ n");
    printf ("Pre-preface:");
    Preorder (BT);

    printf ("\ n");
    printf ("In order:");
    Inorder (BT);

    printf ("\ n");
    printf ("After:");
    Postorder (BT);

    printf ("\ n");
    printf ("by layer:");
    Levelorder (BT);

    printf ("\ n");
    printf ("Enter a character to find: \ n"); scanf ("%c", &x);
    A space in a format string can skip any blank character px = Findbtree (BT, x);
    if (px) printf ("Find success:%c\n", *px);

    else printf ("Find failed \ n");
    printf ("The depth of the binary tree is:");
    printf ("%d\n", Btreedepth (BT));
Clearbtree (&AMP;BT);
 }

Output results:

In the program, the establishment of two-fork tree and the level of traversal part of the use of generalized tables, stacks and queues of knowledge, and more detail, need to be extra careful.


5, the basic concept of the tree and storage structure

This refers to a tree that is greater than or equal to 3, usually called a multiple tree or a fork tree.

The order of the trees is suitable for the full tree, otherwise it will be a waste of storage space. So you usually use a linked storage structure.

The linked storage structure of a tree typically takes the following three ways:

(1) Standard method

In this way, each node in the tree, in addition to the value of the stored data element, contains a K pointer field that points to the K-child node, or to the K-Shang tree, where k is the tree's degree. The type of the node can be defined as:

struct Gtreenode
{
    elemtype data;//node domain struct gtreenode* t[k];//
    node pointer field t[0]~t[k-1]
};

(2) Generalized standard method

The generalized standard approach is to add a pointer field to each node in the standard way that points to its parent node. The type of the node can be defined as:

struct Pgtreenode
{
    elemtype data;//node
    domain struct pgtreenode* t[k];//node pointer field t[0]~t[k-1]
    struct pgtreenode* parent; Parent pointer field
};
(3) Two-fork tree form

This representation first converts the tree to the corresponding two-fork tree, and then stores the binary tree with a binary list. However, it is not possible to indicate that there is an ordered tree in any node that is missing the front child and the child behind it.


in general, the tree is stored in a standard way.


The following is a three-pronged tree and its corresponding linked storage structure (standard method), and the generalized table is expressed as:A (b (, E,f (, J)), C,d (g (k,,l), h,i))

(Note: In the absence of a front face tree and the situation of the face tree, when the generalized table representation, the comma behind the empty tree can not be omitted)


6, Operation and operation of the tree

The operation and operations of the tree are similar to the two-fork tree, which can be compared after the operation and operation of the binary tree.

The following is an example program that shows the operations and operations of the tree in the graph above.

#include <stdio.h> #include <stdlib.h> #define KK 3//define the degree of the tree #define MS 10//Define symbolic constants specify the size of the stack space when building a tree storage structure #define MQ 1
0//define symbol constants the size of the specified queue space in the tree-by-layer traversal algorithm typedef char ELEMTYPE;

struct Gtreenode//Tree link storage standard method of node type definition {elemtype data;//node range struct gtreenode* T[KK];//node pointer domain t[0]~t[kk-1]}; 1, establish the storage structure of the tree, using the representation of the generalized table, such as: A (b (, e,f (, F)), C,d (g (k,,l), h,i))//Assuming that the node value is still character type char, the algorithm is similar to the two-fork tree/Set two stacks, and the s stack is used to store pointers to the root node. So that children can link to their parents ' nodes. The//d stack is used to store the ordinal number of the child node to be linked so that it can be correctly linked to the pointer field of the parent node//The following is a storage structure void creategtree based on the K-fork tree given by the generalized table strings string (struct
    gtreenode** GT, char* string) {struct gtreenode* s[ms];//ms constant is the stack array length of the storage node pointer int D[MS]; int top =-1; Top as a stack of two stack pointers, the initial value of 0 indicates that the stack empty struct gtreenode* p; A pointer int i = 0, J, pointing to a tree node is defined as p;   Use I to indicate the current character position in the scan string array a *gt = NULL;
            Initially the root pointer is placed in the null while (String[i]) {switch (String[i]) {case ': break;
                Case ' (': {top++; S[top] = p; P pointer into s stack, 0 into D stack, d[top] = 0; Indicates the child node to be scannedThe first pointer field break that is linked to the node of the top element of the S stack; Case ') ': top--;break;
                Let S and D back up the stack case ', ':d [top]++;break;//Let the child node to be read link to the node at the top of the s stack the next pointer field default: {
                p = malloc (sizeof (struct gtreenode));
                P->data = String[i];
                for (j = 0; J < KK; J +)//KK indicates the depth of the tree p->t[j] = NULL;
                if (*gt = = NULL)//makes the P Node a root node (if) or a pointer field (else) *GT = P that corresponds to a parent node;
            else S[top]->t[d[top]] = p;
        }}//switch end; i++;
    Prepare to process the next character}//2, the tree's first root traversal void preroot (struct gtreenode* GT)//First root traverse a K-fork tree {int i;  if (GT!= NULL) {printf ("%c,", gt->data);   Access root node for (i = 0; i< kk; i++) Preroot (gt->t[i));
    recursively traverse each subtree}//3, after the tree's root traversal void postroot (struct gtreenode* GT) {int i; if (GT!= NULL) {for (i = 0; i < KK; i++) postrOot (Gt->t[i]);    Recursively traverses each subtree printf ("%c,", gt->data);
    Access root Node}//4, the tree's layered traversal of the void Layerorder (struct gtreenode* GT)//Layer traversal by the GT pointer pointed to the K-fork tree {struct gtreenode* p;
    int i; struct gtreenode* Q[MQ];     Defines a queue with an array of Q,mq constants for the queue array length int front = 0, rear = 0;
        Defines a team head pointer and a team tail pointer, which initially 0 indicates the empty team if (GT!= NULL)//The root pointer into the team {q[rear] = GT;
    Rear = (rear + 1)% MQ;
    while (front!= rear)///When queue is not empty execute loop {p= Q[front];  Front = (front + 1)% MQ; Make the team head pointer to the team first element, the element delete team first elements printf ("%c,", p->data); Outputs the value of the node for the first element of the team for (i = 0; i < KK/i++)//non-empty child node pointers are sequentially queued if (P->t[i]!= NULL) {Q[rea
            R] = p->t[i];
        Rear = (rear + 1)% MQ;    Find the node value elemtype* findgtree (struct gtreenode* GT, Elemtype x) {if (gt==null) return NULL from the Tree}}//5;
        The tree null returns the null pointer else {elemtype* p;
        int i; if (Gt->data = = x) return & (Gt->data);
   Find addresses that successfully return the domain of a node     for (i = 0; i < KK; i++)//To continue looking for each Shang tree, return the resulting domain address if (p = findgtree (gt->t[i), x)) Retu
        RN p; Return null;//find unsuccessful returns null pointer}//6, output tree, can be modified on the basis of the root traversal. 
        Use the generalized table output format: A (b (, e,f (, F)), C,d (g (k,,l), h,i)) void Printgtree (struct gtreenode* GT) {if (GT!= NULL) {int i; printf ("%c", gt->data);
        Outputs the value of the root node for (i = 0; i < KK; i++)//To determine whether the GT node has children if (Gt->t[i]!= NULL) break;
            if (i < KK)//////when having children, execute recursion {printf ("); Printgtree (Gt->t[0]);
                Output the first tree for (i = 1; i < KK; i++)//Output the remaining subtree {printf (",");
            Printgtree (Gt->t[i]);
        printf (")");
        //7, tree depth int gtreedepth (struct gtreenode* gt) {int i, max;//max to save the maximum depth in a subtree that has been asked for (GT = NULL)
    return 0;
    max = 0;
for (i = 0; i < KK; i++) {int d = gtreedepth (Gt->t[i]);//Compute a Shang tree depth        if (d > max) max = D; return Max + 1;
    Returns the depth of the non-empty tree, which equals the maximum depth of each subtree plus 1}//8, clears the binary tree, makes it an empty tree, and the algorithm resembles the subsequent recursive traversal of void Cleargtree (struct gtreenode** GT) {if (*gt!= NULL)
        {int i;            for (i = 0; i < KK; i++) Cleargtree (& ((*GT)->t[i));//delete subtree free (*GT);           Free root node *gt = NULL;
    Set root pointer to NULL}//main function void Main () {char ch;
    struct gtreenode* GT = NULL; Char b[50];
    Defines a character array for storing a generalized table of K-Fork Trees printf ("Enter a generalized table string of%d fork tree: \ n", KK);
    scanf ("%s", b);
    Creategtree (", b);
    printf ("First root traversal result:");
    Preroot (GT);

    printf ("\ n");
    printf ("After root traversal result:");
    Postroot (GT);

    printf ("\ n");
    printf ("Traverse results by layer:");
    Layerorder (GT);

    printf ("\ n");
    printf ("The tree output in the form of a generalized table is:");
    Printgtree (GT);

    printf ("\ n");
    printf ("The depth of the tree is:%d\n", gtreedepth (GT));
    printf ("Enter a character to find:"); scanf ("%c", &ch);//The spaces in the format string can skip any whitespace characters if (findgtree (GT, CH)) printf ("Find success.")
    \ n ");
Else        printf ("Lookup failed.
    \ n ");
Cleargtree (>);
 }

Run Result:



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.