java 二叉树查询_(Java实现)二叉树---遍历、查询、删除算法

本文介绍了使用Java实现二叉树的前序、中序和后序遍历,以及如何通过遍历实现二叉树的查询和删除操作。详细讲解了遍历方法,并给出了具体代码示例。
摘要由CSDN通过智能技术生成

使用的数据结构

这里使用的数据结构是一个节点对象,代码如下:public class TreeNode {

private Integer val;//序号

private TreeNode left;//左孩子

private TreeNode right;//右孩子

public TreeNode(int val){

this.val = val;

}

public Integer getVal() {

return val;

}

public void setVal(Integer val) {

this.val = val;

}

public TreeNode getLeft() {

return left;

}

public void setLeft(TreeNode left) {

this.left = left;

}

public TreeNode getRight() {

return right;

}

public void setRight(TreeNode right) {

this.right = right;

}

}

遍历要实现二叉树的遍历有三种办法,分别是前序遍历、中序遍历和后序遍历前序遍历:先找父节点,再找左右子节点

中序遍历:先找左子节点,再找父节点,最后找右子节点

后序遍历:先找左右子节点,再找父节点

从这可以看出,所谓的前/中/后序,其实是相对于父节点来说,如果是前序,那么父节点就是先于左右子节点,如果是中序,那么父节点就是在左右子节点中间,如果是后序,那么父节点就是在最后

举个例子:如下图所示7d3c3e68d2644fa7e47bd68fe1cc4af5.png对于前序:先输出父节点18,再看左子节点20,左子节点也是个父节点,输出20,再看20的左子节点16,发现16是个叶子节点直接输出。

这样对于父节点18来说,它自己本身以及它的左子节点已经遍历完了,再看它的右子节点29

右子节点29是父节点,先输出29,再看29的左子节点,发现是个叶子节点,直接输出。再看29的右子节点,也是8,直接输出

这样整个二叉树就遍历完了

中序和后序也是一样的方法

代码如下:

我这里用的是递归的方法public class TreeTraversal {

//前序遍历

public static void preorder_Traversal(TreeNode root){

if (root == null) return;

System.out.println(root.getVal());

preorder_Traversal(root.getLeft());

preorder_Traversal(root.getRight());

}

//中序遍历

public static void inorder_Traversal(TreeNode root){

if (root == null) return;

inorder_Traversal(root.getLeft());

System.out.println(root.getVal());

inorder_Traversal(root.getRight());

}

//后序遍历

public static void postorder_Traversal(TreeNode root){

if (root == null) return;

postorder_Traversal(root.getLeft());

postorder_Traversal(root.getRight());

System.out.println(root.getVal());

}

public static void main(String[] args) {

TreeNode node1 = new TreeNode(18);

TreeNode node2 = new TreeNode(20);

TreeNode node3 = new TreeNode(29);

TreeNode node4 = new TreeNode(16);

TreeNode node5 = new TreeNode(39);

TreeNode node6 = new TreeNode(8);

node1.setLeft(node2);

node1.setRight(node3);

node2.setLeft(node4);

node3.setLeft(node5);

node3.setRight(node6);

postorder_Traversal(node1);

}

}

查询查询和遍历是一样的,也分前序、中序和后序,只是在遍历的时候多进行一次比较,这里就不多说了

代码如下://前序查找

public static TreeNode preOrder_Search(TreeNode root, int findVal){

if (root == null) return null;

//判断当前节点的值是否等于findVal

if (root.getVal() == findVal){

return root;

}

//向左子节点递归查找

TreeNode node = preOrder_Search(root.getLeft(), findVal);

//如果node不为空,证明找到了

if (node != null) return node;

//如果左子节点没有找到,向右查找

node = preOrder_Search(root.getRight(), findVal);

if (node != null) return node;

return node;

}

//中序查找

public static TreeNode inOrder_Search(TreeNode root, int findVal){

if (root == null) return null;

//向左子节点递归查找

TreeNode node = inOrder_Search(root.getLeft(), findVal);

//如果node不为空,证明找到了

if (node != null) return node;

//判断当前节点的值是否等于findVal

System.out.println("比较");

if (root.getVal() == findVal){

return root;

}

//如果左子节点没有找到,向右查找

node = inOrder_Search(root.getRight(), findVal);

if (node != null) return node;

return node;

}

//后序查找

