Data structure Programming Note 14: Sixth chapter tree and two fork Tree two fork Tree basic operation and four kinds of traversal algorithm implementation

Source: Internet
Author: User
Tags constant stack pop

Last time we looked together. The sparse matrix compression storage and the implementation of some basic operations of matrix based on ternary table storage structure. This time, let's take a look at the tree. The most important data structure-the implementation of the two-fork list storage structure of the two-fork tree and the implementation of four traversal operations of the two-fork tree based on the binary linked list.

Or the same ritual:

The program can be downloaded on the code cloud.
Address: Https://git.oschina.net/601345138/DataStructureCLanguage.git

Let's take a look at the ADT definition of the binary tree and see what the basic operations of the binary tree are:

ADT binarytree{Data Object D:D is a collection of data elements that have the same attributes. Data Relationship R: If d=φ, then r=φ, called Binarytree is an empty binary tree; if d≠φ, then r={h},h is the following two-yuan relationship; (1) in D there is a unique data element root called root, which has no precursor in relation H; (2
             If d-{root}≠φ, there is d-{root}={d1,dr}, and D1∩dr =φ, (3) If d1≠φ, there is a unique element D1 x1,<root,x1>∈h, and there is D1 on the relationship H1 contained in H; If dr≠φ, there is a unique element xr,<root,xr>∈h in Dr, and there is a relationship between the Dr Hr contained in H; h={<root,x1>,<root,xr>,h1,hr}; (4) (
    D1,{H1}) is a two-fork tree that conforms to this definition, called the left subtree of the root, and (Dr,{hr}) is a two-prong tree that conforms to this definition, called the right subtree of the root.
      Basic operation: Initbitree (&t) operation result: Constructs the empty binary tree T.
        Destroybitree (&t) Initial conditions: two fork tree T already exists.
      Operation Result: Destroy the binary tree T.
        Createbitree (&t, definition) Initial conditions: definition gives the definitions of a two-fork tree T.
      Operation Result: Construct two tree T by Definiton.
        Clearbitree (&t) Initial conditions: Two fork tree T exists.
      Operation Result: The two fork Tree T is cleared to empty tree.
        Bitreeempty (t) initial condition: two fork tree T exists.
      Operation Result: If T is an empty binary tree, True is returned, otherwise false is returned.
        Bitreedepth (t) initial condition: two fork tree T exists.
      Operation Result: Returns the depth of T.
        Root (T) initial condition: two fork tree T exists. Operation Result: returnThe root of T.
        Value (T, E) initial condition: two fork tree T exists, E is a node in T.
      Operation Result: Returns the value of E.
        Assign (T, &e, value) Initial conditions: Two fork tree T exists, E is a node in T.
      Operation Result: node E is assigned value.
        Parent (T, E) initial condition: two fork tree T exists, E is a node in T.
      Operation Result: If E is a non-root node of T, return its parent, otherwise return "null".
        Leftchild (T, E) Initial conditions: Two fork tree T exists, E is a node in T. Operation Result: Returns the left child of E.
      If E has no left child, it returns "empty".
        Rightchild (T, E) Initial conditions: Two fork tree T exists, E is a node in T. Operation Result: Returns the right child of E.
      If E has no right child, it returns "empty".
        Leftsibling (T, E) Initial conditions: Two fork tree T exists, E is a node in T. Operation Result: Returns the left sibling of E.
      If E is the left child of T or has no left sibling, then return "empty".
        Rightsibling (T, E) Initial conditions: Two fork tree T exists, E is a node in T. Operation Result: Returns the right sibling of E.
      If E is the right child or no right sibling of T, then return "empty".
        Insertchild (T, p, LR, C) Initial conditions: Two fork tree T exists, p points to a node in T, LR is 0 or 1, non-empty binary tree C does not intersect with T and the right subtree is empty.
                Operation Result: According to LR 0 or 1, insert C is the left or right subtree of the node referred to in P in T.
      The original left or right subtree of the node referred to by P becomes the right subtree of C.
        Deletechild (T, p, LR) initial conditions: Two fork tree T exists, p points to a node in T, LR is 0 or 1.
      Operation Result: Deletes the left or right subtree of the node in P referred to in T, according to LR 0 or 1.
        Preordertraverse (t, visit ()) Initial conditions: Two fork tree T exists, visit is the application function for node operation. Operation Result: FirstSequence traversal T, visit once and only once for each node invocation function.
      Once visit () fails, the operation fails.
        Inordertraverse (t, visit ()) Initial conditions: Two fork tree T exists, visit is the application function for node operation.
                Operation Result: The middle sequence traverses T, calling the function visit once and only once for each node.
      Once visit () fails, the operation fails.
        Postordertraverse (t, visit ()) Initial conditions: Two fork tree T exists, visit is the application function for node operation.
                Operation Result: Post-order traversal T, call function for each node visit once and only once.
      Once visit () fails, the operation fails.
        Levelordertraverse (t, visit ()) Initial conditions: Two fork tree T exists, visit is the application function for node operation.
                Operation Result: Hierarchy traverse T, call function visit once and only once for each node.
Once visit () fails, the operation fails. }adt BinaryTree

After understanding the basic operations that can be performed on a two-fork tree, we need to review the concept of recursion (skip this section and look directly at the code if you don't need to). Min's book P56 The relationship between recursion and the stack. But there is no mention of the basic concepts of recursion and the conversion of recursive and non-recursive algorithms.

The colloquial recursion is that the function calls itself. A typical example of recursion is the Hanoi tower problem and the Fibonacci sequence. A variety of algorithm books are introduced, Min book also talked about Hanoi Tower problem, in the book P57 page.

The advantages of recursive algorithm program: Clear structure, readable, easy to understand, easy to prove and so on.
Disadvantage: Function calls need to consume time and space, if the number of calls, this cost will be very high, so the execution efficiency of the recursive algorithm is poor.

The idea of designing recursive algorithms:
① divides complex problems into several sub-problems with similar solutions;
The solution of ② problem can be obtained by the solution combination of the sub-problems.
The ③ recursive program must have a termination condition, or the program executes endlessly.

The P56 page on the Min book describes what happened to the system stack during recursive invocation.

Why recursive algorithms need to be converted to non-recursive algorithms:
(1) Recursive algorithm is inefficient, time and space cost is high;
(2) Some programming languages do not support recursion.

The method of dividing and ruling is often mentioned in the algorithm book, and its thought is to divide the problem into several sub-problems, solve the sub-problems respectively, and then solve the problems by solving the problems.

Recursive Problem Solving: (solution from top to bottom). the problem to be solved is divided into several sub-problems, and the solution of problems begins with the original problem. There are many repetitive problem solving processes in the process of program execution.

Recursive problem Solving: (bottom-up solution). the same strategy is adopted, but the solution of the smallest sub-problem is first obtained, and then the scale is small to large, until the solution of the original problem is produced at the end.

The advantage of recursion relative to recursion is that it not only reduces the overhead of function calls, but also reduces the solution of repetitive problems.

How recursive algorithms are converted into non-recursive algorithms:

Some recursive problems can be directly solved, do not need backtracking , in the conversion to non-recursive algorithm can be directly solved by recursion method, the key is to find the recursive formula, that is, find the law. For example, the Fibonacci sequence problem belongs to this kind of problem, because it has the obvious recursive formula.

However, some recursive problems can not be solved directly , because the process of testing and backtracking is included in the solution procedure, and the solution of the original problem can not be obtained directly according to the solution of sub-problem by recursive formula. Such problems must use stacks to memorize backtracking points when converting to non-recursive algorithms. We're going to look at the two. The first order, the middle order and the sequential non-recursive algorithm all contain the backtracking process, and need to use the stack to memorize the backtracking point.

After reviewing the relevant knowledge of recursion and non-recursive algorithm, if you are unfamiliar with stack and queue operation, first look at the basic operation of stack and queue and its implementation, the previous article we also wrote the stack and queue implementation. We will use our own written sequence stack and chain queue as the implementation of the stack and queue to assist the completion of the two-fork tree traversal algorithm.

Data structure Programming note eight: Chapter three implementation of stack and queue sequence stack and carry system
http://blog.csdn.net/u014576141/article/details/77368176

Data structure Programming Note nine: Chapter three implementation of stack and queue chain queue
http://blog.csdn.net/u014576141/article/details/77418397

After describing the content, you can start looking at the code.
This code consists of three source files: The data structure definition of the Stack.cpp sequential stack and its implementation Queue.cpp the data structure definition of the chain queue and its implementation two fork tree Reference version. The basic operation of CPP two fork tree and the implementation of the traversal algorithm introduce the implementation of stack and queue two source files as stack and queue.

These three source files must be compiled in the same directory.

The focus of this article is the two fork tree, not the implementation of stacks and queues. If you have read the eighth and Nineth notes or already understand the sequential stack and the implementation of the chain queue, you do not have to look at the stack and the queue of source files, I just use the source of the two articles directly copied and pasted, the code line has not changed, only deleted some of the functions and comments not used.

In order to complete and clear the source code, I put the stack and the source of the queue behind the article, the stack and the queue implementation of children's shoes in question to go to the summary part of the article to look back.

Well, after the problems that affect the implementation of the code are clearly explained, the next step is to look at the related operations of the binary tree and the implementation of the traversal algorithm.

>>>>>>>>>>>>>>>>>>>>>>>>>>> Introduction of header Files <<<<<<<<<<<<<<<<<<<<<<<<<< <<<< #include <stdio.h>//using the standard library functions #include <stdlib.h>//using the dynamic memory allocation function//>>> >>>>>>>>>>>>>>>>>>>>>> Custom Symbol Constants <<< <<<<<<<<<<<<<<<<<<<<<<<<< #define
Stack_init_size 50//sequential stack storage space initial allocation #define STACKINCREMENT 10//sequential stack storage allocation increment #define OVERFLOW-2//Memory Overflow error Constants  
#define OK 1//Indicates the correct constant #define ERROR 0//indicates the constant of the operation error #define TRUE 1//Represents the logical true constant #define FALSE 0//constant//>>>>>>>>>>>>>>>>>>>& that represents a logical false Gt;>>>>> Custom Data type <<<<<<<<<<<<<<<<<<<<<<<<<<<< typedef int Status;   The status code is of type int, which is used to save the operation result (1 Success 0 failed) typedef char Telemtype;
    Binary tree node data field Element type//----------------binary tree Two-fork list storage represents--------------------typedef struct binode{telemtype data;   struct Binode *lchild,*rchild;

child node pointer}binode,*bitree;     --------introduce the stack and the implementation of the queue (which should actually be placed on the head, because of the reason for compilation)----------------#include "Queue.cpp"//Introduction Queue implementation #include "Stack.cpp" Implementation of the introduction stack//---------------------The main operation of the binary tree--------------------------//>>>>>>>>>> >>>>>>>>>>>>>>>>>>>1. Construction two fork Tree <<<<<<
    <<<<<<<<<<<<<<<<<<<<<<<<</*
          Function: Createbitree parameter: bitree &t two fork Tree Reference return value: status code, Operation successfully returns OK, otherwise returns error effect: Enter the value of the node in the binary tree in order of precedence (one character), the empty characters represents the empty tree, 
  Recursive construction two-fork list denotes binary tree T */Status Createbitree (Bitree &t) {//two fork tree in sequential sequence//ch store characters received from keyboard  Char ch;

    Receive characters from the keyboard ch = getchar ();
    Determines whether the input character is a space if (ch = = ") {//Input space indicates that the node is empty T = null; }//if else{//Not a space, according to the normal node treatment//Application node space//if (!
        T = (Binode *) malloc (sizeof (Binode)))//is equivalent to the following two lines of code//t = (Binode *) malloc (sizeof (Binode)); if (! ( T = (Binode *) malloc (sizeof (Binode)))) if (! ( T = (Binode *) malloc (sizeof (Binode))) {printf ("Memory allocation failed.
            \ n "); 
        Exit (OVERFLOW);

        }//if//Generate root node t->data = ch;

        Recursive construction of left subtree Createbitree (t->lchild);
    Recursive construction of Right subtree Createbitree (t->rchild); 
}//else//Operation successful return OK; }//createbitree//>>>>>>>>>>>>>>>>>>>>2.
    Traversal of binary trees (4 methods) <<<<<<<<<<<<<<<<<<<<<<<</* Function: Print parameter: Telemtype e The returned value of the element being accessed: status code, Operation successfully returned OK, operation failed return error function: Access element e function, modify the function can modify the element to visitmethod, which needs to be used with the traversal function when using the function.

    */Status Printelement (Telemtype e) {//Use console output to access element printf ("%c", e);
Operation successful return OK; }//printelement//------------------------recursive algorithm-----------------------------/* function: Preordertraverse parameter: Bitree T Binary Tree T Status (* Visit) (telemtype) function pointer, point to Element access function return value: Status code, Operation successfully returned OK, operation failed return error effect: Using binary list storage structure, Visit is the data element operation The application function recursively traverses the recursive algorithm of the binary tree T, calling the function Visit */Status Preordertraverse (Bitree T, status (* Visit) (Telemtype)) for each data element {//root The node exists//if (t) <=> if (t! = NULL) if (t) {//1. Access root node//if (Visit (t->data)) <=> if (Visit (t->data)! = ERROR) if (Visit (T->data)) {//2. Access left child (left subtree) if (Preordertraverse (t->
                    Lchild, Visit) {//3. Access right child (access right subtree) if (Preordertraverse (T->rchild, Visit)) {
                return OK;
    }//if}//if}//if return ERROR; }//if else { 
        return OK; }//else}//preordertraverse/* Function: Inordertraverse parameter: bitree t two fork tree T Status (* Visit) (telemtype) function pointer, point to meta 
