Java数据结构学习DAY5——二叉树(二)
1、 二叉树的基本操作
// 前序遍历
void preOrderTraversal(Node root);
// 中序遍历
void inOrderTraversal(Node root);
// 后序遍历
void postOrderTraversal(Node root);
// 遍历思路-求结点个数
static int size = 0;
void getSize1(Node root);
// 子问题思路-求结点个数
int getSize2(Node root);
// 遍历思路-求叶子结点个数
static int leafSize = 0;
void getLeafSize1(Node root);
// 子问题思路-求叶子结点个数
int getLeafSize2(Node root);
// 子问题思路-求第 k 层结点个数
int getKLevelSize(Node root, int k);
// 获取二叉树的高度
int getHeight(Node root);
// 查找 val 所在结点,没有找到返回 null
// 按照 根 -> 左子树 -> 右子树的顺序进行查找
// 一旦找到,立即返回,不需要继续在其他位置查找
Node find(Node room, int val)
1.1 求二叉树前序中序后序遍历
- 代码
package java41_0313;
class Node {
String val;
Node left;
Node right;
public Node(String val) {
this.val = val;
}
}
public class BinaryTree {
//创建一棵树(手动写死的方式)
public static Node build() {
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
Node f = new Node("F");
Node g = new Node("G");
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;
return a;
}
//先序遍历
public static void preOrder(Node root) {
if (root == null) {
return;
}
//访问根节点,此处访问就是打印
System.out.print(root.val);
//递归遍历左子树
preOrder(root.left);
//递归遍历右子树
preOrder(root.right);
}
//中序遍历
public static void inOrder(Node root) {
if (root == null) {
return;
}
//先递归处理左子树
inOrder(root.left);
//再访问根节点
System.out.print(root.val);
//最后递归处理右子树
inOrder(root.right);
}
//后序遍历
public static void postOrder(Node root) {
if (root == null) {
return;
}
//先递归处理左子树
postOrder(root.left);
//再递归处理右子树
postOrder(root.right);
//最后访问根节点
System.out.print(root.val);
}
public static void main(String[] args) {
Node root = build();
// preOrder(root);
// inOrder(root);
postOrder(root);
}
}
- 结果
前序:
中序:
后序:
1.2 求二叉树的节点个数
- 思路
求二叉树的节点个数,先遍历二叉树,之后就不是打印节点的值了,而是访问操作,即count++; - 代码1(使用成员变量来记录元素个数)
package java41_0313;
class Node {
String val;
Node left;
Node right;
public Node(String val) {
this.val = val;
}
}
public class BinaryTree {
//创建一棵树(手动写死的方式)
public static Node build() {
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
Node f = new Node("F");
Node g = new Node("G");
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;
return a;
}
//使用成员变量 count 来记录元素的个数
public static int count = 0;
public static void length(Node root) {
if (root == null) {
return;
}
//访问根节点,此时的访问操作就是count++
count++;
//递归处理左子树
length(root.left);
//递归处理右子树
length(root.right);
}
public static void main(String[] args) {
Node root = build();
length(root);
System.out.println(count);
}
}
- 结果
- 代码2(通过方法的返回值来记录元素个数)
package java41_0313;
class Node {
String val;
Node left;
Node right;
public Node(String val) {
this.val = val;
}
}
public class BinaryTree {
//创建一棵树(手动写死的方式)
public static Node build() {
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
Node f = new Node("F");
Node g = new Node("G");
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;
return a;
}
//接下来还是实现 length ,此时通过方法的返回值来记录元素个数
public static int length2(Node root) {
if (root == null) {
return 0;
}
//当前树的节点个数 = 根节点的个数 + 左子树的节点个数 + 右子树的节点个数
return 1 + length2(root.left) + length2(root.right);
}
public static void main(String[] args) {
Node root = build();
System.out.println(length2(root));
}
}
- 结果
1.3 求叶子结点个数
- 代码1(用成员变量记录叶子节点的个数)
package java41_0313;
class Node {
String val;
Node left;
Node right;
public Node(String val) {
this.val = val;
}
}
public class BinaryTree {
//创建一棵树(手动写死的方式)
public static Node build() {
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
Node f = new Node("F");
Node g = new Node("G");
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;
return a;
}
//6. 求子节点的个数
public static int leafSize = 0;
public static void getLeafSize(Node root) {
//针对二叉树遍历,判断当前节点是否是叶子节点,如果是就 size++;
if (root == null) {
return;
}
//判断当前节点是否是叶子结点
if (root.left == null && root.right == null) {
leafSize++;
}
getLeafSize(root.left);
getLeafSize(root.right);
}
public static void main(String[] args) {
Node root = build();
getLeafSize(root);
System.out.println(leafSize);
}
}
- 结果1
- 代码2
package java41_0313;
class Node {
String val;
Node left;
Node right;
public Node(String val) {
this.val = val;
}
}
public class BinaryTree {
//创建一棵树(手动写死的方式)
public static Node build() {
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
Node f = new Node("F");
Node g = new Node("G");
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;
return a;
}
public static int getLeafSize2(Node root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 1;
}
return getLeafSize2(root.left) + getLeafSize2(root.right);
}
public static void main(String[] args) {
Node root = build();
getLeafSize(root);
System.out.println(getLeafSize2(root));
}
}
- 结果2
1.3 求第 k 层结点个数
-
思路
求第 K 层节点的个数 = 求左子树的 K-1 层节点个数 +求右子树的 K -1 层节点个数
例如,要求 A 的第 3 层节点的个数,就相当于求 B 的第 2 层节点个数 + 求 C 的第 2 层节点个数。(递归的思想)
-
代码
package java41_0313;
class Node {
String val;
Node left;
Node right;
public Node(String val) {
this.val = val;
}
}
public class BinaryTree {
//创建一棵树(手动写死的方式)
public static Node build() {
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
Node f = new Node("F");
Node g = new Node("G");
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;
return a;
}
//8.求第K层节点数
public static int getKLevelSize(Node root, int k) {
if (root == null || k < 1) {
return 0;
}
if (k == 1) {
//如果当前树非空,第一层节点一定是 1 个元素
return 1;
}
return getKLevelSize(root.left,k-1) +getKLevelSize(root.right,k-1) ;
}
public static void main(String[] args) {
Node root = build();
System.out.println(getKLevelSize(root,3));
}
}
- 结果
1.4 求树的高度
-
思路
-
代码
package java41_0313;
class Node {
String val;
Node left;
Node right;
public Node(String val) {
this.val = val;
}
}
public class BinaryTree {
//创建一棵树(手动写死的方式)
public static Node build() {
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
Node f = new Node("F");
Node g = new Node("G");
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;
return a;
}
//9.求树的深度
public static int getHeight(Node root) {
if (root == null) {
return 0;
}
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
return 1 + (leftHeight >rightHeight ? leftHeight : rightHeight);
}
public static void main(String[] args) {
Node root = build();
System.out.println(getHeight(root));
}
}
- 结果
1.5 查找树上的某一节点
- 思路
遍历,然后比较节点即可 - 代码
package java41_0313;
class Node {
String val;
Node left;
Node right;
public Node(String val) {
this.val = val;
}
}
public class BinaryTree {
//创建一棵树(手动写死的方式)
public static Node build() {
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
Node f = new Node("F");
Node g = new Node("G");
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;
return a;
}
//10. 查找树上的某一元素
public static Node find(Node root, String toFind) {
if (root == null) {
return null;
}
if (root.val.equals(toFind)) {
return root.val;
}
Node result = find(root.left,toFind);
if (result != null) {
return result;
}
return find(root.right,toFind);
}
public static void main(String[] args) {
Node root = build();
Node result = find(root, "B");
System.out.println(result.val);
- 结果