二叉树的顺序存储,链式存储,先,中,后,层序遍历。链队列

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define MaxSize 100

typedef struct {
    int id;
}ElemType;
/*以下为顺序存储二叉树,由于只有当树为完全二叉树的时候,树的结点和数组下标有关系
 * 但当不是完全二叉树的时候,就要花费大量的空间去存储空值,造成了大量的内存浪费
 * 因此一般不用顺序存储*/
struct Tree{
    ElemType value;
    bool isEmpty;
};



struct Tree t[MaxSize];//表示一棵二叉树
void InitTree(){
    for (int i = 0; i < MaxSize; ++i) {
        t[i].isEmpty=true;
    }
}

/*
 *
 *
 * */

/*链式存储
 * */


typedef struct BiTNode{
    ElemType data;
    struct BiTNode *lchild,*rchild;
    //struct BiTNode *parent;//如果经常找父节点,可以使用这种三叉链表
}BiTNode,*BiTree;

/*基于队列的遍历*/
typedef struct st{
    BiTNode *data;
    struct st *next;
}LinkNode;

typedef struct {
    LinkNode *front,*rear;//带头结点中,front指向头结点,rear指向尾结点
}LinkQueue;

void visit(BiTNode *T);
BiTNode *treeInsertLeft(BiTNode *R,ElemType a);
BiTNode *treeInsertRight(BiTNode *R,ElemType a);
void PreOrder(BiTree T);
void InOrder(BiTree T);
void BackOrder(BiTree T);
int treeDepth(BiTree T);
void levelOrder(BiTree T);

int main() {
    //creat a tree
    BiTree root = (BiTree) malloc(sizeof(BiTNode));
    //initialized a tree
    root->lchild=NULL;
    root->data.id = 1;
    root->rchild=NULL;

    //insert a node
    ElemType a={1},b={2},c={3},d={4},e={5},f={6},g={7},h={8};
    BiTNode *an,*bn,*cn,*dn,*en,*fn,*gn,*hn;
    bn=treeInsertLeft(root,b);
    cn=treeInsertRight(root,c);
    dn=treeInsertLeft(bn,d);
    en=treeInsertRight(bn,e);
    fn=treeInsertLeft(cn,f);
    gn=treeInsertRight(cn,g);
    PreOrder(root);
    printf("\n");
    InOrder(root);
    printf("\n");
    BackOrder(root);
    printf("\n");
    treeDepth(root);
    levelOrder(root);


    return 0;
}
/*这里只需要一层指针就ok了,根本不需要指针的指针,注意理解指针的本质
 * 我们创建的都是链表结点的指针,因此修改结点只需要把结点的指针在函数之间进行传递就行了,不需要修改指针,只需要修改结点*/
BiTNode *treeInsertLeft(BiTNode *R,ElemType a){
    BiTNode *p = (BiTNode *) malloc(sizeof(BiTNode));
    p->rchild=NULL;
    p->lchild=NULL;
    p->data=a;
    R->lchild=p;
    return p;

}
BiTNode *treeInsertRight(BiTNode *R,ElemType a){
    BiTNode *p = (BiTNode *) malloc(sizeof(BiTNode));
    p->rchild=NULL;
    p->lchild=NULL;
    p->data=a;
    R->rchild=p;
    return p;
}
/*递归遍历
 *
 *
 * */


//先续遍历
void PreOrder(BiTree T){
    if (T!=NULL){
        visit(T);
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}
//中序遍历
void InOrder(BiTree T){
    if (T!=NULL){
        InOrder(T->lchild);
        visit(T);
        InOrder(T->rchild);
    }
}
//后序遍历9                     void BackOrder(BiTree T){
    if (T!=NULL){
        BackOrder(T->lchild);
        BackOrder(T->rchild);
        visit(T);
    }
}

/*先中后续遍历可以转换求前中后缀表达式*/
void visit(BiTNode *T) {
    printf("%d",T->data.id);
}

/*求树的深度*/
/*递归从逻辑的本质上就是树的遍历,比如求阶乘,就是度为1的树的遍历
 * 求斐波那契数列,就是度为2的树的前续遍历
 * 通过递归的方式把一个问题分解为规模最小的情况,但是数量最多。这点十分像树,从一个根开始生长,生长到最后的全是叶子,再从叶子一步步返回都根
 * 在生长的过程中,通过类似n-1的操作是的问题规模变小,通过出口条件判断来限定最小规模条件,通过return语句来执行返回到根的操作(由零到整)
 * 总之是,化整为零,由零到整
 * 一颗树从生长到无数叶子,每个叶子代表着一种递归的可能性*/
int treeDepth(BiTree T){
    if(T==NULL){
        return 0;
    } else{
        int l=treeDepth(T->lchild);
        int r=treeDepth(T->rchild);
        return l>r? l+1:r+1;
    }

}

/*层次遍历
 *
 * 设置一个辅助队列*/
bool Empty(LinkQueue *Q){
    if (Q->front->next==NULL)
        return true;
    else
        return false;
}
/*尾插法*/
void EnQueue(LinkQueue *Q,BiTNode *z){
    LinkNode *s = (LinkNode *) malloc(sizeof(LinkNode));
    s->data=z;
    s->next=NULL;
    Q->rear->next=s;
    Q->rear=s;

}

bool DeQueue(LinkQueue *Q,BiTNode **s){
    if (Empty(Q)){
        return false;
    }
    LinkNode *p=Q->front->next;
    *s=p->data;
    Q->front->next=Q->front->next->next;
    if(Q->rear==p)
        Q->rear=Q->front;
    free(p);
    return true;
}

void levelOrder(BiTree T){
    LinkQueue *Q=(LinkQueue *)malloc(sizeof(LinkQueue));
    (*Q).rear = (*Q).front = (LinkNode *) malloc(sizeof(LinkNode));
    BiTree p;
    EnQueue(Q,T);
    while (!Empty(Q)){
        DeQueue(Q,&p);
        visit(p);
        if (p->lchild!=NULL){
            EnQueue(Q,p->lchild);
        }
        if (p->rchild!=NULL){
            EnQueue(Q,p->rchild);
        }
    }
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值