【数据结构】二叉树

一、存储结构

        1.1顺序存储,在逻辑上连续的元素,在物理存储单元上也连续(只适合存储完全二叉树)

#define MaxSize 100

struct TreeNode{
    int value;
    bool isEmpty;
};

//实例化
TreeNode t[MaxSize];

         1.2链式存储

typedef struct BiTNode{
    int data;                         //数据域
    struct BitNode *lchild, *rchild;  // 左右孩子指针
}BiTNode, *BiTree;

        n个结点的二叉链表有n+1个空链域, 可以用来构造线索二叉树; 

构建过程:

        三叉链表:在上述二叉链表的基础上,增加父指针指向父节点。

二、二叉树的 先、中、后序遍历和层次遍历

           代码使用递归实现:

先序:根左右
void PerOrder(BiTree T){
    if(T!=NULL){
        visit(T);    // 访问根结点
        PreOrder(T->lchild);
        PreOrder(T->rChild);   // 递归遍历左右子树
    }
}

中序:左根右
void InrOrder(BiTree T){
    if(T!=NULL){
        PreOrder(T->lchild);
        visit(T);
        PreOrder(T->rChild);   
    }
}
后序:左右根
void PosrOrder(BiTree T){
    if(T!=NULL){
        PreOrder(T->lchild);
        PreOrder(T->rChild);  
        visit(T); 
    }
}

        层序遍历

        ①、初始化辅助队列(仅允许一边进,另一边出)

        ②、根结点入队

        ③、若队列非空,队头结点出队,访问其孩子结点并入队(左、右)

        重复③至队列为空

//以链式存储的方式实现一个二叉树
typedef strcut BiTNode{
    char data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

//链式队列记录结点
typedef struct LinkNode{
    BiTNode *data;
    struct LinkNode *next;
}LinkNode;

typedef struct{
    LinkNode *front, *rear;  //队头、队尾
}LinkQueue;

//层序遍历
void LevelOrder(BiTree T){
    LinkQueue Q;       
    InitQueue(Q);       初始化辅助队列
    BiTree p;           根节点
    EnQueue(Q, p);      根节点入队
    while(!IsEmpty(Q)){
        DeQueue(Q, p);      队头结点出队
        visit(p);           
        if(p->lchild!=NULL)
            EnQueue(Q, p->lchild);     左孩子入队
        if(p->rchild!=NULL)
            EnQueue(Q, p->rchild);     右孩子入队
    }
}

三、由遍历序列构造二叉树

        需要以上四种遍历的两种,其中一种必须为中序遍历,才能唯一确定二叉树。

        根据不同遍历方式的访问顺序,来确定根结点、左右子树根节点....重复。

四、线索二叉树(线索链表)

        让结点的左右孩子指针指向前驱和后继,这样就可以在任意结点(好像也不是任意,当有左右孩子的时候比较麻烦)处找到此结点在前/中/后序遍历排序的前驱和后继。

        为了不混淆左右孩子指针指向的到底是此结点的左右孩子,还是此结点在遍历排序中的前驱后继,代码实现的过程中需要是用ltag和rtag来区分,为0:指向孩子;为1:是线索指针

typedef struct ThreadNode{
    int data;
    struct ThreadNode *lchild, *rchild;
    int ltag, rtag;
} ThreadNode, *ThreadTree;

  

五、利用线索二叉树找指定结点的前驱后继

       中序:rtag=1:则没有孩子结点,指向的就是后继结点;

                rtag=0:有右孩子结点,则其子树(这个右孩子的子树)的最左下角的左孩子结点为其后继;

ThreadNode *Firstnode(ThreadNode *p){
    循环找到最左下角的结点(不一定是叶子结点)   (中序)
    while(p->ltag == 0)
        p = p->lchild;
    return p;
}

......
        

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值