Vegetarian Access function return value: Status code, Operation successfully returned OK, operation failed return error effect: Using binary linked list storage structure, visit is a recursive algorithm of sequential traversal of binary tree T in the application function of data element operation, call function visit for each data element */ 

        Status Inordertraverse (Bitree T, status (* Visit) (Telemtype)) {//root node exists if (t) {//if (t) <=> if (t! = NULL) 1. Access the left subtree if (Inordertraverse (t->lchild,visit)) {//2. Access root node//if (Visit (T-&G 
                T;data)) <=> if (Visit (t->data)! = ERROR) if (Visit (T->data)) {//3. Access right subtree
                if (Inordertraverse (t->rchild,visit)) {return OK;
    }//if}//if}//if return ERROR;
    }//if else {return OK; }//else}//inordertraverse/* Function: Postordertraverse parameter: bitree t two fork tree T Status (* Visit) (telemtype) function pointer, refers to return value to element access function: Status code, Operation successfully returned OK, operation failed return ERROR function: Using binary linked list storage structure, visit is the application function of data element operation recursive algorithm for traversing binary tree T, call function visit */Status Postordertraverse (Bitree T) for each data element. Status (* Visit) (Telemtype)) {//root node exists if (t) {//if (t) <=> if (t! = NULL)//1. Access the left subtree if (Po

                Stordertraverse (T->lchild, Visit)) {//2. Access right subtree if (Postordertraverse (T->rchild, Visit)) {
                3. Access root node//if (Visit (t->data)) <=> if (Visit (t->data)! = ERROR)
                if (Visit (T->data)) {return OK;
    }//if}//if}//if return ERROR;
}//if else return OK; }//postordertraverse//-----------------------non-recursive traversal algorithm---------------------------/* function: PreOrderTraverse1 parameter: Bitr EE t two fork tree T Status (* Visit) (telemtype) function pointer, point to Element access function return value: Status code, Operation successfully returns OK, Operation failure returns error effect: Using binary list storage structure, Visit is logarithmic According to the application function of the element operation, the non-recursive algorithm of the binary tree T is iterated, and the function visit */status PreOrderTraverse1 (Bitree T, status (* Vis) is called for each data element.It) (Telemtype) {///two fork-tree non-recursive traversal needs to borrow stacks to hold the backtracking point stack S;

    Initialize stack initstack (S);

    The working pointer p points to the binary root node bitree p = T; Traversal continuation Condition: The work pointer P is not empty or the stack is not empty//while (P | |! Stackisempty (S)))//<=> while (P! = NULL | | Stackisempty (S)! = 1) while (P | |! ( Stackisempty (S))) {///root node exists if (p) {//1. Access root node//if (Visit (p->data)) <=> if (Visit (p->data)! = ERROR) if (!
            Visit (P->data)) {return ERROR;

            }//if//root pointer-in-Stack Push (S, p);
        2. Traverse left subtree p = p->lchild;

            }//if else{//root pointer fallback Pop (S, p);
        3. Traverse right Sub-tree P = p->rchild; 

    }//else}//while//Destroy Stack Destorystack (S);
