c语言实现二叉树的建立以及二叉树的先序遍历和层次遍历

首先建立一个二叉树节点的结构体:

节点的左右孩子用lchild和rchild表示

typedef struct node{
    datatype data;
    struct node*lchild;
    struct node*rchild;
}node;

建立二叉树的结构体:

树都有一个根root

typedef struct binarytree{
    node*root;
}binarytree;

定义建立一颗二叉树的函数:

binarytree* makebtree(binarytree* bt,datatype x,binarytree*ltree,binarytree*rtree){
    bt->root=(node*)malloc(sizeof(node));
    bt->root->data=x;
    bt->root->lchild=ltree->root;
    bt->root->rchild=rtree->root;
    return bt;
}

以上是左右数不为空的二叉树的建立方式,如果一棵树只有一个节点,也就是左右子树为空的二叉树,我们可以定义一个空树函数解决

binarytree* nulltree(binarytree*bt){  //空树
    bt->root=NULL;
    return bt;
}

树的先序遍历:

递归遍历

void preorder(node*root){
    if(root){
        printf("%c",root->data);
        preorder(root->lchild);
        preorder(root->rchild);
    }
}
void preoredertree(binarytree*bt){
    if(bt->root){
        preorder(bt->root);
        printf("\n");
    }
}

main函数测试一下:

建立一颗二叉树并遍历

int main(){
    binarytree bt1,bt2,bt3,bt4,bt5;
    nulltree(&bt5);
    makebtree(&bt2,'B',&bt5,&bt5);
    makebtree(&bt4,'D',&bt5,&bt5);
    makebtree(&bt3,'C',&bt4,&bt5);
    makebtree(&bt1,'A',&bt2,&bt3);
    preoredertree(&bt1);
    return 0;
}

最终输出结果为 ABCD

然后在实现层次遍历:

次遍历方法需要用到一个队列作为辅助,队列如下

利用一个树的节点类型的指针数组存储二叉树的节点

typedef struct qnode{
    int front;
    int rear;
    node*data[MAXSIZE];  //二叉树节点类型的指针数组,MAXSIZE大小为100
}queue;

队列创建的函数实现:

queue* create(queue*q){
    q=(qnode*)malloc(sizeof(qnode));
    q->front=q->rear=0;
}

进队以及出队函数的实现:

queue* inselem(queue*q,node*btnode){   //进队
    if(q&&btnode){
        if((q->rear+1)%MAXSIZE!=q->front){
        int ret=(q->rear+1)%MAXSIZE;
        q->data[ret]=btnode;
        q->rear=(q->rear+1)%MAXSIZE;
        return q;
        }
        else
        printf("this queue is full\n");
    }
}
queue* deldata(queue*q){        //出队
    if(q){
        if(q->front!=q->rear){
            int ret=(q->front+1)%MAXSIZE;
            q->data[ret]=q->data[q->front];
            q->front=(q->front+1)%MAXSIZE;
            return q;
        }
        else
        printf("this queue is empty");
    }
    else
    printf("this queue is not exist\n");
}

摧毁队列的函数实现:

queue* destroy(queue*q){
    if(q){
        while(!isempty(q)){
            deldata(q);
        }
        free(q);
    }
}

先编写一个队列判空的函数,后面的层次遍历时用得到

接下来实现层次遍历:

void levelorder(binarytree*bt){
    if(bt){
        node*p;
        p=bt->root;
        queue*q;
        q=create(q);
        inselem(q,p);
        while(!isempty(q)){       //判断队列q是否为空,为空时推出循环
              printf("%c",p->data);
              deldata(q);
              if(p->lchild)
              inselem(q,p->lchild);
              if(p->rchild)
              inselem(q,p->rchild);
              p=front(q);        //将队头的节点赋值给p
        }
        destroy(q);
        printf("\n");
    }
}

main函数:

int main(){
    binarytree bt1,bt2,bt3,bt4,bt5;
    nulltree(&bt5);
    makebtree(&bt2,'B',&bt5,&bt5);
    makebtree(&bt4,'D',&bt5,&bt5);
    makebtree(&bt3,'C',&bt4,&bt5);
    makebtree(&bt1,'A',&bt2,&bt3);
    preoredertree(&bt1);
    levelorder(&bt1);
    levelorder(&bt3);
    return 0;
}

预测结果为:

ABCD

ABCD

CD

源码在此

你可能感兴趣的:(数据结构,c语言)