二叉树的遍历 and 基本操作实现
- 1.二叉树的遍历
- 前序遍历
- 中序遍历
- 后序遍历
- 层序遍历
- 2.基本操作实现
- 2.1 获取节点个数
- 2.2 获取叶子节点的个数
- 2.3 获取第K层节点的个数
- 2.4 获取二叉树的高度
- 2.5 检测值为value的元素是否存在
1.二叉树的遍历
二叉树由于其特殊结构,有四种遍历方式,分别为前序遍历、中序遍历、后序遍历和层序遍历
下面以如下的二叉树为例,依次分析各个遍历的区别
前序遍历
前序遍历的顺序为:根节点->左子树->右子树
故图示二叉树前序遍历结果为:A->B->D->E->G->C->F
代码实现如下:
// 前序遍历
public void preOrder(TreeNode root) {
if(root == null) {
return;
}
System.out.print(root.val +" ");
preOrder(root.left);
preOrder(root.right);
}
中序遍历
中序遍历的顺序:左子树->根节点->右子树
故图示二叉树中序遍历的结果为:D->B->G->E->A->C->F
代码实现如下:
// 中序遍历
public void inOrder(TreeNode root) {
if(root == null) {
return;
}
inOrder(root.left);
System.out.print(root.val + " ");
inOrder(root.right);
}
后序遍历
后序遍历的顺序为:左子树->右子树->根节点
故图示二叉树后序遍历结果为:D->G->E->B->F->C->A
代码实现如下:
// 后序遍历
public void postOrder(TreeNode root) {
if(root == null) {
return;
}
postOrder(root.left);
postOrder(root.right);
System.out.print(root.val + " ");
}
层序遍历
层序遍历,顾名思义,就是一层一层地遍历;在同一层按照从左到右的顺序依次遍历,这一层结束后,进入下一层再从左到右遍历,如此直至遍历完这棵二叉树。
思路:
- 二叉树的层序遍历需要借助队列来完成
- 先将根节点放入队列中,每次出队列一个元素,并将其记录下来,将其打印出来,再将其左右节点放入队列中
- 如此循环,直至队列为空,层序遍历完成
图示二叉树层序遍历的结果为:A->B->C->D->E->F->G
代码实现如下:
//层序遍历
public void levelOrder(TreeNode root) {
if(root == null) {
return;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()) {
TreeNode cur = queue.poll();
System.out.print(cur.val+" ");
if(cur.left != null) {
queue.offer(cur.left);
}
if(cur.right != null) {
queue.offer(cur.right);
}
}
}
2.基本操作实现
2.1 获取节点个数
- 遍历思路
public static int nodeSize;
/**
* 获取树中节点的个数:遍历思路
*/
public void size(TreeNode root) {
if(root == null) {
return;
}
nodeSize++;
size(root.left);
size(root.right);
}
- 子问题思路
/**
* 获取节点的个数:子问题的思路
*节点个数 = 左子树节点个数 + 右子树节点个数 + 1
* @param root
* @return
*/
public int size2(TreeNode root) {
if(root == null) {
return 0;
}
return size2(root.left) + size2(root.right) + 1;
}
2.2 获取叶子节点的个数
- 遍历思路
/*
获取叶子节点的个数:遍历思路
*/
public static int leafSize = 0;
public void getLeafNodeCount1(TreeNode root) {
if(root == null) {
return;
}
if(root.left == null && root.right == null) {
leafSize++;
}
getLeafNodeCount1(root.left);
getLeafNodeCount1(root.right);
}
- 子问题思路
/*
获取叶子节点的个数:子问题
*/
public int getLeafNodeCount2(TreeNode root) {
if(root == null) {
return 0;
}
if(root.left == null && root.right == null) {
return 1;
}
return getLeafNodeCount2(root.left) + getLeafNodeCount2(root.right);
}
2.3 获取第K层节点的个数
/*
获取第K层节点的个数
*/
public int getKLevelNodeCount(TreeNode root, int k) {
if(root == null) {
return 0;
}
if(k == 1) {
return 1;
}
return getKLevelNodeCount(root.left, k-1) + getKLevelNodeCount(root.right, k-1);
}
2.4 获取二叉树的高度
二叉树的高度 = 左子树高度和右子树高度最大值+1
/*
获取二叉树的高度
时间复杂度:O(N)
*/
public int getHeight(TreeNode root) {
if(root == null) {
return 0;
}
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
return Math.max(leftHeight, rightHeight) + 1;
}
2.5 检测值为value的元素是否存在
// 检测值为value的元素是否存在
public TreeNode find(TreeNode root, char val) {
if(root == null) {
return null;
}
if(root.val == val) {
return root;
}
TreeNode leftNode = find(root.left, val);
if(leftNode != null) {
return leftNode;
}
TreeNode rightNode = find(root.right, val);
if(rightNode != null) {
return rightNode;
}
return null;
}