Operation successful return OK; 
    }//preordertraverse1/* function: InOrderTraverse1 parameter: bitree t two fork tree T Status (* Visit) (telemtype) function pointer, point to element access function Return value: Status code, Operation successfully returned OK, operation failed to return error effect: Using binary linked list storage structure, VisIt is a non-recursive algorithm that iterates through binary tree T in the application function of data element operation, calls the function Visit */status InOrderTraverse1 (Bitree T, status (* Visit) (Telemtype) for each data element.

    {//Two fork-tree non-recursive traversal requires borrowing stacks to hold the backtracking point stack S;

    Initialize stack initstack (S);

    The working pointer p points to the root node bitree p = T; Traversal continuation Condition: The work pointer P is not empty or the stack is not empty//while (P | |! Stackisempty (S)))//<=> while (P! = NULL | | Stackisempty (S)! = 1) while (P | |! ( 

            Stackisempty (s))) {///root node NOT NULL if (p) {///root pointer in stack Push (s, p);
        1. Traverse left subtree p = p->lchild;

            }//if else{//root pointer fallback Pop (S, p); 2. Access root node//if (Visit (p->data)) <=> if (Visit (p->data)! = ERROR) if (!
            Visit (P->data)) {return ERROR; 
        }//if//3. Traversing right subtree P = p->rchild; 

    }//else}//while//Destroy Stack Destorystack (S);
