数据结构——二叉树

二叉树

二叉树的顺序存储

结点结构体

struct treeNode {//二叉树结点
    int value;
    bool IsEmpty;
};

定义一个二叉树

    treeNode t[MAXSIZE];//定义一个二叉树

完全二叉树存储方案

数据结构——二叉树_第1张图片在这里插入图片描述
数据结构——二叉树_第2张图片

普通二叉树(非完全)存储方案

数据结构——二叉树_第3张图片
在这里插入图片描述

二叉树的链式存储

n个结点的二叉链表共有n+1个空链域

结点结构体

struct BitNode {//二叉树链式存储结点
    int value;
    BitNode* lchild, * rchild;
}BitNode,*Bitree;

带有父节点指针的链式存储结点(三叉链表)

方便逆序遍历

typedef struct BitNode {//二叉树链式存储结点
    int value;
    BitNode* lchild, * rchild;
    BitNode* father;
}BitNode, *Bitree;

定义一个根节点

    Bitree root = NULL;
    root = new(BitNode);
    root->value = 1;
    root->lchild = NULL;
    root->rchild = NULL;

二叉树的遍历

先序遍历

//先序遍历 
void preOrder(Bitree root)
{
    if (root != NULL)
    {
        visit(root);
        preOrder(root->lchild);
        preOrder(root->rchild);
    }
}

中序遍历

//中序遍历
void InOrder(Bitree root)
{
    if (root != NULL)
    {
        preOrder(root->lchild);
        visit(root);
        preOrder(root->rchild);
    }
}

后序遍历

//后序遍历
void InOrder(Bitree root)
{
    if (root != NULL)
    {
        preOrder(root->lchild);
        preOrder(root->rchild);
        visit(root);
    }
}

层次遍历

队列辅助

//二叉树层次遍历
void levelOrder(Bitree root)
{
    InitQueue(Q);//初始化辅助队列
    Bitree p;
    EnQueue(Q, root);//根节点入队
    while (!IsEmpty(Q))//队列不空则循环
    {
        DeQueue(Q, p);//对头结点出队
        visit(p);//访问出队结点
        if (p->lchild != NULL)
            EnQueue(Q, p->lchild);//左子树不空则左子树结点入队
        if (p->rchild != NULL)
            EnQueue(Q, p->rchild);//右子树不空则右子树结点入队
    }
}

线索二叉树

数据结构——二叉树_第4张图片

tag0表示指针指向孩子
tag
1表示指针指向线索

typedef struct ThreadNode{
    int data;
    ThreadNode* lchild, * rchild;
    int ltag, rtag;//左右线索标志
}ThreadNode,*Threadtree;

数据结构——二叉树_第5张图片

中序线索化


ThreadNode* pre = NULL;
//中序线索化二叉树
void creatInThread(Threadtree T)
{
    pre == NULL;
    if (T != NULL)
    {
        InThread(T);
        if (pre->rchild == NULL)//最后将pre结点的rtag置1
            pre->rtag = 1;
    }
}
//一边遍历一遍线索化
void InThread(Threadtree root)
{
    if (root != NULL)
    {
        InThread(root->lchild);
        Thread_visit(root);
        InThread(root->rchild);
    }
}
void Thread_visit(ThreadNode* q)
{
    if (q->lchild == NULL)//左子树为空建立前驱结点
    {
        q->lchild = pre;
        q->ltag = 1;
    }
    if (pre!=NULL&&pre->rchild == NULL)//前驱结点不为空且右子树为空建立后继结点
    {
        pre->rchild = q;
        pre->rtag = 1;
    }
    pre = q;
}

先序线索化

在遍历过程中注意防止程序指针循环指的问题加上条件
if (root != NULL)
{
Thread_visit(root);
if(root->ltag==0)
PreThread(root->lchild);==
PreThread(root->rchild);
}

//先序线索化
void creatPreThread(Threadtree T)
{
    pre == NULL;
    if (T != NULL)
    {
        InThread(T);
        if (pre->rchild == NULL)//最后将pre结点的rtag置1
            pre->rtag = 1;
    }
}
//一边遍历一边线索化
void PreThread(Threadtree root)
{
    if (root != NULL)
    {
        Thread_visit(root);
        if(root->ltag==0)
            PreThread(root->lchild);
        PreThread(root->rchild);
    }
}
void Thread_visit(ThreadNode* q)
{
    if (q->lchild == NULL)//左子树为空建立前驱结点
    {
        q->lchild = pre;
        q->ltag = 1;
    }
    if (pre!=NULL&&pre->rchild == NULL)//前驱结点不为空且右子树为空建立后继结点
    {
        pre->rchild = q;
        pre->rtag = 1;
    }
    pre = q;
}

中序线索二叉树找后继结点

//中序线索二叉树中找到中序后继

//在线索二叉树中找到p的后继结点
ThreadNode* NextNode(ThreadNode* p)
{
    if (p->rtag == 0)return Firstnode(p->rchild);
    else return p->rchild;
}
//找到以p为根子树中第一个杯中序遍历的结点
ThreadNode* Firstnode(ThreadNode* p)
{
    while (p->ltag == 0)
        p = p->lchild;
    return p;
}

///

线索后继方法中序遍历线索二叉树

void InOrder(ThreadNode* T)//利用线索后继方法实现中序线索二叉树遍历
{
    for (ThreadNode* p = Firstnode(T); p!NULL; p = NextNode(p))
        visit(p);
}

中序线索二叉树找前驱结点

//线索二叉树结点找前驱
///
//找到以p为根的子树中最后一个被遍历的结点
ThreadNode* LastNode(ThreadNode* p)
{
    while (p->rtag == 0)p = p->rchild;
    return p;
}
//在中序线索二叉树中找到结点p的前驱结点
ThreadNode* preNode(ThreadNode* T)
{
    //左子树中最右下的结点
    if (T->ltag == 0)return LastNode(T->lchild);
    else return T->lchild;
}
///

你可能感兴趣的:(笔记,学习,数据结构,二叉树)