树和二叉树

树和二叉树

以下代码全部本人手动敲滴,若有帮助请点个赞吧

一.树的表示方法

1.倒置树结构(最为常用)

2.文氏图表示法

3.广义表形式(嵌套括号形式)

4.凹入表示法

二.二叉树

1.二叉树的性质

1_1 在二叉树的第i层至多有2^i-1个结点(数学归纳法可证明)
1_2 深度为k的二叉树至多有2^k-1个结点。
1_3 对任意二叉树T,若终端结点数为n0,而其度数为2的结点数为n2,则n0=n2+1.
1_4 对于完全二插树,其有n个节点,那么其深度为log2 n+1;
1_5 对二叉树从上到下,从左到右依次用1-n进行标号
若i=1,则序号为i的结点为根结点;若i>1,则序号为i的结点的双亲结点序号为[i/2];
若2i>n,那么序号为i的结点没有左孩子,若2i<=n,那么序号为i的结点的左孩子序号为2i;
若2i+1>n,则序号为i的结点无右孩子,若2i+1>n,那么序号为i的结点的右孩子的序号为2i+1.

2.二叉树的存储结构

2_1顺序存储结构

在这里插入图片描述

2_2链式存储结构
typedef struct Node
{
    DataType data;
    struct Node*LChild;
    struct Node*RChild;
}BitNode,*BitTree;

PS:若一个二叉树右n个结点,则其二叉链表中必含有2n个指针域,其中必含有n+1个空指针域,n-1个实指针域

3.二叉树的遍历

3_1先序遍历

递归算法:

void PreOrder
{
    if(root!=NULL)
    {
        print(root->data);
        PreOrder(root->LChild);
        PreOrder(root->RChild);
    }
}
输出二叉树中的叶子结点
 void  PreOrder
{
    if(root!=NULL)
    {
        if(root->LChild==NULL&&root->RChild==NULL)
        print(root->data);
        PreOrder(root->LChild);
        PreOrder(root->RChild);
    }
}
void leaf(BiTree root)
{
    int leafcount=0;
    if(root!=NULL)
    leaf(root->LChild);
    leaf(root->RChild);
    if(root->Lchild==NULL&&root->Rchild==NULL)leafcount++;
}

非递归算法1

//前序遍历
void PreOrder1(BitNode *b)
{
    BitNode*p;
    SqStack* s;
    InitStack(s);
    if(b!=NULL){
        Push(s,b);//根节点入栈
    while(!StackEmpty(s))//栈不为空就继续
    {
        Pop(s,p);//把s中的顶部弹出来并赋予p
        print("%c",p->data);
        if(p->rchild!=NULL)Push(s,p->rchild);
        if(p->lchild!=NULL)Push(s,p->lchild);
    }
    printf("\n");
 }
  DestroyStack(s);   
}

非递归算法2

void PreOrder2(BitNode *b)
{
    BitNode*p;SqStack *st;
    p=b;
    while(StackEmpty(st)|| p!=NULL)
    {
        while(p!=NULL)
        {
            printf("%c",p->data);
            Push(st,p);
            p=p->Lchild;
        }
        if(!StackEmpty(st))
        {
            Pop(st,p);
            p=p->Rchild;
        }
    }
    printf("\n");
    Destory(st);
}

用扩展的先序遍历序列创建二叉链表

void CreateBit(BiTree *bt)
{
    char ch;
    ch=getchar();
    if(ch=='.')*b=NULL;
    else
    {
        *bt=(BiTree)malloc(sizeof(BiTree));
        (*bt)->data=ch;
        CreateBit(&((*bt)->Lchild));
        CreateBit(&(((*bt)->Rchild));
    }
}
3_2中序遍历
//递归算法
void MiddleOrder(BitNode* b)
{
    if(b!=NULL)
    {
    MiddleOrder(b->Lchild);    
    printf("%c",b->data);
    MiddleOrder(b->Rchild);
    }
}
//非递归算法(直接调用栈)
void MiddleOrder2(BitNode* b)
{
    int top=0;	BitNode*p=b;
    do
    {
        while(p!=NULL)
        {
            if(top>m)return;
            top=top+1;
            s[top]=p;
            p=p->Lchild;
        }//遍历左子树
        if(top!=0)
        {
            p=s[top];
            top=top-1;
            Visit(p->data);
            p=p->Rchild;
        }//遍历右子树
    }while(p!=NULL||top!=0)
}
void MiddleOrder3(BitNode* b)
{
    InitStack(&S);
    p=root;
    while(p!=NULL||!IsEmpty(S))
    {
        if(p!=NULL)
        {
            Push(&S,p);
            p=p->Lchild;
        }
        else
        {
            pop(&s,&p);Visit(p->data);
            p=p->Rchild;
        }
    }
}
3_3后序遍历
//递归算法
void EndOrder(BitNode* b)
{
    if(b!=NULL){
    EndOrder(b->Lchild);    
    EndOrder(b->Rchild);
    printf("%c",b->data);
    }
}
//后序遍历非递归操作
void EndOrder2(BitNode *root)
{
    BitNode*p,*q;
    Stack S;
    q=NULL;p=root;
    InitStck(S);
    while(p!=NULL||IsEmpty(S))
    {
        if(p!=NULL)
 z   {
        Push(&S,p);
        p=p->Lchild;
    }
    else
    {
        GetTop(&S,&p);
        if(p->Rchild==NULL||p->Rchild==q)//无右孩子或右孩子已经被遍历过
        {
            visit(p->data);
            q=p;
            Pop(&S,&p);p=NULL;//p置空方可继续退层
        }
        else
            p=p->Rchild;
     }
   }
}
3_4其他
//求二叉树的高度

int PostTreeDepth(BiTree bt)
{
    int hl,hr,mX;
    if(bt!=NULL)
    {
        hl=PostTreeDepth(bt->Lchild);
        hr=PostTreeDepth(bt->Rchild);
        max=hl>hr?hl:hr;
        return max+1;
    }
    return 0;//空树返回零
}
void PrintTree(BiTree bt,int nLayer)//按横向树形显示二叉树
{
    if(bt==NULL)return;
    PrintTree(bt->Rchild,nLayer++);
    for(int i=0;i<nLayer;i++)
        printf(" ");
    printf("%c",bt->data);
    PrintTree(bt->Rchild,nLayer+1);
}
//先序遍历求二叉树高度的递归算法
int depth=0;
void PreTreeDepth(Bitree bt,int h)//h初始值为1
{
    if(bt!=NULL)
    {
        if(h>depth)depth=h;
        PreTreeDepth(bt->Lchild,h+1);//遍历左子树
        PreTreeDepth(bt->Rchild,h+1);//遍历右子树
    }
}

4.线索二叉树

新增了Ltag和Rtag两个标志位,0表示指向孩子,1表示指向的是前驱

//中序建立线索二叉树
BinTree pre = NULL;


void Inthread(BinTree bt)
{
    if(bt != NULL){
        Inthread(bt->LChild);
        if(!bt->LChild){
            bt->Ltag = 1;
            bt->LChild = pre;
        }
        if(pre&& !pre->RChild){
            pre->RChild = bt;
            pre->Rtag = 1;
        }
        pre = bt;
        Inthread(bt->RChild);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

时光诺言

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

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

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

打赏作者

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

抵扣说明:

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

余额充值