Operation successful return OK; }//inordertraverse1/* function: PostOrderTraverse1 parameter: bitree T two fork TreeT status (* Visit) (telemtype) function pointer, point to Element access function return value: Status code, Operation successfully returned OK, operation failed return error effect: Using binary linked list storage structure, Visit is the application of data element operation The function Visit the non-recursive algorithm to traverse the binary tree T, calling the function on each data element */Status PostOrderTraverse1 (Bitree T, status (* Visit) (Telemtype)) {//p

    and q are all working pointers//p points to the currently traversed node, Q points to the last traversed node of bitree p = T, q = NULL;

    The binary tree non-recursive traversal needs to borrow the stack to save the backtracking point stack s;

    Initialize stack initstack (s); Traversal continuation Condition: The work pointer P is not empty or the stack is not empty//while (P | |! Stackisempty (S))//<=> while (P! = NULL | | Stackisempty (S)! = 1) while (P | |! 
        Stackisempty (s)) {//follow the root of the tree, go straight to the left branch until you encounter the end of the leftmost branch (left child of the leaf node).

            while (p) {//root node into stack push (S, p);
        Access left sub-tree P = p->lchild;

        }//while//Resets the value of the pointer q to NULL q = NULL; The stack is not empty while (!

            Stackisempty (s)) {//p points to the top element of the stack GetTop (s, p); 
      This condition indicates that P points to the leaf node or the left and right subtrees of P are traversed if (P->rchild = = NULL | | p->rchild = = q) {//Access root node          if (Visit (p->data)) <=> if (Visit (p->data)! = ERROR) if (!    
                Visit (P->data)) {return ERROR;
                }//if if (p = = T) {return ERROR;

                }//if//q points to the last traversed node of P q = p;
            Root pointer out of stack Pop (s, p);

                }//if else{//Access right sub-tree P = p->rchild;              
            Exit inner loop break; 

    }//else}//while}//while//Destroy stack Destorystack (s);
