目录
一、前言
1.关于递归
1)递归的应用场景
a.大问题可以拆分成小问题
b.拆分后的小问题和大问题除了数据规模,解决思路全一样
c.存在递归终止条件,拆分拆到底的条件
2)如何写递归程序:不要纠结内部运行,学会使用递归的语义解决问题
2.树的基本概念
1)为什么要有树结构?
二叉树就是树形结构(天然的查找语义),树形结构可以更加高效的进行查找和搜索。如电脑中的文件系统就是一个树形结构。
如果文件是线性结构会怎么样:线性结构是所有文件逻辑上连续,成一条直线排列,换句话说电脑中假设有100w个文件,都在一个位置存储,检索特点的某个文件,就要遍历这个集合n次,O(n),如果是树,根据文件夹查找特定文件,时间复杂度实际上就是文件树的深度:O(logN)。
2)数据结构常用的树结构
a.BST:二分搜索树【二叉树的元素查找】
b.平衡二分搜索树:AVL(严格平衡),红黑树(非严格平衡)
c.堆
d.并查集
e.字符串:线段树;字典树(Trie)
3)树的基本概念
树是一种非线性的数据结构,由n(n>=0)个有限节点组成一个具有层次关系的集合,把他叫做树是因为它看起来像一颗倒挂的树,也就是说它是根朝上,叶朝下,子树是不能相交的,除了根节点外,每个节点有且仅有一个父节点,一棵N个节点的树有N-1条边,树是递归定义的。
a.树中的每个单元称为节点
b.节点的度:该节点含有的子树的个数就称为节点都度
c.树的度:该树中最大的节点的度就是该树的度
d.叶子节点:度为0的节点,也称为终端节点
e.根节点:树中没有父亲节点的节点:A就是根节点
f.关于节点的层次:从根开始计算,根节点是第一层
g.树的高度:节点的最大层次
二、二叉树
每个节点最多只有两个子树,二叉树中节点的度不超过2,两个子树有左右之分。
1.两种特殊的二叉树
1)满二叉树
a.概念
一个二叉树如果每一层的节点树都能达到最大值(所有非叶子节点的度都为2),则这个二叉树是满二叉树。
b.特点:对一棵二叉树来讲
1)高度为k,则该二叉树最多有2^k-1个节点【节点最多的情况就是满二叉树】
2)层次为k,第k层最多有2^(k-1)个节点
3)边长和节点个数关系:边长=节点个数-1。设度为0的节点个数为n0,度为1的节点个数n1,度为2的节点个数n2,则:n0=n2+1(叶子节点的个数=度为2的节点个数+1),设总的个数为n,n=n0+n1+n2,边长=n-1。
2)完全二叉树
a.概念
完全二叉树是效率很高的数据结构,它实际上就是满二叉树“缺了个右下角”,在完全二叉树中,度为1的节点若存在,只可能有一个度为1的节点,且只有左子树没有右子树,不存在只有右子树没有左子树的节点(节点要靠左排列!)。
b.问题1:
一个完全二叉树第六层有8个叶子节点,则该完全二叉树至多有多少个节点(求该完全二叉树全部的节点个数)
分析:已知第六层8个叶子节点,让完全二叉树前六层拉满,存在第七层。前6层而言,最多的节点个数:2^6-1=63;第6层总共有2^(6-1)=32,有8个叶子节点,非叶子节点=32-8=24个,这24个节点的子树就是第七层的节点,这24节点都有左右子树,第7层节点个数:24*2=48,总的节点个数=前六层拉满的节点+第7层的节点=63+48=111。
c.问题2:
500,500,1,0
分析:总结点1000,1024之内(2^10-1=1023,2^9-1=511),二叉树高度为10,前九层节点个数拉满:511,第十层节点个数:1000-511=489(全是叶子节点),第九层非叶子节点=第10层节点个数/2=488/2+1(度为2的节点+度为1的节点)=245,第九层总节点个数:2^(9-1)=256,第九层叶子节点=256-245=11。综上,总叶子节点=11+489=500,非叶子节点=1000-500=500,度为2的节点=499,度为1的节点=1。
3)完全二叉树的节点编号
若根节点从1开始编号,设父节点的编号为k,则左子树2k,右子树2k+1;若根节点从0开始编号,左子树2k+1,右子树2k+2。
2.二叉树的存储方式
同链表一样,有顺序存储和链式存储(引用)。顺序存储是将二叉树采用数组的方式存储(只能存储完全二叉树,在堆章节介绍),普通二叉树采用引用方式存储。
class Node<E>{
E val; Node left; Node right;//左右孩子表示法,一般都可以使用该方法来存储二叉树的节点
}
class Node<E>{//之后平衡树会用到
E val; Node left; Node right;
Node parent;//父节点地址
}