C | 二叉树的创建销毁遍历,计算叶子数,深度以及对二叉树进行拷贝等基本操作

  • 二叉树是一块比较重要的知识点,而且是从线性结构到树形结构的一个跨越,建议大家动手实现以下。
  • 树是递归算法最好的应用,当然不嫌麻烦的话也可以用栈。

前序遍历初始化树:

void InitializeTree(Tree *T) {
    char ch;
    scanf("%c",&ch);
    if (ch == '*') {
        (*T) = NULL;
    }
    else {
        if (!((*T) = (Node*)malloc(sizeof(Node))))
            exit(-1);
        (*T)->data = ch;
        InitializeTree(&((*T)->lchild));
        InitializeTree(&((*T)->rchild));    
    }

}

后序遍历销毁二叉树

void DestroyTree(Tree *T) {
    if ((*T)) {
        DestroyTree(&((*T)->lchild));
        DestroyTree(&((*T)->rchild));
        free((*T));
        (*T) = NULL;
    }   
}

前序遍历打印二叉树

void PreOrderTraverse(Tree T, void (*Visit)(ElemType e)) {
    if (T) {
        Visit(T->data);
        PreOrderTraverse(T->lchild,Visit);
        PreOrderTraverse(T->rchild,Visit);
    }
}

中序遍历打印二叉树

void InOrderTraverse(Tree T, void (*Visit)(ElemType e)) {
    if(T) {
        InOrderTraverse(T->lchild,Visit);
        Visit(T->data);
        InOrderTraverse(T->rchild,Visit);
    }   
}

后序遍历打印二叉树

void PostOrderTraverse(Tree T, void (*Visit)(ElemType e)) {
    if (T) {
        PostOrderTraverse(T->lchild,Visit);
        PostOrderTraverse(T->rchild,Visit);
        Visit(T->data); 
    }
}

前序遍历计算叶子结点数

void CountLeaf1(Tree T, int *count) {
    if (T) {
        if (!(T->lchild) && !(T->rchild)) {
            (*count)++; 
        }
        CountLeaf1(T->lchild,count);
        CountLeaf1(T->rchild,count);    
    }
    else 
        (*count) = 0;
}

计算叶子结点的简化方法:

unsigned int CountLeaf2(Tree T) {
    if (!T) {
        return 0;
    }
    else if (!T->lchild && !T->rchild)
        return 1;
    else
        return CountLeaf2(T->lchild)+CountLeaf2(T->rchild);
}

后序遍历计算二叉树深度

unsigned int DepthOfTree(Tree T) {  
    if (T) {
        return DepthOfTree(T->lchild) > DepthOfTree(T->rchild) ? DepthOfTree(T->lchild) + 1 : DepthOfTree(T->rchild) + 1;
    }
    return 0;
}

后序遍历复制二叉树

Tree CopyTree(Tree T) {
    if (T) {
        Tree ltree = NULL;
        Tree rtree = NULL;
        if (T->lchild)
            ltree = CopyTree(T->lchild);
        if (T->rchild)
            rtree = CopyTree(T->rchild);
        Tree New = (Node*)malloc(sizeof(Node));
        New->data = T->data;
        New->lchild = ltree;
        New->rchild = rtree;
        return New;
    }
    return NULL;    
}
  • 是不是惊喜的发现所有的算法都是用递归来实现
  • 递归在二叉树和树种应用真的很广,大家又不太理解的建议找个二叉树的基本图手动模拟算法去遍历尝试一下,好记性不如烂笔头

最后附上源码:

Tree.h

#ifndef _TREE_H_
#define _TREE_H_
#include <stdbool.h>

typedef char ElemType;

typedef struct BiTNode {
    ElemType data;
    struct BiTNode *lchild, *rchild;
} Node, *Tree;

//Initialize a tree
void InitializeTree(Tree *T);

//Destroy a tree
void DestroyTree(Tree *T);

//void PreOrderTraverse(Tree T);

//Pre-Order traversing a tree
void PreOrderTraverse(Tree T, void (*Visit)(ElemType e));

//In-Order traversing a tree
void InOrderTraverse(Tree T, void (*Visit)(ElemType e));

//using in c++
void InOrderTraverse2(Tree T, void (*Visit)(ElemType e));

//Post-Order traversing a tree
void PostOrderTraverse(Tree T, void (*Visit)(ElemType e));

//Level-Order traversing a tree
void LevelOrderTraverse(Tree T, void (*Visit)(ElemType e));

//Count the number of leaf nodes in the binary tree
void CountLeaf1(Tree T,  int *count);