Operation successful return OK; }//postordertraverse1/* function: LevelOrderTraverse1 parameter: bitree t two fork tree T Status (* Visit) (telemtype) function pointer, point to Element Q function return value: Status code, Operation successfully returned OK, operation failed return error effect: Using binary linked list storage structure, visit is the application of data element operation function sequence traversal binary tree T algorithm, call function visit per data element */Sta

    Tus LevelOrderTraverse1 (Bitree T, Status (* Visit) (Telemtype)) {//sequence traversal requires queuing queue Q; The work pointer p points toroot node Bitree p = T;

        The root node is not empty if (t) {//if (t) <=> if (t! = NULL)//Initialize queue initqueue (Q);

        Root node into the queue EnQueue (Q, T); Queue is not empty//while (! Queueempty (q)) <=> while (queueempty (q) = = 0) while (!

            Queueempty (q)) {//root node out of team DeQueue (Q, p); Access the root node if (!
            Visit (P->data)) {return ERROR; }//if//left child not empty if (p->lchild) {//left child into queue EnQueue (Q, P->lch   
            ILD);
            }//if if (p->rchild) {//Right child into queue EnQueue (Q, p->rchild);

       }//if}//while//output line, make the display beautiful printf ("\ n"); 
    When the queue is exhausted, it is destroyed, freeing its memory space Destoryqueue (Q);
}//IF//Operation successful return OK; }//levelordertraverse1//>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>3. Two Fork Tree Information <<<<<<<<<<<<<<< <<<<<<<<<<<<<<<<<<<<<<<<<<< </* Function: bitreedepth parameter: bitree t two fork tree T return value: If the binary tree T exists, returns the depth (height) of T, otherwise returns 0 effect: If the binary tree T exists, recursively find the depth of the binary tree T */int Bitre

    Edepth (Bitree T) {//thigh is two fork tree height, Leftthigh is Zuozi height, Rightthigh is right subtree height int thigh, leftthigh, Rightthigh; The root node is empty and the tree height is 0 if (!
    T) {return 0;

        }//if the else{//root node is not empty, the height of the recursive calculation tree///recursion is calculated Zuozi height Leftthigh = bitreedepth (t->lchild);

        Recursively finding the right subtree height Rightthigh = bitreedepth (t->rchild); 
         The left and right sub-trees may be highly unequal, as defined by the height of the tree//should take the height of the Saozi in the tree.

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.