美文网首页
C语言实现二叉树的各种遍历及求解深度

C语言实现二叉树的各种遍历及求解深度

作者: IT之旅 | 来源:发表于2020-07-08 09:43 被阅读0次

    一、介绍

    二叉树是一种重要的数据结构,在很多方面都有重要的应用,此文主要记录了二叉树的基础知识,包括二叉树的建立、前中后序遍历方式、层次遍历方式、求解二叉树的深度、求解二叉树的节点总数、求解二叉树每层的节点数目等。(更好的阅读体验,请移步我的个人博客)

    二、实现思路

    主要借助栈和队列方式实现二叉树的非递归访问等操作,二叉树的建立采用递归方式。层次遍历时,借助队列数据结构,将根节点入队,当队列不为空时,退出队列的一个节点,判断此节点是否有左孩子,如有则访问,并将此孩子入队列,然后判断此节点是否有右孩子,如有则访问,并将有孩子入队列;重复此过程即可。

    三、实现代码

    #include<stdio.h>
    #include<malloc.h>
    #define MAXSIZE 100
    typedef char dataType;
    //二叉树结构
    typedef struct bnode{
        dataType data;
        struct bnode *lChild,*rChild;
    }Bnode,*BTree;
    //队列结构
    typedef struct {
        BTree data[MAXSIZE];
        int front,rear;
    }SeqQueue,*PSeqQueue;
    //栈的结构
    typedef struct {
        BTree data[MAXSIZE];
        int top;
    }SeqStack,*PSeqStack;
     
    //队列的初始化
    PSeqQueue initSeqQueue(){
        PSeqQueue  queue;
        queue = (PSeqQueue)malloc(sizeof(SeqQueue));
        if(queue){
            queue->front = queue->rear = 0;
        }
        return queue;
    }
    //判断队列是否为空
    int emptyQueue(PSeqQueue queue){
        if(queue && queue->front==queue->rear){
            return 1;
        }else{
            return 0;
        }
    }
    //入队列
    int pushQueue(PSeqQueue queue,Bnode *node){
        if((queue->rear+1)%MAXSIZE == queue->front){//判断队列是否满了
            return -1;
        }else{
            queue->rear = (queue->rear+1)%MAXSIZE;//位置为0的地址空间不用,方便判断是否为空
            queue->data[queue->rear] = node;
            return 1;
        }
    }
    //出队列
    int popQueue(PSeqQueue queue,BTree *node){
        if(emptyQueue(queue)){
            return -1;
        }else{
            queue->front = (queue->front +1)%MAXSIZE;
            *node = queue->data[queue->front];
            return 1;
        }
    }
    //读取队头元素
    int frontQueue(PSeqQueue queue,BTree *node){
        if(queue->rear == queue->front){
            return -1;
        }else{
            *node = queue->data[(queue->front+1)%MAXSIZE];
            return 1;
        }
    }
    //销毁队列
    void destroyQueue(PSeqQueue *queue){
        if(*queue){
            free(*queue);
            *queue = NULL;
        }
    }
    //栈的初始化
    PSeqStack initStack(){
        PSeqStack stack;
        stack = (PSeqStack)malloc(sizeof(SeqStack));
        if(stack){
            stack->top = -1;
        }
        return stack;
    }
    //判断栈是否为空    1,空;0,非空
    int emptyStack(PSeqStack stack){
        if(stack->top == -1){
            return 1;
        }else{
            return 0;
        }
    }
    //入栈
    int pushStack(PSeqStack stack,Bnode *node){
        if(stack->top == MAXSIZE-1){
            return 0;
        }else{
            stack->top ++;
            stack->data[stack->top] = node;
            return 1;
        }
    }
    //出栈
    int popStack(PSeqStack stack,BTree *node){
        if(emptyStack(stack) == 1){
            return 0;
        }else{
            *node = stack->data[stack->top];
            stack->top --;
            return 1;
        }
    }
    //打印元素
    void visit(char ch){
        printf("%c \t",ch);
    }
     
    //二叉树的建立
    BTree createTree(){
        BTree tree;
        dataType str;
        str = getchar();
        if(str == '#'){
            tree = NULL;
        }else{
            tree = (BTree)malloc(sizeof(Bnode));
            tree->data = str;
            tree->lChild = createTree();
            tree->rChild = createTree();
        }
        return tree;
    }
    //先序遍历二叉树
    void perOrder(BTree tree){
        PSeqStack stack;
        BTree p = tree;
        stack = initStack();
        while(p || ! emptyStack(stack)){
            if(p){
                visit(p->data);
                pushStack(stack,p);
                p = p->lChild;
            }else{
                popStack(stack,&p);
                p = p->rChild;
            }
        }
    } 
    //中序遍历此二叉树
    void inOrder(BTree tree){
        PSeqStack stack;
        BTree p = tree;
        stack = initStack();
        while(p || !emptyStack(stack)){
            if(p){
                pushStack(stack,p);
                p = p->lChild;
            }else{
                popStack(stack,&p);
                visit(p->data);
                p = p->rChild;
            }
        }
    }
     
    //后序遍历打印元素
    void postOrder(BTree tree){
        PSeqStack s1,s2;
        BTree p = tree;
        s1 = initStack();
        s2 = initStack();
        while(p || !emptyStack(s2)){
            if(p){
                pushStack(s1,p);
                pushStack(s2,p);
                p = p->rChild;
            }else{
                popStack(s2,&p);
                p = p->lChild;
            }
        }
        while(!emptyStack(s1)){
            popStack(s1,&p);
            visit(p->data);
        }
    }
    //层次遍历二叉树
    void levelOrder(BTree tree ){
        BTree p = tree;
        PSeqQueue queue = initSeqQueue();
        if(p){
            pushQueue(queue,p);
            while(!emptyQueue(queue)){
                popQueue(queue,&p);
                visit(p->data);
                if(p->lChild){
                    pushQueue(queue,p->lChild);
                }
                if(p->rChild){
                    pushQueue(queue,p->rChild);
                }
            }
        }
    }
    //求二叉树的高度
    int height(BTree tree){
        int h1,h2;
        if(tree == NULL){
            return 0;
        }else{
            h1 = height(tree->lChild);
            h2 = height(tree->rChild);
            if(h1>h2){
                return h1+1;
            }else{
                return h2+1;
            }
        }
    }
    //求解二叉树每层节点的个数
    void levelCount(BTree tree,int l,int num[]){
        if(tree){
            num[l]++;
            levelCount(tree->lChild,l+1,num);
            levelCount(tree->rChild,l+1,num);
        }
    }
    //求解二叉树节点总数
    int countTree(BTree tree){
        int lCount,rCount;
        if(tree == NULL){
            return 0;
        }
        lCount = countTree(tree->lChild);
        rCount = countTree(tree->rChild);
        return lCount + rCount +1;
    }
     
    int main(){
        BTree tree = createTree();
        int i=0;
        int countNum[10]={0,0,0,0,0,0,0,0,0,0},l=1,treeHeight,treeCount;//记录每层的节点数,l从1开始,树的深度
        
        treeHeight = height(tree);
        printf("\n此二叉树的深度为: %d\n",treeHeight);
     
        treeCount = countTree(tree);
        printf("此二叉树的节点总数为: %d\n",treeCount);
     
        levelCount(tree,l,countNum);
        printf("此二叉树各层的节点数为: ");
        for(i=1;i<=treeHeight;i++){
            printf("第%d层数目: %d,  ",i,countNum[i]);
        }
        printf("\n\n");
     
        printf("先序遍历此二叉树: ");
        perOrder(tree);
        printf("\n");
     
        printf("中序遍历此二叉树: ");
        inOrder(tree);
        printf("\n");
     
        printf("后序遍历此二叉树: ");
        postOrder(tree);
        printf("\n");
     
        printf("层次遍历此二叉树: ");
        levelOrder(tree);
        printf("\n");
        return 0;
    }
    

    四、实验结果截图

    实验结果截图.png

    相关文章

      网友评论

          本文标题:C语言实现二叉树的各种遍历及求解深度

          本文链接:https://www.haomeiwen.com/subject/ojsqcktx.html