数据结构学习小记-树

1.一种非线性结构,属于图均属于非线性结构。

  1. 树是由结点或顶点和边组成的,不存在任何环的结构,没有结点的树称为空,null,一棵非空的树包括一个根节点,还有很多附加结点,所有结点构成一个多级分层结构。

  2. 树的定义:n个节点组成的有限集合。n=0,空树;n>0,1个根节点,m个互不相交的有限集,每个子集为根的子树。

  3. 节点的度:树中某个节点的子树的个数;树的度:树中各节点的度的最大值;分支节点:度不为零的节点;叶子节点:度为0的节点;路径:i>j;路径长度;路径经过节点数目减一;孩子节点:某节点的后继结点;双亲节点:该节点为其孩子节点的双亲节点(父母节点);兄弟节点:同一双亲的孩子节点;子孙节点:某节点所有子树中的节点;祖先节点:从树节点到该节点的路径上的节点;

  4. 节点的层次:根节点为第一层(以此类推);树的高度;树中节点的最大层次;有序树:树中节点子树按次序从左向右安排,次序不能改变;无序树;与之相反;森林:互不相交的树的集合。

  5. 树的性质:树的节点树为所有节点度数加1(加根节点);度为m的树中第i层最多有m(i-1)个节点;高度为h的m次树至多有(mh-1)/(m-1)个节点;具有n个节点的m次树的最小高度为logm(n(m-1)+1)向上取整。

二叉树

  1. 二叉树是n个节点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根节点和两棵互不相交的、分别称为根节点的左子树和右子树组成。每一个节点最多拥有一个左节点和一个右节点,并没有多余的节点;

  2. 二叉树的特点:每个节点最多有两棵子树,所以二叉树中不存在度大于2的节点。左子树和右子树是有顺序的,次序不能任意点颠倒;即使树中某节点只有一棵子树,也要区分是左子树还是右子树;

  3. 性质:二叉树的第i层上的节点数目最多为2(i-1)个节点;深度为k的二叉树至多有2k -1 个节点;包含n个节点的二叉树的高度至少为log2(n+1);在任意一棵二叉树中,若终端节点的个数为n0,度为2的节点树为n2,则n0 = n2+1;

几种特殊的二叉树

  1. 斜树:

    • 所有的节点都只有左子树的二叉树叫左斜树。所有节点都是只有右子树的二叉树叫右斜树。统称为斜树。
  2. 满二叉树:

    • 在一棵二叉树中,如果所有分支节点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。所有叶子只能出现在最下一层。出现在其他层就不可能达成平衡;非叶子节点的度一定是2;在同样深度的二叉树中,满二叉树的节点个数最多,叶子树最多;
  3. 完全二叉树:

    • 对一颗具有n个节点的二叉树按层编号,如果编号为i(1<=i<=n)的节点与同样深度的满二叉树中编号为i的节点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。

二叉树的存储

  1. 一颗二叉树的结点设计一定要有如下内容:

    • 结点元素,data域,用来存储数据,其可以是int,char等基本的类型,同时也可以是struct等这些复杂的复合数据类型。

    • 左孩子结点,left指针,总是用来指向当前结点的下一层的左边结点,其属于一种指针。

    • 右孩子结点,right指针,总是用来指向当前结点的下一层的右边结点,其属于一种指针。

    • 父结点(可选),parent指针,总是指向当前结点的前一个结点,简称父亲结点,其不属于必须结点设计,省略掉可以节省内存的效果,而使用则可以更方便进行定向搜索,以上就是一颗二叉树的结点设计,除此之外,我们使用一棵树的时候需要建立一颗树根,由这个“根”,来进行逐步的向下构建。

    typedef struct node{
    	int data;
    	struct node* left;
    	struct node* right;
    } Node;
    
    //树根
    typedef struct {
    	Node* root;
    } Tree;
    
  2. 树的创建:

    • 首先,我们创建一个空的结点再进行连接,首先将这个空的结点中的data域赋予数据,再判断tree中是否是一个空树,如果为空,只需要将整个根指向这一个结点即可,如果不为空,再进行两个判断.
  3. 树的遍历之先序遍历二叉树:

    • 树作为非线性数据结构,在我们取出数据时就需要设计遍历,所谓遍历,就是按照一定的规则性,将数据结构中的所有数据全部依次访问,而二叉树本身并不具有天然的全局次序,故为实现遍历,需通过在各节点与其孩子之间约定某种局部次序,间接地定义某种全局次序,这便是我们常规定的先序,中序,后序遍历。

    先序遍历:根左右

    中序遍历:左根右

    后序遍历:左右根

    1. 先序遍历就是在访问二叉树的结点的时候采用,先根,再左,再右的方式
  4. DFS深度优先搜索
    a. 是一种用于遍历或搜索树或图的算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。而即使对于一颗深度为n的二树,在没有任何优化的情况下适用DFS去搜索访问数据,其算法的时间复杂度也高达O(2^n),在数据较大的情况下DFS是无法满足程序的时间要求,这就会涉及到一个思路——剪枝,即通过现有的数据判断接下来的数据无法再满足解,直接将当前结点以后的所有数据舍弃,遍历不再访问,通过精心设计的剪枝可以使得DFS搜索的效果得到很大提升。

  5. 哈夫曼树
    a. 又名最优二叉树,给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
    b. 相关名词:结点的权:给每一个结点赋予一个新的数值,被称为结点的权。结点的带权路径长度:指的是从根节点到该节点之间的路径长度与该结点的权的乘积。树的带权路径长度为树中所有子节点的带权路径长度之和。通常记作"WPL"。
    c. 构建哈夫曼树:只需要遵循一个原则,那就是权重越大的结点距离树根越近。首先,选出我们数据中最小的两个数据,构建成二叉树的左孩子和右孩子,而根的数据为两者之和。其次,将刚才合成的数据作为右孩子,左孩子从未处理的数据中选出最小的一个,作为左孩子,他们的根同样为左右孩子的权值和。不断重复上述的步骤,直到将所有的数据全部处理完并构建出二叉树,这棵二叉树就是我们的哈夫曼树。

posted @   阳扬的杨  阅读(44)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示