数据结构——排序二叉树的前序、中序、后序遍历

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/**定义树中的节点结构体,
 *该结构体包含节点的数据int val
 *左子节点结构体指针Node* lchild
 *右子节点结构体指针Node* rchild
 **/
typedef struct Node{
    int val;
    struct Node* lchild,*rchild;
}Node;
/**定义树结构体,
 *该结构体包含树的根节点Node* root
 *树的节点个数int n
 **/
typedef struct Tree{
    Node* root;
    int n;
}Tree;
/**
 * 函数声明
 **/
void preorderNode(Node*);
void preorderTree(Tree*);
void inorderNode(Node*);
void inorderTree(Tree*);
void postorderNode(Node*);
void postorderTree(Tree*);
//初始化一个节点
Node* getNewNode(int val){
    Node* N=(Node*)malloc(sizeof(Node));//申请struct Node结构体类型的空间
    N->val=val;//节点赋值val
    N->lchild=N->rchild=NULL;//成员变量child和rchild均赋值为空
    return N;//返回节点
}
//初始化树
Tree* getNewTree(){
    Tree* tree=(Tree*)malloc(sizeof(Tree));//申请struct Tree结构体类型的空间
    tree->n=0;//树的初始节点个数为0个
    tree->root=NULL;//根节点为空
    return tree;//返回树
}
//向树中存在的节点插入左子树和右子树
Node* insertNode(Node *root,int val){
    if(root==NULL){return getNewNode(val);}//如果节点为空,则新建一个节点,并返回保存这个插入值的新建节点
    if(root->val==val){return root;}//如果根节点的值和要插入的值相等,则返回该根节点
    if(root->val>val){root->lchild=insertNode(root->lchild,val);}//如果根节点的值大于要插入的值,则在左子树节点插入该节点,由于使用了递归函数,一直会遍历到最左端的叶子节点
    else{root->rchild=insertNode(root->rchild,val);}//如果根节点的值小于要插入的值,则在右子树节点插入该节点,由于使用了递归函数,一直会遍历到最右端的叶子节点
    return root;//返回插入新节点完成的根节点
}
//向树中插入节点
void insert(Tree *tree,int val){
    tree->root=insertNode(tree->root,val);//插入左或右子树节点
    tree->n++;//树的节点数增加1
    return;
}
//删除节点
void  clearNode(Node* node){
    if(node==NULL){return;}
    clearNode(node->rchild);//递归删除所有左节点
    clearNode(node->lchild);//递归删除所有右节点
    free(node);//释放节点空间
}
//删除树
void clearTree(Tree *tree){
    clearNode(tree->root);
    free(tree);
    return;
}
//输出节点
void outputNode(Node* root){
    if(root==NULL){
        return;//空树直接返回
    }
    printf("%d",root->val);//打印树根节点的值
    if(root->lchild==NULL&&root->rchild==NULL){
        return;//树根左右节点的值都为空,直接返回
    }
    printf("(");
    if(root->lchild==NULL){
        printf("Null");//如果左节点为空,在该左节点填一个Null
    }else{
        outputNode(root->lchild);//层层递归调用左节点输出
    }
    printf(",");
    if(root->rchild==NULL){
        printf("Null");//如果右节点为空,在该右节点填一个Null
    } else{
        outputNode(root->rchild);//层层递归调用输出右节点
    }
    printf(")");
    return;
}
//输出树
void outputTree(Tree* tree){
    printf("tree(%d)=",tree->n);
    outputNode(tree->root);
    printf("\n");
    return;
}
//二叉树的前序遍历
void preorderNode(Node* node){
    if(node==NULL){
        return;
    }
    printf("%d\t",node->val);
    preorderNode(node->lchild);
    preorderNode(node->rchild);
    return;

}
void preorderTree(Tree* tree){
    printf("pre order:");
    preorderNode(tree->root);
    printf("\n");
    return;
}
//二叉树的中序遍历
void inorderNode(Node* node){
    if(node==NULL){
        return;
    }
    inorderNode(node->lchild);
    printf("%d\t",node->val);
    inorderNode(node->rchild);
    return;

}
void inorderTree(Tree* tree){
    printf("in order:");
    inorderNode(tree->root);
    printf("\n");
    return;
}
//二叉树的后序遍历
void postorderNode(Node* node){
    if(node==NULL){
        return;
    }
    postorderNode(node->lchild);
    postorderNode(node->rchild);
    printf("%d\t",node->val);
    return;

}

void postorderTree(Tree* tree){
    printf("post order:");
    postorderNode(tree->root);
    printf("\n");
    return;
}

int main() {
    srand(time(0));//产生随机数
    Tree *tree=getNewTree();
    for(int i=0;i<15;i++){
        int val=rand()%100;//一次向树中插入15个节点
        insert(tree,val);
        outputTree(tree);
    }
    preorderTree(tree);
    inorderTree(tree);
    postorderTree(tree);
    clearTree(tree);
    return 0;
}

输出结果为:

tree(1)=58
tree(2)=58(36,Null)
tree(3)=58(36(Null,53),Null)
tree(4)=58(36(Null,53),88)
tree(5)=58(36(Null,53),88(Null,95))
tree(6)=58(36(3,53),88(Null,95))
tree(7)=58(36(3,53),88(Null,95(94,Null)))
tree(8)=58(36(3,53),88(79,95(94,Null)))
tree(9)=58(36(3(Null,20),53),88(79,95(94,Null)))
tree(10)=58(36(3(Null,20(Null,21)),53),88(79,95(94,Null)))
tree(11)=58(36(3(Null,20(8,21)),53),88(79,95(94,Null)))
tree(12)=58(36(3(Null,20(8,21(Null,23))),53),88(79,95(94,Null)))
tree(13)=58(36(3(Null,20(8,21(Null,23))),53(38,Null)),88(79,95(94,Null)))
tree(14)=58(36(3(Null,20(8,21(Null,23(22,Null)))),53(38,Null)),88(79,95(94,Null)))
tree(15)=58(36(3(Null,20(8,21(Null,23(22,Null)))),53(38,Null)),88(79(Null,87),95(94,Null)))
pre order:58  36    3    20    8    21   23   22   53   38   88   79   87   95   94
in order:  3   8   20    21   22    23   36   38   53   58   79   87   88   94   95
post order:8 22    23    21   20     3   38   53   36   87   79   94   95   88   58

输出结果分析:
1、排序二叉树的中序遍历是有序的
2、二叉树结构如下

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

karwen2020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值