vlambda博客
学习文章列表

第五章编程任务与二叉树基本操作

基本内容

该代码包含树的基本操作和智慧树编程任务
     1. 树的基本操作:
         ①空二叉树初始化
         ②.广义表创建二叉树
         ③.查找某节点
         ④找左右孩子节点
         ⑤.递归求树的高度
         ⑥.广义表形式输出二叉树
         ⑦.二叉树销毁
         ⑧.访问二叉树节点
         ⑨.递归前/中/后/层序遍历二叉树
     2. 智慧树编程任务
         非递归实现前中后序遍历

注意事项

注意事项
   ①.不要抄不要抄不要抄
   ②.写这的目的是为了方便学习,方便复习
   ③.自己手敲,不要一不会就找,实在实在没办法了可以参考下,也不要只看这个,多看看很多相关博文,收获会很大
   ④.b站懒猫老师的树讲的很好,有时间可以去看看,然后自己有时间把功能实现
   ⑤.暂时没空写具体的函数的步骤了,遇到不会的去推荐看b站懒猫老师视频(力推)

代码

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef struct BTNode
{

    struct BTNode *lchild;
    struct BTNode *rchild;
    char data;
}BTNode;

typedef struct elem
{

    BTNode *ptr;
    int flag;
}Elem;

//空二叉树初始化 
void init(BTNode *&T)
{
    T = NULL;
}

//广义表创建二叉树 
void creatBiTree(BTNode *&T, char str[])
{
    BTNode *st[MAXSIZE], *p = NULL;
    int tag, top = -1;
    T = NULL;
    for(int i = 0; str[i]; i++)
    {
        char c = str[i];
        switch(c)
        {
            case '(':
                st[++top] = p;
                tag = 1;//表明后面遇到的节点为左孩子 
                break;
            case ')':
                top--;
                break;
            case ',':
                tag = 2;//表明后面遇到的孩子为右孩子 
                break;              
            default:
                p = (BTNode *)malloc(sizeof(BTNode));
                p -> data = c;
                p -> lchild = p -> rchild = NULL;
                if(T == NULL)
                    T = p;
                else
                {
                    switch(tag)
                    {
                        case 1:
                            st[top] -> lchild = p;
//                            printf("st[top] -> data = %c,st[top] -> lchild -> data = %c\n",st[top] -> data,st[top] -> lchild -> data);
                            break;
                        case 2:
                            st[top] -> rchild = p;
//                            printf("st[top] -> data = %c,st[top] -> rchild -> data = %c\n",st[top] -> data,st[top] -> rchild -> data);
                            break;
                    }   
                } 
                break;
        }
    }
}

