二叉树的遍历查找插入删除等
Posted 须弥戒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的遍历查找插入删除等相关的知识,希望对你有一定的参考价值。
关注我,获取须弥戒中的宝藏
/********************************************
* All Rights Reserved By www.laughing.ren
* @author:Laughing_Lz
* @version:2018年11月29日 下午11:33:24
* ******************************************/
package ren.laughing.code.Test;
import java.util.LinkedList;
import java.util.Queue;
/**
* 二叉树
*
* @author Laughing_Lz
*
*/
public class Tree {
/**
* 前序遍历二叉树
*
* @param root
*/
public static void preOrder(Node root) {
if (root == null) {
return;
}
System.out.print(root.getValue() + " ");
if (root.getLeft() != null) {
preOrder(root.getLeft());
}
if (root.getRight() != null) {
preOrder(root.getRight());
}
}
/**
* 中序遍历二叉树
*
* @param root
*/
public static void inOrder(Node root) {
if (root == null) {
return;
}
if (root.getLeft() != null) {
inOrder(root.getLeft());
}
System.out.print(root.getValue() + " ");
if (root.getRight() != null) {
inOrder(root.getRight());
}
}
/**
* 后序遍历二叉树
*
* @param root
*/
public static void postOrder(Node root) {
if (root == null) {
return;
}
if (root.getLeft() != null) {
postOrder(root.getLeft());
}
if (root.getRight() != null) {
postOrder(root.getRight());
}
System.out.print(root.getValue() + " ");
}
/**
* 层次遍历二叉树
*
* @param root
*/
public static void levelOrder(Node root) {
if (root == null) {
return;
}
Queue<Node> queue = new LinkedList<Node>();
queue.add(root);
while (!queue.isEmpty()) {
Node currentNode = queue.poll();
System.out.print(currentNode.getValue() + " ");
if (currentNode.getLeft() != null) {
queue.add(currentNode.getLeft());
}
if (currentNode.getRight() != null) {
queue.add(currentNode.getRight());
}
}
}
/**
* 卡特兰数: 给定一组数据,比如 1,3,5,6,9,10。你来算算,可以构建出多少种不同的二叉树?
* https://en.wikipedia.org/wiki/Catalan_number
*
* @param numKeys
* @return
*/
public static int countTrees(int numKeys) {
if (numKeys <= 1) {
return (1);
} else {
int sum = 0;
int left, right, root;
// 每次迭代,root节点的左右两颗子树的节点数不同--左子树的节点数从0到numKeys-1,右子树相反
// 这样迭代结束后,各种情况便都覆盖全了;
for (root = 1; root <= numKeys; root++) {
left = countTrees(root - 1);
right = countTrees(numKeys - root);
// number of possible trees with this root == left*right
sum += left * right;
}
return (sum);
}
}
static class Node {
private int value;
private Node left;
private Node right;
public Node(int value) {
super();
this.value = value;
}
public Node() {
super();
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
/**
* 二叉查找树的查找操作 二叉查找树:每个节点的左节点都比当前节点值小,右节点都比当前节点大值。
*
* @param root
* @param value
* @return
*/
public static Node find(Node root, int value) {
if (root == null) {
return null;
}
while (root != null) {
if (root.getValue() == value) {
return root;
} else if (root.getValue() > value) {
root = root.getLeft();
} else if (root.getValue() < value) {
root = root.getRight();
}
}
return null;
}
/**
* 二叉查找树的插入操作
*
* @param root
* @param value
*/
public static void insert(Node root, int value) {
if (root == null) {
root = new Node(value);
}
while (root != null) {
if (root.getValue() < value) {
if (root.getRight() == null) {
root.setRight(new Node(value));
return;
}
root = root.getRight();
} else if (root.getValue() > value) {
if (root.getLeft() == null) {
root.setLeft(new Node(value));
return;
}
root = root.getLeft();
}
}
}
/**
* 二叉查找树的删除操作,要注意有三种情况:1、待删除节点没有子节点2、待删除节点只有一个子节点(只需更新父节点)
* 3、待删除节点有两个子节点(从待删除节点的左子节点中找出最大的节点替换,或从右子节点中找出最小的节点替换)
*
* @param tree
* @param data
*/
public static void delete(Node tree, int data) {
Node p = tree; // p 指向要删除的节点,初始化指向根节点
Node pp = null; // pp 记录的是 p 的父节点
while (p != null && p.getValue() != data) {
pp = p;
if (data > p.getValue())
p = p.right;
else
p = p.left;
}
if (p == null)
return; // 没有找到
// 要删除的节点有两个子节点
if (p.left != null && p.right != null) { // 查找右子树中最小节点
Node minP = p.right;
Node minPP = p; // minPP 表示 minP 的父节点
while (minP.left != null) {
minPP = minP;
minP = minP.left;
}
p.setValue(minP.getValue()); // 将 minP 的数据替换到 p 中
p = minP; // 下面就变成了删除 minP 了
pp = minPP;
}
// 删除节点是叶子节点或者仅有一个子节点
Node child; // p 的子节点
if (p.left != null)
child = p.left;
else if (p.right != null)
child = p.right;
else
child = null;
if (pp == null)
tree = child; // 删除的是根节点
else if (pp.left == p)
pp.left = child;
else
pp.right = child;
System.out.println("\n删除节点" + data + "后:");
inOrder(tree);
}
/**
* 计算二叉树的高度
*
* @param root
* @param index
* @return
*/
public static int getBinaryLevel(Node root, int index) {
if (null == root) {
return index;
}
int maxleftLevel = 0;
if (root.left != null) {
maxleftLevel = getBinaryLevel(root.left, index + 1);
}
int maxRightLevel = 0;
if (root.right != null) {
maxRightLevel = getBinaryLevel(root.right, index + 1);
}
return Math.max(maxleftLevel, maxRightLevel) + 1;
}
public static void main(String[] args) {
// 构建二叉树
Node leaf1 = new Node(6);
Node leaf2 = new Node(9);
Node leaf3 = new Node(10);
Node node1 = new Node(3);
node1.setLeft(leaf1);
node1.setRight(leaf2);
Node node2 = new Node(5);
node2.setLeft(leaf3);
Node root = new Node(1);
root.setLeft(node1);
root.setRight(node2);
// 构建中序遍历有序的二叉查找树
Node leaf11 = new Node(1);
Node leaf22 = new Node(5);
Node leaf33 = new Node(9);
Node node11 = new Node(3);
node11.setLeft(leaf11);
node11.setRight(leaf22);
Node node22 = new Node(10);
node22.setLeft(leaf33);
Node root1 = new Node(6);
root1.setLeft(node11);
root1.setRight(node22);
System.out.println("前序遍历:");
preOrder(root);
System.out.println("\n中序遍历:");
inOrder(root);
System.out.println("\n后序遍历:");
postOrder(root);
System.out.println("\n层次遍历:");
levelOrder(root);
System.out.print("\n计算卡特兰数:\n" + countTrees(3));
System.out.print("\n二叉查找树的查找操作:\n" + find(root1, 6).value);
System.out.print("\n计算二叉树高度:\n" + getBinaryLevel(root, 0));
System.out.println("\n二叉查找树的插入操作:");
insert(root1, 11);
System.out.println("\n二叉查找树插入节点11后:");
inOrder(root1);
System.out.println("\n二叉查找树的删除操作:");
delete(root1, 6);
}
}
点击“阅读原文”查看更多
以上是关于二叉树的遍历查找插入删除等的主要内容,如果未能解决你的问题,请参考以下文章