public static TreeNode postOrder_Search(TreeNode root, int findVal){

if (root == null) return null;

//向左子节点递归查找

TreeNode node = postOrder_Search(root.getLeft(), findVal);

//如果node不为空,证明找到了

if (node != null) return node;

//如果左子节点没有找到,向右查找

node = postOrder_Search(root.getRight(), findVal);

if (node != null) return node;

//判断当前节点的值是否等于findVal

System.out.println("比较");

if (root.getVal() == findVal){

return root;

}

return node;

}

删除二叉树删除节点有两种情况:1)删除的是叶子节点,则直接删除

2)删除的是非叶子节点,则要删除子树

基本思路:1)如果只有一个根节点,并且是我们要找的节点,则直接置空

2)判断当前节点的子节点是否是要删除的节点:如果当前节点的左子节点不为空,并且是要删除的节点,那么将左子节点置空

如果当前节点的右子节点不为空,并且是要删除的节点,那么将右子节点置空

3)如果当前节点的子节点不是要删除的节点,那么向左子树递归

4)如果步骤3)也没删除,那么向右子树递归

代码如下:public class TreeTraversal {

private static TreeNode root = null;

//前序遍历

public static void preorder_Traversal(TreeNode root){

if (root == null) return;

System.out.print(root.getVal() + " ");

preorder_Traversal(root.getLeft());

preorder_Traversal(root.getRight());

}

//中序遍历

public static void inorder_Traversal(TreeNode root){

if (root == null) return;

inorder_Traversal(root.getLeft());

System.out.println(root.getVal());

inorder_Traversal(root.getRight());

}

//后序遍历

public static void postorder_Traversal(TreeNode root){

if (root == null) return;

postorder_Traversal(root.getLeft());

postorder_Traversal(root.getRight());

System.out.println(root.getVal());

}

//前序查找

public static TreeNode preOrder_Search(TreeNode root, int findVal){

if (root == null) return null;

//判断当前节点的值是否等于findVal

if (root.getVal() == findVal){

return root;

}

//向左子节点递归查找

TreeNode node = preOrder_Search(root.getLeft(), findVal);

//如果node不为空,证明找到了

if (node != null) return node;

//如果左子节点没有找到,向右查找

node = preOrder_Search(root.getRight(), findVal);

if (node != null) return node;

return node;

}

//中序查找

public static TreeNode inOrder_Search(TreeNode root, int findVal){

if (root == null) return null;

//向左子节点递归查找

TreeNode node = inOrder_Search(root.getLeft(), findVal);

//如果node不为空,证明找到了

if (node != null) return node;

//判断当前节点的值是否等于findVal

System.out.println("比较");

if (root.getVal() == findVal){

return root;

}

//如果左子节点没有找到,向右查找

node = inOrder_Search(root.getRight(), findVal);

if (node != null) return node;

return node;

}

//后序查找

public static TreeNode postOrder_Search(TreeNode root, int findVal){

if (root == null) return null;

//向左子节点递归查找

TreeNode node = postOrder_Search(root.getLeft(), findVal);

//如果node不为空,证明找到了

if (node != null) return node;

//如果左子节点没有找到,向右查找

node = postOrder_Search(root.getRight(), findVal);

if (node != null) return node;

//判断当前节点的值是否等于findVal

System.out.println("比较");

if (root.getVal() == findVal){

return root;

}

return node;

}

//删除节点

public static void delete(int val){

deleteRootNode(val);

}

public static void deleteRootNode(int val){

if (root == null) return;

if (root.getVal() == val){

root = null;

}else {

deleteChildNode(root, val);

}

}

public static void deleteChildNode(TreeNode root, int val){

if (root.getLeft() != null && root.getLeft().getVal() == val){

root.setLeft(null);

return; }

if (root.getRight() != null && root.getRight().getVal() == val){

root.setRight(null);

return; }

if (root.getLeft() != null){

deleteChildNode(root.getLeft(), val);

}

if (root.getRight() != null){

deleteChildNode(root.getRight(), val);

}

}

public static void main(String[] args) {

root = new TreeNode(18);

TreeNode node2 = new TreeNode(20);

TreeNode node3 = new TreeNode(29);

TreeNode node4 = new TreeNode(16);

TreeNode node5 = new TreeNode(39);

TreeNode node6 = new TreeNode(8);

root.setLeft(node2);

root.setRight(node3);

node2.setLeft(node4);

node3.setLeft(node5);

node3.setRight(node6);

preorder_Traversal(root);

delete(20);

System.out.println();

preorder_Traversal(root);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值