//查找某节点 
BTNode *FindNode(BTNode *T, char x)//递归返回值BTNode * 
{
    BTNode *p;
    //递归终止条件 
    if(T == NULLreturn NULL;//未找到终止条件 
    else if(T -> data == x) return T;//找到终止条件 
    else
    {
        //本级递归 
        p = FindNode(T -> lchild,x);//左子树查找 
        if(p != NULLreturn p;
        else return FindNode(T -> rchild,x);//右子树查找 
    }


//找左孩子节点
BTNode *LchildNode(BTNode *p)
{
    return p -> lchild;


//找右孩子节点
BTNode *RchildNode(BTNode *p)
{
    return p -> rchild;


//递归求树的高度, 
int BiTreeDepth(BTNode *T)//递归返回值,本层高度 
{
    int ldepth,rdepth;
    if(T == NULLreturn 0//递归终止条件:空树 
    else
    {   
        ldepth = BiTreeDepth(T -> lchild);
        rdepth = BiTreeDepth(T -> rchild);
        return ldepth > rdepth ? (ldepth + 1) : (rdepth + 1);
    } 
}

//输出二叉树
void printBiTree(BTNode *T)
{
    if(T == NULLreturn;
    else
    {
        printf("%c",T -> data);
        if(T -> lchild || T -> rchild)
        {
            printf("(");
            printBiTree(T -> lchild);
            if(T -> rchild) printf(",");
            printBiTree(T -> rchild);
            printf(")");
        }
    }   


//欠:横向输出二叉树

//销毁二叉树
void destroyBiTree(BTNode *T)
{
    if(T == NULLreturn;
    else
    {
        destroyBiTree(T -> lchild);
        destroyBiTree(T -> rchild);
        free(T);    
    }   


//访问二叉树节点
void visit(BTNode *p)
{
    printf("%c",p -> data); 


//前序遍历二叉树
void preOrderTraverse(BTNode *T)
{
    if(T == NULLreturn;
    else
    {
        visit(T);
        preOrderTraverse(T -> lchild);
        preOrderTraverse(T -> rchild);
    }


//中序遍历二叉树
void inOrderTraverse(BTNode *T)
{
    if(T == NULLreturn;
    else
    {
        inOrderTraverse(T -> lchild);
        visit(T);
        inOrderTraverse(T -> rchild);
    }


//后序遍历二叉树
void postOrderTraverse(BTNode *T)
{
    if(T == NULLreturn;
    else
    {
        postOrderTraverse(T -> lchild);
        postOrderTraverse(T -> rchild);
        visit(T);
    }


//层序遍历二叉树
void  levelTraverse(BTNode *T)
{
    BTNode *q[MAXSIZE];
    int tt = 0, hh = 0;
    q[tt++] = T;//入队 
    while(hh != tt)//判断队列是否为空 
    {
        BTNode *p = q[hh++];//出队,并判断hh 
        if(hh == MAXSIZE) hh = 0;
        printf("%c",p -> data);
        if(p -> lchild) 
        {
            if(tt == MAXSIZE) tt = 0;//判断tt,并入队 
            q[tt++] = p -> lchild;
        }
        if(p -> rchild)
        {
            if(tt == MAXSIZE) tt = 0;
            q[tt++] = p -> rchild;
        }
    }
}

//前序遍历非递归算法
void preOrderTraverseNRE(BTNode *T)
{
    BTNode *st[MAXSIZE];
    BTNode *p = T;
    int tt = 0;
    while(p != NULL || tt > 0)
    {
        while(p != NULL)
        {
            printf("%c",p -> data);
            st[++tt] = p;
            p = p -> lchild;
        }
        if(tt > 0)
        {
            p = st[tt--];
            p = p -> rchild;
        }
    }   


//中序遍历非递归实现
void inOrderTraverseNRE(BTNode *T)
{
    BTNode *st[MAXSIZE];
    BTNode *p = T;
    int tt = 0;
    while(p != NULL || tt > 0)
    {
        while(p != NULL)
        {
            st[++tt] = p;
            p = p -> lchild;
        }   
        if(tt > 0)
        {
            p = st[tt--];
            printf("%c",p->data);
            p = p -> rchild;
        }
    }   
}

//后序遍历非递归实现
void  postOrderTraverseNRE(BTNode *T)
{
    Elem st[MAXSIZE];
    BTNode *p = T;
    int tt = 0;
    while(p != NULL || tt > 0)
    {
        //访问左子树,并入栈 
        while(p != NULL)
        {
            st[++tt].ptr = p;
            st[tt].flag = 1;
            p = p -> lchild;
        }
        //左子树访问结束,取栈顶元素,①访问右子树,②.访问栈顶节点值s 
        Elem elem = st[tt--];
        p = elem.ptr;
        if(elem.flag == 1)//说明只访问过左子树,取出栈顶节点,访问右子树 
        {
            elem.flag = 2;
            st[++tt] = elem;
            p = p -> rchild;
        }
        else//已经访问过右子树,可以获取子树根节点的值 
        {
            visit(p);
            p = NULL
        }

    }
}

int main()
{
    BTNode *T;
    char str[30] = "A(B(D,E(G,)),C(,F)";
    init(T);
    creatBiTree(T,str);


    printf("=====高度测试=====\n");
    int depth = BiTreeDepth(T);
    printf("depth = %d\n",depth);

    printf("=====查找节点测试=====\n");
    BTNode *p = FindNode(T,'E');
//    printf("%c -> lchild -> data = %c\n",p -> data,p -> lchild -> data);
//    printf("%c -> rchild -> data = %c\n",p -> data,p -> rchild -> data);

    printf("=====左孩子测试=====\n");
    p =  LchildNode(p);
    if(p == NULLprintf("无左孩子\n");
    else printf("左孩子为:%c\n",p -> data);

    printf("=====右孩子测试=====\n");
    p =  LchildNode(p);
    if(p == NULLprintf("无右孩子\n");
    else printf("右孩子为:%c\n",p -> data);

    printf("=====打印二叉树测试=====\n");
    printBiTree(T);
    printf("\n");
//    printf("=====释放二叉树测试=====\n");
//    destroyBiTree(T);
    printf("\n\n\n");
    printf("=====前序遍历二叉树测试=====\n");
    preOrderTraverse(T);
    printf("\n");  

    printf("=====中序遍历二叉树测试=====\n");
    inOrderTraverse(T);
    printf("\n"); 

    printf("=====后序遍历二叉树测试=====\n");
    postOrderTraverse(T);
    printf("\n");

    printf("=====层序遍历二叉树测试=====\n");
    levelTraverse(T);
    printf("\n\n\n");


    printf("=====前序遍历(非递归)二叉树测试=====\n");
    preOrderTraverseNRE(T);
    printf("\n"); 

    printf("=====中序遍历(非递归)二叉树测试=====\n");
    inOrderTraverseNRE(T);
    printf("\n"); 

    printf("=====后序遍历(非递归)二叉树测试=====\n");
    postOrderTraverseNRE(T);
    printf("\n"); 
}