二叉树(二叉树遍历与查找):
树有很多种,每个节点最多只能有两个子节点的一种形式称为二叉树,二叉树的子节点分为左节点与右节点。
如果该二叉树所有的叶子节点都在最后一层,并且满足结点的总数 = 2^n - 1(n为树的层数),则称为满二叉树。 如果二叉树的所有叶子节点(没有子节点的节点)都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,则称为完全二叉树。
1、遍历二叉树
前序遍历:先输出父节点,再遍历左子树和右子树。
(1)先输出当前节点(初始的节点为root)
(2)如果左子节点不为空,则递归前序遍历
(3)如果右子节点不为空,则递归前序遍历
中序遍历:先遍历左子树,再输出父节点,再遍历右子树
(1)如果左子节点不为空,则递归中序遍历
(2)输出当前节点(初始的节点为root)
(3)如果右子节点不为空,则递归中序遍历
后序遍历:先遍历左子树,再遍历右子树,最后输出父节点
(1)如果左子节点不为空,则递归后序遍历
(2)如果右子节点不为空,则递归后序遍历
(3)输出当前节点(初始的节点为root)
2、通过遍历查找二叉树结点
编写前序查找结点
思路:
(1)先判断当前结点是否等于要查找到的,如果是则返回当前结点
(2)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
判断左子结点是否等于要查找的,如果是则返回当前结点。
(3)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
判断右子结点是否等于要查找的,如果是则返回当前结点
编写中序查找结点
思路:
(1)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
判断左子结点是否等于要查找的,如果是则返回当前结点。
(2)先判断当前结点是否等于要查找到的,如果是则返回当前结点
(3)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
判断右子结点是否等于要查找的,如果是则返回当前结点
编写后序查找结点
思路:
(1)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
判断左子结点是否等于要查找的,如果是则返回当前结点。
(2)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
判断右子结点是否等否于要查找的,如果是则返回当前结点
(3)先判断当前结点是等于要查找到的,如果是则返回当前结点
(1)对以下二叉树进行前序、中序、后序遍历
(2)对以下二叉树进行前序、中序、后续遍历查找
实现代码:
package com.struct;
import java.util.Scanner;
public class BinaryTreeDemo {
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
//手动创建一个树
Node root = new Node(1, "马一");
Node node1 = new Node(2, "马二");
Node node2 = new Node(3, "马三");
Node node3 = new Node(4, "马四");
Node node4 = new Node(5, "马五");
root.setLeft(node1);
root.setRight(node2);
node2.setLeft(node4);
node2.setRight(node3);
binaryTree.setRoot(root);
// //前序遍历
// binaryTree.preOrder();
// //中序遍历
// binaryTree.infixOrder();
// //后序遍历
// binaryTree.postOrder();
Scanner scanner = new Scanner(System.in);
//前序遍历查找
// System.out.println("前序遍历查找~请输入需要查找用户的ID");
// int no = scanner.nextInt();
// Node resNode = binaryTree.preOrderSearch(no);
// if (resNode != null)
// System.out.println("找到该结点:no = " + resNode.getNo() + " name = " + resNode.getName());
// else
// System.out.println("没有找到no=%d,此结点" + no);
//中序遍历查找
// System.out.println("中序遍历查找~请输入需要查找用户的ID");
// int no = scanner.nextInt();
// Node resNode = binaryTree.infixOrderSearch(no);
// if (resNode != null)
// System.out.println("找到该结点:no = " + resNode.getNo() + " name = " + resNode.getName());
// else
// System.out.println("没有找到no=%d,此结点" + no);
System.out.println("后序遍历查找~请输入需要查找用户的ID");
int no = scanner.nextInt();
Node resNode = binaryTree.postOrderSearch(no);
if (resNode != null)
System.out.println("找到该结点:no = " + resNode.getNo() + " name = " + resNode.getName());
else
System.out.println("没有找到no=%d,此结点" + no);
}
}
class BinaryTree
{
private Node root;//定义根结点
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
//前序遍历
public void preOrder()
{
if (root != null)
this.root.preOrder();
else {
System.out.println("二叉树为空,无法遍历");
}
}
//中续遍历
public void infixOrder()
{
if (root != null)
this.root.infixOrder();
else {
System.out.println("二叉树为空,无法遍历");
}
}
//后续遍历
public void postOrder()
{
if (root != null)
this.root.postOrder();
else {
System.out.println("二叉树为空,无法遍历");
}
}
//前序遍历查找
public Node preOrderSearch(int no)
{
//如果根结点不为空,则返回前序遍历查找的结果
if (root != null)
return root.preOrderSearch(no);
else {
return null;
}
}
//中序遍历查找
public Node infixOrderSearch(int no)
{
//如果根结点不为空,则返回中序遍历查找的结果
if (root != null)
return root.infixOrderSearch(no);
else
return null;
}
//后序遍历查找
public Node postOrderSearch(int no)
{
//如果根结点不为空,则返回后序遍历查找的结果
if (root != null)
return this.root.postOrderSearch(no);
else
return null;
}
}
//定义节点类
class Node
{
private int no;//定义节点编号
private String name;//定义节点名称
private Node left;//定义节点左子节点
private Node right;//定义节点右子节点
public Node(int no, String name) {
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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;
}
@Override
public String toString() {
return "Node{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
//编写前序遍历
public void preOrder()
{
//首先输出该节点
System.out.println(this);
//如果左子节点不为空,则继续递归前序遍历
if (this.left != null)
this.left.preOrder();
//如果右子节点不为空,则继续递归前序遍历
if (this.right != null)
this.right.preOrder();
}
//编写中序遍历
public void infixOrder()
{
//如果左子节点不为空,则继续递归前序遍历
if (this.left != null)
this.left.infixOrder();
//首先输出该节点
System.out.println(this);
//如果右子节点不为空,则继续递归前序遍历
if (this.right != null)
this.right.infixOrder();
}
//编写后序遍历
public void postOrder()
{
//如果左子节点不为空,则继续递归前序遍历
if (this.left != null)
this.left.postOrder();
//如果右子节点不为空,则继续递归前序遍历
if (this.right != null)
this.right.postOrder();
//首先输出该节点
System.out.println(this);
}
/*编写前序查找结点
思路:
(1)先判断当前结点是否等于要查找到的,如果是则返回当前结点
(2)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
判断左子结点是否等于要查找的,如果是则返回当前结点。
(3)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
判断右子结点是否等于要查找的,如果是则返回当前结点
*/
public Node preOrderSearch(int no)
{
System.out.println("前序遍历~~~~~~~~~");
//判断当前结点是否为等于需查找的
if (this.no == no)
{
return this;
}
Node node = null;
//若没找到,向左递归继续查找
if (this.left != null)
node = this.left.preOrderSearch(no);
if (node != null)//此时说明向左递归已找到
return node;
//若没找到,向右递归继续查找
if (this.right != null)
node = this.right.preOrderSearch(no);
return node;
}
/*编写中序查找结点
思路:
(1)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
判断左子结点是否等于要查找的,如果是则返回当前结点。
(2)先判断当前结点是否等于要查找到的,如果是则返回当前结点
(3)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
判断右子结点是否等于要查找的,如果是则返回当前结点
*/
public Node infixOrderSearch(int no)
{
Node node = null;
//向左递归查找
if (this.left != null)
{
node = this.left.infixOrderSearch(no);
}
if (node != null)//此时说明已经找到
return node;
System.out.println("中序遍历~~~~~~~~~");
//判断当前结点是否等于要查找的
if (this.no == no)
return this;
//如果没找到,向右递归查找
if (this.right != null)
node = this.right.infixOrderSearch(no);
return node;
}
/*编写后序查找结点
思路:
(1)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
判断左子结点是否等于要查找的,如果是则返回当前结点。
(2)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
判断右子结点是否等否于要查找的,如果是则返回当前结点
(3)先判断当前结点是等于要查找到的,如果是则返回当前结点
*/
public Node postOrderSearch(int no)
{
Node node = null;//定义一个空结点
//向左递归开始查找
if (this.left != null)
node = this.left.postOrderSearch(no);
if (node != null)//此时已找到
return node;
//向右递归开始查找
if (this.right != null)
node = this.right.postOrderSearch(no);
if (node != null)//此时已找到
return node;
System.out.println("后序遍历~~~~~~~~~");
//判断当前结点是否等于要查找的
if (this.no == no)
return this;
return node;
}
}