数据结构之树

1、树

概念:有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树;

 (1)若它的左子树不为空,则左子树上的所有节点的值都小于它的根节点的值;
 (2)若它的右子树不为空,则右子树上所有节点的值都大于它的根节点的值;
 (3)其他的左右子树也分别为二叉查找树;
 (4)二叉查找树是动态查找表,在查找的过程中可见添加和删除相应的元素,在这些操作中需要保持二叉查找树的以上性质。

2、二叉树

 概念:每个节点最多含有两个子树的树称为二叉树;

下图是满二叉树和完全二叉树

3、二叉树的存储结构

(1)顺序存储结构

二叉树的顺序存储结构就是用一维数组存储二叉树中的结点,并且结点的存储位置,也就是数组的下标要能体现结点之间的逻辑关系,比如双亲与孩子的关系,左右兄弟的关系。

使用顺序存储结构表现二叉树的时候,在其线性结构中,会存在一些空结点,但是其会占据一定的内存空间,会造成存储空间的浪费;所以,顺序存储结构一般只用于完全二叉树。

(2)链表存储方式

二叉链表

由于二叉树的每个结点最多有两个孩子,所以为每个结点设计一个数据域和两个指针域,通常将其称之为二叉链表。

链表来表示一棵二叉树,即用链来指示元素的逻辑关系。

 

其中,data域存放某结点的数据信息;lchild与rchild分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或NULL表示)。利用这样的结点结构表示的二叉树的链式存储结构被称为二叉链表,

左边是二叉树,右边是二叉树链表。

一棵二叉树的三叉链表表示

为了方便访问某结点的双亲,还可以给链表结点增加一个双亲字段parent,用来指向其双亲结点。每个结点由四个域组成,其结点结构为:

尽管在二叉链表中无法由结点直接找到其双亲,但由于二叉链表结构灵活,操作方便,对于一般情况的二叉树,甚至比顺序存储结构还节省空间。因此,二叉链表是最常用的二叉树存储方式。

4、二叉树的前序、中序、后序三种遍历

一、先序遍历: 

1、访问根节点          2、前序遍历左子树      3、前序遍历右子树     (根------左-------右)

二、中序遍历: 

1、中序遍历左子树         2、访问根节点       3、中序遍历右子树     (左-----根-------右)

三、后序遍历: 

1、后序遍历左子树      2、后序遍历右子树     3、访问根节点       (左------右-------根)

以下是对二叉树解释。参考https://blog.csdn.net/qq_33243189/article/details/80222629

A:根节点、B:左节点、C:右节点,前序顺序是ABC(根节点排最先,然后同级先左后右);中序顺序是BAC(先左后根最后右);后序顺序是BCA(先左后右最后根)。

比如上图二叉树遍历结果

    前序遍历:ABCDEFGHK

    中序遍历:BDCAEHGKF

    后序遍历:DCBHKGFEA

分析中序遍历如下图,中序比较重要

举例:后序遍历顺序为:AEFDHZMG

5、线索二叉树

概念:在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序中序、后序)使其变为线索二叉树的过程称为对二叉树进行线索化

                                                              (通过虚线箭头就可以遍历,倒着看箭头) 

本质:二叉树的遍历本质上是将一个复杂的非线性结构转换为线性结构,使每个结点都有了唯一前驱和后继(第一个结点无前驱,最后一个结点无后继)。对于二叉树的一个结点,查找其左右子女是方便的,其前驱后继只有在遍历中得到。为了容易找到前驱和后继,有两种方法。一是在结点结构中增加向前和向后的指针,这种方法增加了存储开销,不可取;二是利用二叉树的空链指针。 

优势

(1)利用线索二叉树进行中序遍历时,不必采用堆栈处理,速度较一般二叉树的遍历速度快,且节约存储空间。

(2)任意一个结点都能直接找到它的前驱和后继结点。

不足

(1)结点的插入和删除麻烦,且速度也较慢。

(2)线索子树不能共用。

6、树和森林

树和二叉树、森林的转化

将树转换为二叉树:

树中每个结点最多只有一个最左边的孩子(长子)和一个右邻的兄弟。按照这种关系很自然地就能将树转换成相应的二叉树:1.在所有兄弟结点之间加一连线2.对每个结点,除了保留与其长子的连线外,去掉该结点与其它孩子的连线。

将一个森林转换为二叉树:

具体方法是:1.将森林中的每棵树变为二叉树;2.因为转换所得的二叉树的根结点的右子树均为空,故可将各二叉树的根结点视为兄弟从左至右连在一起,就形成了一棵二叉树。

二叉树转换为树:

是树转换为二叉树的逆过程。

1.加线。若某结点X的左孩子结点存在,则将这个左孩子的右孩子结点、右孩子的右孩子结点、右孩子的右孩子的右孩子结点…,都作为结点X的孩子。将结点X与这些右孩子结点用线连接起来。

2.去线。删除原二叉树中所有结点与其右孩子结点的连线。

二叉树转换为森林:

假如一棵二叉树的根节点有右孩子,则这棵二叉树能够转换为森林,否则将转换为一棵树。

1.从根节点开始,若右孩子存在,则把与右孩子结点的连线删除。再查看分离后的二叉树,若其根节点的右孩子存在,则连线删除…。直到所有这些根节点与右孩子的连线都删除为止。

2.将每棵分离后的二叉树转换为树。

7、哈夫曼树

概念:给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

这里直接楼主就不画图了,直接看https://blog.csdn.net/qq_29519041/article/details/81428934

这个博主讲的很好。

 

树的存储结构和树的遍历以及森林的遍历暂时不想看。(看不进去了)

 

参考:https://www.cnblogs.com/shixiangwan/p/7530015.html

https://www.cnblogs.com/fthjane/p/4746186.html

https://blog.csdn.net/qq_33243189/article/details/80222629

https://baike.baidu.com/item/%E7%BA%BF%E7%B4%A2%E4%BA%8C%E5%8F%89%E6%A0%91/10810037?fr=aladdin

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值