一)二叉树数据结构
// 二叉树数据结构
static class Node {
Node left; // 左节点
Node right; // 右节点
int value; // 节点的值
Node (Node left, Node right, int value) {
this.left = left;
this.right = right;
this.value = value;
}
}
private Node root; // 根节点
二)求二叉树最大深度
// 求二叉树最大深度
public int getMaxHeight(Node node) {
if (node == null) {
return 0;
} else {
// 左节点
int left = getMaxHeight(node.left);
// 右节点
int right = getMaxHeight(node.right);
// 返回
return left > right ? left + 1 : right + 1; // 加1的原因,是因为要算上根节点
}
}
三)求二叉树最小深度
// 求二叉树最小深度
public int getMinHeight(Node node) {
if (node == null) {
return 0;
}
return getMin(node);
}
private int getMin(Node node) {
if (node == null) {
return Integer.MAX_VALUE;
}
if (node.left == null && node.right == null) {
return 1;
}
// 左节点
int left = getMin(node.left);
// 右节点
int right = getMin(node.right);
// 返回
return left <= right ? left + 1 : right + 1; // 加1的原因,是因为要算上根节点
}
四)求二叉树节点个数
// 求二叉树节点个数
public int getNodeNumber(Node node) {
if (node == null) {
return 0;
}
// 左节点
int left = getNodeNumber(node.left);
// 右节点
int right = getNodeNumber(node.right);
// 返回
return left + right + 1;
}
五)求二叉树中叶子节点个数
// 求二叉树中叶子节点个数
public int getChildNodeNumber(Node node) {
if (node == null) {
return 0;
}
if (node.left == null && node.right == null) {
return 1;
}
// 左节点
int left = getChildNodeNumber(node.left);
// 右节点
int right = getChildNodeNumber(node.right);
// 返回
return left + right;
}
六)求二叉树中第k层节点个数
// 求二叉树中第k层节点个数
public int getNodeNumberByK(Node node, int k) {
if (node == null || k < 1) {
return 0;
}
if (k == 1) {
return 1;
}
// 左节点的值
int left = getNodeNumberByK(node.left, k-1);
// 右节点的值
int right = getNodeNumberByK(node.right, k-1);
// 返回
return left + right;
}
七)求二叉树中最大节点的值
// 求二叉树中最大节点的值
public int getMaxValue(Node node) {
if (node == null) {
return -1;
} else {
// 左节点
int leftValue = getMaxValue(node.left);
// 右节点
int rightValue = getMaxValue(node.right);
// 当前值
int value = node.value;
// 假如左节点的值为最大值
int max = leftValue;
// 判断右节点的值是否大于当前值
if (rightValue >= max) {
max = rightValue;
}
// 和当前节点比较
if (value > max) {
max = value;
}
return max;
}
}
八)判断一个值是否在二叉树中存在
// 判断一个值是否在二叉树中存在
public boolean findValue(int value) {
if (value <= 0) {
return false;
} else {
// 根节点
Node rootNode = root;
boolean bool = false;
while (rootNode != null) {
// 如果值相等,就返回true
if (value == rootNode.value) {
bool = true;
break;
} else {
// 继续查找子节点,对比value
if(value > rootNode.value) {
rootNode = rootNode.right;
} else {
rootNode = rootNode.left;
}
}
}
return bool;
}
}
九)判断二叉树是否是平衡二叉树
// 判断二叉树是否是平衡二叉树
public boolean isAVLTree(Node node) {
return avl(node)!=-1;
}
public int avl(Node node) {
if (node == null) {
return 0;
}
// 左节点
int left = avl(node.left);
// 右节点
int right = avl(node.right);
if (left == -1 || right == -1 || Math.abs(left-right) > 1) {
return -1;
}
// 返回
return left > right ? left + 1 : right + 1; // 加1的原因,是因为要算上根节点
}
十)判断两个二叉树是否完全相同
// 判断两个二叉树是否完全相同
public boolean isEquals(Node node1, Node node2) {
if (node1 == null && node2 == null) {
return true;
}
if (node1 == null || node2 == null) {
return false;
}
if (node1.value != node2.value) {
return false;
}
// 左节点
boolean left = isEquals(node1.left, node2.left);
// 右节点
boolean right = isEquals(node1.right, node2.right);
// 返回
return left && right;
}
十一)判断两个二叉树是否互为镜像
// 判断两个二叉树是否互为镜像
public boolean isImage(Node node1, Node node2) {
if (node1 == null && node2 == null) {
return true;
}
if (node1 == null || node2 == null) {
return false;
}
if (node1.value != node2.value) {
return false;
}
// 左节点
boolean left = isImage(node1.left, node2.right);
// 右节点
boolean right = isImage(node1.right, node2.left);
// 返回
return left && right;
}
十二)二叉树前序遍历: 根节点 ==> 左节点 ==> 右节点
// 二叉树前序遍历: 根节点 ==> 左节点 ==> 右节点
// 方式一: 递归
public void preNode(Node node) {
if (node != null) {
System.out.print(node.value + "\t");
preNode(node.left);
preNode(node.right);
}
}
// 方式二: 迭代
public void preNodeWhile(Node node) {
Stack<Node> stack = new Stack<Node>();
stack.push(node);
while (!stack.empty()) {
Node currentnode = stack.pop();
System.out.print(currentnode.value + "\t");
if (currentnode.right != null) {
stack.push(currentnode.right);
}
if (currentnode.left != null) {
stack.push(currentnode.left);
}
}
}
十三)二叉树中序遍历: 左节点 ==> 根节点 ==> 右节点
// 二叉树中序遍历: 左节点 ==> 根节点 ==> 右节点
// 方式一: 递归
public void inNode(Node node) {
if (node != null) {
inNode(node.left);
System.out.print(node.value + "\t");
inNode(node.right);
}
}
// 方式二: 迭代
public void inNodeWhile(Node node) {
Stack<Node> stack = new Stack<Node>();
Node current = node;
while (current != null || !stack.empty()) {
while (current != null) {
stack.add(current);
current = current.left;
}
current = stack.peek();
stack.pop();
System.out.print(current.value + "\t");
current = current.right;
}
}
十四)二叉树后序遍历: 左节点 ==> 右节点 ==> 根节点
// 二叉树后序遍历: 左节点 ==> 右节点 ==> 根节点
// 方式一: 递归
public void nextNode(Node node) {
if (node != null) {
nextNode(node.left);
nextNode(node.right);
System.out.print(node.value + "\t");
}
}
// 方式二: 迭代
public void nextNodeWhile(Node node) {
int left = 1; // 在辅助栈里表示左节点
int right = 2;// 在辅助栈里表示右节点
Stack<Node> stack = new Stack<Node>();
Stack<Integer> stack2 = new Stack<Integer>();
// 辅助栈,用来判断子节点返回父节点时处于左节点还是右节点
while (node != null || !stack.empty()) {
while (node != null) {
// 将节点压入栈1,并在栈2将节点标记为左节点
stack.push(node);
stack2.push(left);
node = node.left;
}
while (!stack.empty() && stack2.peek() == right) {
// 如果是从右子节点返回父节点,则任务完成,将两个栈的栈顶弹出
stack2.pop();
System.out.print(stack.pop().value + "\t");
}
if (!stack.empty() && stack2.peek() == left) {
// 如果是从左子节点返回父节点,则将标记改为右子节点
stack2.pop();
stack2.push(right);
node = stack.peek().right;
}
}
}
识别二维码关注个人微信公众号
本章完结,待续,欢迎转载!
本文说明:该文章属于原创,如需转载,请标明文章转载来源!