目录
1.树型结构
1.1概念及特点
1.2树的表示形式
2.二叉树
2.1概念及特点
2.2特殊二叉树
2.3二叉树的性质
2.4二叉树的存储
2.5二叉树基本操作
2.5.1创建二叉树
2.5.2遍历二叉树
2.5.3二叉树常见方法
3.二叉树面试题
1.树型结构
1.1概念及特点
定义:树是一种非线性的数据结构,由n个有限结点组成一个具有层次关系的集合。
特点:1> 有一个特殊结点根结点,根结点没有前驱结点;
2> 一棵N个结点的树由N-1条边;
3> 子树之间不能有交集;
4> 每个结点有且仅有一个父结点;
5> 树是递归定义的;
以下举例均以上图为本:
概念 | 说明 | 举例 |
---|---|---|
结点的度 | 一个结点含有子树的个数 | A的度为3 |
树的度 | 一棵树中所有结点的度的最大值 | 树的度为3 |
叶子结点/终端结点 | 度为0的结点 | JFKLHI |
双亲结点/父结点 | 若一个结点含有子结点,则这个结点称为其子结点的父结点 | ABCDEG |
孩子结点/子结点 | 一个结点含有的子树的根结点 | B~L |
根结点 | 一棵树中,没有双亲结点的结点 | A |
结点的层次 | 从根开始,根为第1层,根的子结点为第2层,以此类推 | A的层次为4,B的层次为3 |
树的高度/深度 | 树中结点的最大层次 | 4 |
非终端结点/分支结点 | 度不为0的结点 | A~E,G |
兄弟结点 | 具有相同父结点的结点 | BCD,EF… |
堂兄弟结点 | 双亲在同一层的结点 | EG,FG… |
结点的祖先 | 从根到该结点所经分支上的所有结点 | 略 |
子孙 | 以某结点为根的子树中任一结点 | 略 |
森林 | 由m (m >= 0) 棵互不相交的树组成的集合称为森林 | 略 |
1.2树的表示形式
双亲表示法,孩子表示法,孩子双亲表示法,孩子兄弟表示法……
下面演示其中最常用的孩子兄弟表示法:
class Node {
int value;//树中存储的数据
Node firstChild;//第一个孩子引用
Node nextBrother;//下一个兄弟引用
}
2.二叉树
2.1概念及特点
定义:一棵二叉树是结点的一个有限集合,该集合:要么为空,要么是由一个根结点加上两棵别称为左子树和右子树的二叉树组成。
特点:1> 二叉树不存在度大于2的结点;
2> 二叉树的子树有左右之分,次序不可颠倒,因此二叉树是有序树;
2.2特殊二叉树
满二叉树:一棵二叉树,如果每层的结点数都达到最大值,则这棵二叉树就是满二叉树;也 就是说,如果一棵二叉树的层数为K,且结点总数是2^K-1 ,则它就是满二叉树。
完全二叉树:对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的 满二叉树中编号从0至n-1的结点一一对应时,称之为完全二叉树。
2.3二叉树的性质
重点重点重点!!重要的事情说三遍!!!
1> 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1) 个结点;
2> 若规定只有根结点的二叉树的深度为1,则深度为K的二叉树的最大结点数是2^K -1;
深度为K的N叉树的最大结点树是 ( 2^K -1 ) / N-1;
3> 结点个数=度为0的结点+度为1的结点+度为2的结点,即n=n0+n1+n2;
4> 如果叶结点的个数为n0,度为2的非叶结点的个数为n2,则有n0=n2+1;
5> 具有n个结点的完全二叉树的深度K为log2(n+1)向上取整;
6> 对完全二叉树来说,偶数个结点时n1=1,奇数个结点时n1=0;
7> 完全二叉树中如果一个结点没有左孩子,则一定没有右孩子;
2.4二叉树的存储
分类:链式存储,顺序存储。这里先讲链式存储,常见的表示方法有二叉和三叉:
//孩子表示法
class Node {
int val;//数据域
Node left;//左孩子的引用,常常代表左孩子为根的整棵左子树
Node right;//右孩子的引用,常常代表右孩子为根的整棵右子树
}
//孩子双亲表示法
class Node {
int val;//数据域
Node left;//左孩子的引用,常常代表左孩子为根的整棵左子树
Node right;//右孩子的引用,常常代表右孩子为根的整棵右子树
Node parent;//当前节点的根节点
}
2.5二叉树基本操作
下面所有代码以上图为基础:
2.5.1创建二叉树
public class BinaryTree {
static class TreeNode { //静态内部类
public char val;
public TreeNode left;
public TreeNode right;
public TreeNode(char val) {
this.val = val;
}
}
//创建二叉树:见上图
public TreeNode createTree() {
TreeNode A = new TreeNode('A');
TreeNode B = new TreeNode('B');
TreeNode C = new TreeNode('C');
TreeNode D = new TreeNode('D');
TreeNode E = new TreeNode('E');
TreeNode F = new TreeNode('F');
TreeNode G = new TreeNode('G');
TreeNode H = new TreeNode('H');
A.left = B;
A.right = C;
B.left = D;
B.right = E;
C.left = F;
C.right = G;
E.right = H;
return A;
}
}
public class Test {
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
BinaryTree.TreeNode root = binaryTree.createTree();//静态内部类需要通过类名来访问
}//在此处打一个断点,有下图debug
}
2.5.2遍历二叉树
前序遍历:根 — 左子树 — 右子树,结果:ABDCEF
中序遍历:左子树 — 根 — 右子树,结果:DBAECF
后序遍历:左子树 — 右子树 — 根,结果:DBEFCA
层序遍历:上 — 下,左 — 右, 结果:ABCDEF
不论前中后序都是红色虚线路线。
避免繁琐,这里的代码省略了之前创建二叉树写的那部分。注意使用的还是最开始的那张图~
//前序遍历
public void preOrder(TreeNode root) {
if (root == null) {
return;
}
System.out.print(root.val+" ");//根
preOrder(root.left);//左
preOrder(root.right);//右
}
//中序遍历
public void inOrder(TreeNode root) {
if (root == null) {
return;
}
inOrder(root.left);//左
System.out.print(root.val+" ");//根
inOrder(root.right);//右
}
//后序遍历
public void postOrder(TreeNode root) {
if (root == null) {
return;
}
postOrder(root.left);//左
postOrder(root.right);//右
System.out.print(root.val+" ");//根
}
public class Test {
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
BinaryTree.TreeNode root = binaryTree.createTree();
binaryTree.preOrder(root);//A B D E H C F G
System.out.println();
binaryTree.inOrder(root);//D B E H A F C G
System.out.println();
binaryTree.postOrder(root);//D H E B F G C A
}
}
这里写的是没有返回值和递归的方法,还有有返回值和非递归的方法,详见下:
有返回值:
前序遍历 中序遍历 后序遍历
非递归:
二叉树面试题
2.5.3二叉树常见方法
获取树中节点个数,获取叶子节点个数,获取第K层结点个数,获取二叉树高度,检测值为value的元素是否存在。
//获取树中结点的个数
//法一:root不为空,count++
public static int count = 0;
public int size(TreeNode root) {
if (root == null) {
return 0;
}
count++;
size(root.left);
size(root.right);
return count;
}
//法二:左树+右树+根
public int size1(TreeNode root) {
if (root == null) {
return 0;
}
int ret = size1(root.left) + size1(root.right) + 1;
return ret;
}
// 获取叶子结点的个数
//法一:root左右均为空时,count++
public static int leafSize = 0;
public int getLeafNodeCount(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
leafSize++;
}
getLeafNodeCount(root.left);
getLeafNodeCount(root.right);
return leafSize;
}
//法二:左树叶子+右树叶子
public int getLeafNodeCount1(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 1;
}
int ret = getLeafNodeCount1(root.left) + getLeafNodeCount1(root.right);
return ret;
}
3.二叉树面试题
二叉树面试题
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net