//Another way to count the number of leaf nodes in the binary tree
unsigned int CountLeaf2(Tree T);

//Calculate the depth of the binary tree
unsigned int DepthOfTree(Tree T);

//Copy the binary tree
Tree CopyTree(Tree T);
#endif

Tree.c

#include <stdio.h>
#include "Tree.h"
#include <stdlib.h>
#include <string.h>
#include "../stack/Stack.h"

void InitializeTree(Tree *T) {
    char ch;
    scanf("%c",&ch);
    if (ch == '*') {
        (*T) = NULL;
    }
    else {
        if (!((*T) = (Node*)malloc(sizeof(Node))))
            exit(-1);
        (*T)->data = ch;
        InitializeTree(&((*T)->lchild));
        InitializeTree(&((*T)->rchild));    
    }

}

void DestroyTree(Tree *T) {
    if ((*T)) {
        DestroyTree(&((*T)->lchild));
        DestroyTree(&((*T)->rchild));
        //(*T)->data='*';
        free((*T));
        (*T) = NULL;
    }   
}

void PreOrderTraverse(Tree T, void (*Visit)(ElemType e)) {
    if (T) {
        Visit(T->data);
        PreOrderTraverse(T->lchild,Visit);
        PreOrderTraverse(T->rchild,Visit);
    }
}

void InOrderTraverse(Tree T, void (*Visit)(ElemType e)) {
    if(T) {
        InOrderTraverse(T->lchild,Visit);
        Visit(T->data);
        InOrderTraverse(T->rchild,Visit);
    }   
}

void PostOrderTraverse(Tree T, void (*Visit)(ElemType e)) {
    if (T) {
        PostOrderTraverse(T->lchild,Visit);
        PostOrderTraverse(T->rchild,Visit);
        Visit(T->data); 
    }
}
//I'm too lazy to want to call stack interface,so this function need to realise using c++
/*void InOrderTraverse2(Tree T, void (*Visit)(ElemType e)) {
    stack<Tree> S;
    Tree p;
    p = T;
    S.push(p);
    while (p->lchild != NULL) {
        p = p->lchild;
        S.push(p);
    }
        while (!S.empty()) {
            p = S.top();
            Visit(p->data);
            S.pop();
            if (p->rchild != NULL) {
                p=p->rchild;
                S.push(p);
                while (p->lchild != NULL) {
                    p = p->lchild;
                    S.push(p);
                }           
            }
        }
}
*/
void CountLeaf1(Tree T, int *count) {
    if (T) {
        if (!(T->lchild) && !(T->rchild)) {
            (*count)++; 
        }
        CountLeaf1(T->lchild,count);
        CountLeaf1(T->rchild,count);    
    }
    else 
        (*count) = 0;
}

unsigned int CountLeaf2(Tree T) {
    if (!T) {
        return 0;
    }
    else if (!T->lchild && !T->rchild)
        return 1;
    else
        return CountLeaf2(T->lchild)+CountLeaf2(T->rchild);
}

unsigned int DepthOfTree(Tree T) {  
    if (T) {
        return DepthOfTree(T->lchild) > DepthOfTree(T->rchild) ? DepthOfTree(T->lchild) + 1 : DepthOfTree(T->rchild) + 1;
    }
    return 0;
}

Tree CopyTree(Tree T) {
    if (T) {
        Tree ltree = NULL;
        Tree rtree = NULL;
        if (T->lchild)
            ltree = CopyTree(T->lchild);
        if (T->rchild)
            rtree = CopyTree(T->rchild);
        Tree New = (Node*)malloc(sizeof(Node));
        New->data = T->data;
        New->lchild = ltree;
        New->rchild = rtree;
        return New;
    }
    return NULL;    
}

main.c

#include "Tree.h"
#include <stdio.h>
void Visit(ElemType e);
void Visit(ElemType e) {
    printf("%c\n",e);
}
int main () {
    int count = 0;
    Tree T;
    InitializeTree(&T);
    /*CountLeaf1(T,&count);
    printf("%d\n",count);
    printf("%d\n",DepthOfTree(T));
    PreOrderTraverse(T,Visit);
    InOrderTraverse(T,Visit);
    PostOrderTraverse(T,Visit);*/
    Tree A = CopyTree(T);
    PreOrderTraverse(A,Visit);
    DestroyTree(&T);
    DestroyTree(&A);
    return 0;   
}

猜你喜欢

转载自blog.csdn.net/perry0528/article/details/82505568
今日推荐