二叉树的常见算法

 

二叉树的遍历

  • 先序遍历指的就是先访问本节点,再访问该节点的左孩子和右孩子;
  • 中序遍历指的就是:先访问左孩子,再访问本节点,最后访问右孩子;
  • 后序遍历指的就是:先访问左右孩子,最后访问本节点。
  • 层次遍历:按照树的每一层(高度)进行遍历。

深度遍历

  • 递归实现:先序、中序、后序
  • 非递归实现:先序、中序、后序

层次遍历

 

深度遍历

递归实现先序、中序、后序

#include <stdio.h>

//声明树类型
typedef struct TREEtag TREEtagNode;

struct TREEtag {
    int val;
    TREEtagNode *left;
    TREEtagNode *right;
};


//访问
void get(TREEtagNode *node){
    printf("%d\n",node->val);
}


//先序遍历
void r1(TREEtagNode *node){
    
    if(node !=  NULL)
    {
    //
    get(node);
    //
    r1(node->left);
    
    //
    r1(node->right);
    
    }

}

//中序遍历
void r2(TREEtagNode *node){

    if(node !=  NULL)
    {
    //
    r2(node->left);
    //
    get(node);
    //
    r2(node->right);
    
    }

}


//后序遍历
void r3(TREEtagNode *node){
    
    if(node !=  NULL)
    {
    //
    r3(node->left);
    //    
    r3(node->right);
    //
    get(node);
    
    }

}




int main () {
    TREEtagNode A0,A1,A2,A3,A4;
    A0.left = &A1;
    A0.right = &A2;
    A0.val = 10;
    
    A1.left = &A3;    
    A1.right = NULL;
    A1.val = 2;
    
    
    A2.left = &A4;
    A2.right = NULL;
    A2.val = 7;
    
    
    A3.left = NULL;
    A3.right = NULL;
    A3.val = 5;
    
    A4.left = NULL;
    A4.right = NULL;
    A4.val = 9;
    
    printf("初始化成功\n");
    
    printf("先序遍历:\n");
    r1(&A0);
    
    printf("中序遍历:\n");
    r2(&A0);
    
    printf("后序遍历:\n");
    r3(&A0);
    return 0;
}
初始化成功
先序遍历:
10
2
5
7
9
中序遍历:
5
2
10
9
7
后序遍历:
5
2
9
7
10
运行结果

 

非递归实现:先序、中序、后序

#include <stdio.h>

//声明树类型
typedef struct TREEtag TREEtagNode;

struct TREEtag {
    int val;
    TREEtagNode *left;
    TREEtagNode *right;
};


//访问
void get(TREEtagNode *node){
    printf("%d\n",node->val);
}



#define Size 10
typedef struct stacktag
{
    TREEtagNode *a[Size];
    int top;
}stack;


//先序遍历
void r4(TREEtagNode *node){
    if(node != NULL)
    {
    //初始化栈
    stack Stack;
    Stack.top = -1;
    
    //初始化临时节点
    TREEtagNode *p;
    
    //把根节点插入栈
    Stack.a[++Stack.top] = node;
    
    //开始遍历
    while(Stack.top != -1)
    {
        //取出元素
        p = Stack.a[Stack.top--];
        
        //操作
        get(p);
        
        //存储元素:判断当前节点的左右节点是否存在,如果存在,则先存右元素,后存左元素
        if(p->right != NULL)
        Stack.a[++Stack.top] = p->right;
        if(p->left != NULL)
        Stack.a[++Stack.top] = p->left;
        
    }
    }

}



//中序遍历
void r5(TREEtagNode *node){
    if(node != NULL)
    {
        //初始化栈
        stack Stack;
        Stack.top = -1;

        //初始化临时节点
        TREEtagNode *p = NULL;

        p = node;

        //开始遍历
        while(Stack.top != -1 || p != NULL)
            {
            
                while(p != NULL)
                    {
                        Stack.a[++Stack.top] = p;
                        p = p->left;
                    }
                if(Stack.top != -1)
                    {
                        p = Stack.a[Stack.top--];
                        //操作
                        get(p);
                        p = p->right;                
                    }
            }
    }

}


//双栈法后序遍历
void r6(TREEtagNode *node){
    if(node != NULL)
    {
    //初始化栈
    stack Stack1;
    Stack1.top = -1;

    stack Stack2;
    Stack2.top = -1;
    
    //初始化临时节点
    TREEtagNode *p;
    
    //把根节点插入栈
    Stack1.a[++Stack1.top] = node;
    
    //开始遍历
    while(Stack1.top != -1)
        {
            //取出元素
            p = Stack1.a[Stack1.top--];

            Stack2.a[++Stack2.top] = p;

            //存储元素:判断当前节点的左右节点是否存在,如果存在,则先存右元素,后存左元素
            if(p->left != NULL)
            Stack1.a[++Stack1.top] = p->left;

            if(p->right != NULL)
            Stack1.a[++Stack1.top] = p->right;


        }
    while(Stack2.top != -1)
        {
            p = Stack2.a[Stack2.top--];
            //操作
            get(p);

        }
    }

}


int main () {
    TREEtagNode A0,A1,A2,A3,A4;
    A0.left = &A1;
    A0.right = &A2;
    A0.val = 10;
    
    A1.left = &A3;    
    A1.right = NULL;
    A1.val = 2;
    
    
    A2.left = &A4;
    A2.right = NULL;
    A2.val = 7;
    
    
    A3.left = NULL;
    A3.right = NULL;
    A3.val = 5;
    
    A4.left = NULL;
    A4.right = NULL;
    A4.val = 9;
    
    printf("初始化成功\n");
    
    printf("先序遍历:\n");
    r4(&A0);
    
    printf("中序遍历:\n");
    r5(&A0);
    
    printf("后序遍历:\n");
    r6(&A0);
    return 0;
}
初始化成功
先序遍历:
10
2
5
7
9
中序遍历:
5
2
10
9
7
后序遍历:
5
2
9
7
10
运行结果
posted @ 2020-01-14 17:25  -零  阅读(588)  评论(0编辑  收藏  举报