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)利用线索二叉树进行中序遍历时,不必采用堆栈处理,速度较一般二叉树的遍历速度快,且节约存储空间。
不足
(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