郝斌数据结构树的学习笔记

3 篇文章 0 订阅
2 篇文章 0 订阅

定义
1.有且仅有一个称为根的节点
2.有若干个互不相交的子树,这些子树本身也是一棵树
通俗定义:
1.树是由节点和边组成
2.每个节点只有一个父节点但可以有多个子节点
3.但有一个节点例外,该节点没有父节点,此节点称为根节点

专业术语:节点 父节点 子节点 子孙 堂兄弟

深度:从根节点到最底层节点的层数称之为深度,根节点是第一层

叶子节点:没有子节点的节点

非终端节点:实际就是非叶子节点,既有子节点的节点

:子节点的个数(子节点度最大的为树的度)

树的分类

一般树:任意一个节点的子节点的个数都不受限制

二叉树:任意一个节点的子节点个数最多为两个,且子节点的位置不可更改

分类
一般二叉树

满二叉树:在不增加树的层数的前提下,无法再多添 加一个节点的二叉树

完全二叉树:如果只删除满二叉树最底层最右边的连续若干个节点
(满二叉树是完全二叉树的一个特列)
森林:n个互不相交的数的集合

树的存储:

二叉树的存储:
连续存储【完全二叉树】
【优点】:查找某个节点的父节点和子节点(可以判断有没有子节点)
【缺点】:耗用内存空间大

链式存储
我们存普通树,首先将其变成完全二叉树在进行存储。

一般树的存储:双亲表示法:求父节点比较方便

孩子表示法:求子节点比较方便

双亲孩子表示法:求两个都比较方便

二叉树表示法:将普通树转换成二叉树来存储,既设法保证任意一个节点的
左指针域指向他的第一个孩子,右指针域指向他的兄弟

森林的存储
先把森林转换成二叉树,在存储二叉树

二叉树的操作:
遍历:
先序遍历:先访问根节点,再先序访问左子树,再先序访问右子树。【先访问根节点】
中序遍历:中序遍历左子树,再访问根节点,在中序遍历右子树。【中间访问根节点】
后序遍历:中序遍历左子树,在中序遍历右子树,再访问根节点。【最后访问根节点】
已知两种遍历序列,求原始二叉树:
只能通过先序中序或中序后序,才能还原二叉树。

应用:树的数据库中数据组织一种重要形式
操作系统子父进程的关系就是一棵树
面向对象语言中类的继承关系就是一颗树
赫夫曼树

链式二叉树的遍历

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


struct BTNode
{

    char data;

    struct BTNode* pLchild;

    struct BTNode* pRchild;

};

struct BTNode* CreatBTree() {
    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->pLchild = pB;
    pA->pRchild = pC;
    pB->pLchild = pB->pRchild = NULL;
    pC->pLchild = pD;
    pC->pRchild = pD->pLchild = NULL;
    pD->pRchild = pE;
    pE->pLchild = pE->pRchild = NULL;
    return pA;
}

//void PostTraverBTree(struct BTNode* );

void PreTraverBTree(struct BTNode* p) {
    if (p != NULL) {
        printf("%c\n", p->data);
    }
    if (p->pLchild != NULL) {
        PreTraverBTree(p->pLchild);//递归思想
    }
    if (p->pRchild != NULL) {
        PreTraverBTree(p->pRchild);//递归思想
    }
}



void InTraverBTree(struct BTNode* p) {
    if (p != NULL) {
     
    if (p->pLchild != NULL) {
        InTraverBTree(p->pLchild);//递归思想
    }
    printf("%c\n", p->data);
   
    if (p->pRchild != NULL) {
        InTraverBTree(p->pRchild);//递归思想
    }
    }
}


void  PostTraveraBTree(struct BTNode* p) {
    if (p != NULL) {
        if (p->pLchild != NULL) {
            PostTraveraBTree(p->pLchild);//递归思想
        }
        if (p->pRchild != NULL) {
            PostTraveraBTree(p->pRchild);//递归思想
        }
        printf("%c\n", p->data);
    }
}

void  main()
{
    struct BTNode* p = CreatBTree();

   // PreTraverBTree(p);
    
   // InTraverBTree(p);

    PostTraveraBTree(p);
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值