1.树的概念
树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看 起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
节点的度:一个节点含有的子树的个数称为该节点的度
树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6
叶子节点或终端节点:度为0的节点称为叶节点
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节点。
节点的层次:从根开始定义起,根为第1层,根的子节点为第2层。
树的高度或深度:树中节点的最大层次
2.二叉树的概念
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉 树组成。
二叉树的特点:
(1). 每个结点最多有两棵子树,即二叉树不存在度大于 2 的结点。
(2). 二叉树的子树有左右之分,其子树的次序不能颠倒,因此二叉树是有序树。
2.1二叉树的性质
(1).如果规定二叉树的根节点的层数为1,则一颗非空二叉树的第i层上最多有(i>0)
个节点。
(2).若规定只有根节点的二叉树的深度为1,则深度为k的二叉树的最大节点数为
(k >= 0)
(3).对任何一颗二叉树,如果其叶节点个数为n0,度为2的非叶节点个数为n2,则有n0 = n2+1
推导过程:
(4).具有n个节点的完全二叉树的深度k为
3.二叉树相关操作
3.1前序遍历
void preOrder(TreeNode root) {
if (root == null) {
return;
}
System.out.println(root.val + " ");
preOrder(root.left);
preOrder(root.right);
}
3.1.1前序遍历方法2
public List<Character> preorderTrversal(TreeNode root) {
//List<Character>用来存储节点
List<Character> retlist = new ArrayList<>();
if(root == null){
return retlist;
}
retlist.add(root.val);
List<Character> lefttree = preorderTrversal(root.left);
retlist.addAll(lefttree);
List<Character> righttree = preorderTrversal(root.right);
retlist.addAll(righttree);
return retlist;
}
3.2中序遍历
void inOrder(TreeNode root){
if(root == null){
return;
}
inOrder(root.left);
System.out.println(root.val+" ");
inOrder(root.right);
}
3.2.1中序遍历方法2
public List<Character> inOrderTrvelsal(TreeNode root){
List<Character> retlist = new ArrayList<>();
if(root == null){
return retlist;
}
List<Character> lefttree = inOrderTrvelsal(root.left);
retlist.addAll(lefttree);
retlist.add(root.val);
List<Character> rightTree = inOrderTrvelsal(root.right);
retlist.addAll(rightTree);
return retlist;
}
3.3后序遍历
void postOrder(TreeNode root) {
if (root == null) {
return;
}
postOrder(root.left);
postOrder(root.right);
System.out.println(root.val + " ");
}
3.3.1后序遍历方法2
public List<Character> postOrderTrvelsal(TreeNode root){
List<Character> retlist = new ArrayList<>();
if(root == null){
return retlist;
}
List<Character> leftTree = postOrderTrvelsal(root.left);
retlist.addAll(leftTree);
List<Character> rightTree = postOrderTrvelsal(root.right);
retlist.addAll(rightTree);
retlist.add(root.val);
return retlist;
}
3.4获取树中节点
int count = 0;
public int size1(TreeNode root){
if(root == null){
return 0;
}
count++;
size1(root.left);
size1(root.right);
return count;
}
//子问题思路
public int size2(TreeNode root){
if(root == null){
return 0;
}
return size2(root.left)+size2(root.right)+1;
}
3.5获取树中叶子节点
static int leafCount = 0;
public void getLeafNodeCount(TreeNode root){
if(root == null){
return;
}
if(root.left == null && root.right ==null){
leafCount++;
}
getLeafNodeCount(root.left);
getLeafNodeCount(root.right);
}
//子问题思路
public int getLeafCount2(TreeNode root){
if(root == null){
return 0;
}
if(root.left == null && root.right == null){
return 1;
}
return getLeafCount2(root.left)+getLeafCount2(root.right);
}
3.6获取第k层节点的个数
//获取第k层节点的个数,子问题思路
public int getKLevelNodeCount(TreeNode root,int k){
if(root == null || k < 0){
return 0;
}
if(k == 1){
return 1;
}
return getKLevelNodeCount(root.left,k-1)+getKLevelNodeCount(root.right,k-1);
}
3.7获取二叉树的高度
//获取二叉树的高度 = 左右树中较高的树 + 1(1为根节点)
//时间复杂度:O(N)
//空间复杂度:log2 N
public int getHeight(TreeNode root){
if(root == null){
return 0;
}
int leftTree = getHeight(root.left);
int rightTree = getHeight(root.right);
return leftTree > rightTree ? leftTree + 1:rightTree + 1;
}
3.8检测值为value的值是否存在
//检测值为value的值是否存在,前序遍历一个一个找
TreeNode find(TreeNode root,char val){
if(root == null){
return null;
}
if(root.val == val){
return root;
}
TreeNode ret = find(root.left,val);
if(ret != null){
return ret;
}
ret = find(root.right,val);
if(ret != null){
return ret;
}
return null;
}
3.9判断是不是完全二叉树
//判断是不是完全二叉树
boolean isCompleteTree(TreeNode root){
if(root == null){
return true;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (! queue.isEmpty()){
TreeNode cur = queue.poll();
if(cur != null){
queue.offer(cur.left);
queue.offer(cur.right);
}else {
break;
}
}
while (! queue.isEmpty()){
TreeNode top = queue.peek();
//最后将树的节点都放到队列中后,开始检查队列中的元素是否还有不为空的元素,如果有,则不是完全二叉树
if(top != null){
return false;
}
queue.poll();
}
return true;
}