数据结构之树

一、树的定义

  有且只有一个称为跟的结点;由若干个互不相交的子树,这些子树本身也是一棵树。

解释:1.树是有结点和边组成的
           2.每个结点只有一个父节点,但是可有多个子节点
      3.但是有一个节点例外,给节点没有父节点,此节点成为根节点

二、树的术语

节点、父节点、子节点
子孙、堂兄弟
度:子节点的个数
深度:从根节点到最底层节点的层数称之为深度
叶子节点:没有子节点的节点
非终端节点:实际就是非叶子节点

三、树的分类

一般树:任意一个节点的子节点的个数不受限制
二叉树:任意一个节点的子节点的个数最多是两个,且子节点的位置不可更改
  分类:
  一般二叉树
  满二叉树:在不增加树的层数的前提下,无法再添加一个节点的二叉树即为满二叉树。
  完全二叉树:如果只是删除了满二叉树的最底层、最右边的连续的若干个节点,这样形成的二叉树就是完全二叉树。
森林:n个互不相交的树的集合

四、树的存储

连续存储【完全二叉树】/链式存储

一般树的存储:(二叉树表示法)把一棵树转化成二叉树来存储:设法保证任意一个节点的左指针指向它的孩子,右指针指向它的兄弟。

一个普通树转化成的二叉树没有右子树。

五、树的操作

遍历【递归定义的】
先序遍历【先访问根节点】
先访问根节点--》再先序访问左子树--》再先序访问右子树
中序遍历【中间访问根节点】
先中序访问左子树--》再访问根节点--》再中序访问右子树
后序遍历【最后访问根节点】
先后序访问左子树--》再后序访问右子树--》再访问根节点


已知两种遍历序列,求原始二叉树:
1.已知先序和中序,(求原始二叉树)求后序
2.已知中序和后序,(求原始二叉树)求先序
3.已知先序和后序,无法得到原始二叉树,无法求出中序。

代码

#include<stdio.h>
#include<malloc.h>

struct BTnode{
    char data;
    struct BTnode * pLeft;
    struct BTnode * pRight;
    
};

struct BTnode * createTree(void);
void preTraverseTree(struct BTnode *);
void midTraverseTree(struct BTnode *);
void postTraverseTree(struct BTnode *);

int main(void)
{
    struct BTnode * pT = createTree();
    printf("preTraverseTree: \n");
    preTraverseTree(pT);
    printf("\n");
    
    printf("midTraverseTree: \n");
    midTraverseTree(pT);
    printf("\n");
    
    printf("postTraverseTree: \n");
    postTraverseTree(pT); 
    printf("\n");
    
    return 0;
} 


struct BTnode * createTree(void)
{
    struct BTnode * pA = (struct BTnode *)malloc(sizeof(struct BTnode ));
    struct BTnode * pB = (struct BTnode *)malloc(sizeof(struct BTnode ));
    struct BTnode * pC = (struct BTnode *)malloc(sizeof(struct BTnode ));
    struct BTnode * pD = (struct BTnode *)malloc(sizeof(struct BTnode ));
    struct BTnode * pE = (struct BTnode *)malloc(sizeof(struct BTnode ));
    
    pA->data = 'A';
    pB->data = 'B';
    pC->data = 'C';
    pD->data = 'D';
    pE->data = 'E';
    
    pA->pLeft = pB;
    pA->pRight = pC;
    pB->pLeft = pB->pRight = NULL;
    pC->pLeft = pD;
    pC->pRight = NULL;
    pD->pLeft = NULL;
    pD->pRight = pE;
    pE->pLeft = pE->pRight =NULL;
    return pA;
    
}

void preTraverseTree(struct BTnode * pT)
{
    if(NULL != pT)
    {
        printf("%c  ",pT->data);
        if(pT->pLeft !=NULL)
        {
            preTraverseTree(pT->pLeft);    
        } 
        if(pT->pRight != NULL)
        {
            preTraverseTree(pT->pRight);
        }
        
    }
}
void midTraverseTree(struct BTnode * pT)
{
    if(NULL != pT)
    {
        if(pT->pLeft !=NULL)
        {
            midTraverseTree(pT->pLeft);    
        } 
        printf("%c  ",pT->data);
        if(pT->pRight != NULL)
        {
            midTraverseTree(pT->pRight);
        }
        
    }
}
void postTraverseTree(struct BTnode * pT)
{
    if(NULL != pT)
    {
        if(pT->pLeft !=NULL)
        {
            postTraverseTree(pT->pLeft);    
        } 
        if(pT->pRight != NULL)
        {
            postTraverseTree(pT->pRight);
        }
        printf("%c  ",pT->data);
        
    }
}
View Code

 

转载于:https://www.cnblogs.com/ljd4you/p/9609916.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值