二叉树的前序、中序、后序遍历、查找、删除

目录

一、需求

二、分析

2.1  如何建立一棵二叉树

2.2  如何定义一个结点类

2.3  遍历功能的位置?

三、遍历方式简介

四、代码实现

4.1  结点类中定义方法

4.2  二叉树类中定义方法

五、查找

5.1  代码实现

六、删除

6.1  需求

6.2  思路分析

6.3  代码实现


一、需求

      A:利用java建立一颗二叉树,并进行前序,中序,后序的遍历;

二、分析

2.1  如何建立一棵二叉树

      A:首先肯定要定义一个二叉树类,树必然有根结点,这是它本身就具有的属性,于是就定义为私有变量;

      B:至于这棵树的功能,那要有前序遍历、中序遍历、后序遍历的功能;

      C:而结点本身也是一个对象,也需要定义为一个类,下面讨论如何定义一个结点类;

2.2  如何定义一个结点类

      A:这个要根据,现实中的能作为结点的对象来决定的,比如把英雄看作结点,那么英雄要有名字等等,这

         就是结点本身的属性;

      B:结点本身可能作为父结点或子结点,从而作为左结点或右结点也是该结点的一个属性;

      C:而结点本身的功能,也是前序遍历、中序遍历、后序遍历;

2.3  遍历功能的位置?

      A:到底是在二叉树类中定义遍历功能,还是在结点类中定义遍历功能呢?

          a:每个结点都是一个具体的对象,它们之间都是有关系的;

          b:以前序遍历为例,输出根结点后,递归判断有没有左子结点,有就调用遍历函数,也就是结点需要调用

             方法来实现遍历;

          c:二叉树中也需要定义遍历功能,本身是由二叉树对象调用的,但实质上需要的是该二叉树对象传入的结点

             去调用结点中定义的遍历功能,比如传入根结点,一套套就下来了;

      B:设想一下,能否在二叉树类中直接定义遍历功能的具体实现,而不是依赖于结点定义的遍历功能?

          a:还是以前序遍历为例,明确返回值为void类型,参数列表应该为结点类型;

      C:下面会对A,B分别用代码进行实现,在这之前先明确前序、中序、后序遍历的概念;

三、遍历方式简介

四、代码实现

4.1  结点类中定义方法

package cn.itcast_01;

/*
 * 需求:
 *    A:实现二叉树的前序遍历,中序遍历和后序遍历
 * 分析:
 */
public class BinaryTreeDemo {
	public static void main(String[] args) {
		// 建立一棵树
		BinaryTree bt = new BinaryTree();
		// 创建结点对象
		HeroNode root = new HeroNode(1, "宋江");
		HeroNode node2 = new HeroNode(2, "吴用");
		HeroNode node3 = new HeroNode(3, "卢俊义");
		HeroNode node4 = new HeroNode(4, "林冲");
		// 手动将结点连起来,后期自动生成
		root.setLeft(node2);
		root.setRight(node3);
		node3.setRight(node4);
		// 把根结点传递给树对象
		bt.setRoot(root);
		// 前序遍历
		System.out.println("前序遍历:");
		bt.preOrder();
		System.out.println("------------");
		// 中序遍历
		System.out.println("中序遍历为:");
		bt.infixOrder();
		System.out.println("------------");
		// 后序遍历
		System.out.println("后序遍历为:");
		bt.postOrder();
	}
}

class HeroNode {
	// 英雄本身就具有的属性
	private int id;
	private String name;
	private HeroNode left;
	private HeroNode right;

	// 构造方法
	public HeroNode(int id, String name) {
		this.id = id;
		this.name = name;
	}

	// 自动生成get,set方法
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public HeroNode getLeft() {
		return left;
	}

	public void setLeft(HeroNode left) {
		this.left = left;
	}

	public HeroNode getRight() {
		return right;
	}

	public void setRight(HeroNode right) {
		this.right = right;
	}

	// toString方法
	@Override
	public String toString() {
		return "HeroNode [id=" + id + ", 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);
	}
}

// 有了结点,那就可以建一棵树了
class BinaryTree {
	// 这个树只需有个根就行,通过这个根去和其它的结点连成树
	private HeroNode root;

	// 生成构造方法
	public BinaryTree() {

	}

	public void setRoot(HeroNode root) {
		this.root = root;
	}

	// 前序遍历
	public void preOrder() {
		if (this.root != null) {
			this.root.preOrder();
		}
	}

	// 中序遍历
	public void infixOrder() {
		if (this.root != null) {
			this.root.infixOrder();
		}
	}

	// 后序遍历
	public void postOrder() {
		if (this.root != null) {
			this.root.postOrder();
		}
	}
}

4.2  二叉树类中定义方法

package cn.itcast_01;

/*
 * 需求:实现二叉树的前序遍历,中序遍历和后序遍历
 * 分析:根左右,左根右,左右根
 */
public class BinaryTreeDemo {

	public static void main(String[] args) {
		// 创建二叉树
		BinaryTree binaryTree = new BinaryTree();
		// 创建需要的结点
		HeroNode root = new HeroNode(1, "宋江");
		HeroNode node2 = new HeroNode(2, "吴用");
		HeroNode node3 = new HeroNode(3, "卢俊义");
		HeroNode node4 = new HeroNode(4, "林冲");
		// 先手动创建二叉树
		root.setLeft(node2);
		root.setRight(node3);
		node3.setRight(node4);
		binaryTree.setRoot(root);
		// 前序遍历
		System.out.println("前序遍历:");
		binaryTree.preOrder(root);
		// 中序遍历
		System.out.println("中序遍历:");
		binaryTree.infixOrder(root);
		// 后序遍历
		System.out.println("后序遍历:");
		binaryTree.postOrder(root);
		;
	}

}

// 定义BinaryTree 二叉树
class BinaryTree {

	private HeroNode root;

	public void setRoot(HeroNode root) {
		this.root = root;
	}

	// 前序遍历
	public void preOrder(HeroNode node) {
		if (node != null) {
			System.out.println(node);
			// 递归左子树
			if (node.left != null) {
				preOrder(node.left);
			}
			// 递归右子树
			if (node.right != null) {
				preOrder(node.right);
			}
		} else {
			System.out.println("二叉树为空,无法遍历");
		}
	}

	// 中序遍历
	public void infixOrder(HeroNode node) {
		if (node != null) {
			// 递归左子树
			if (node.left != null) {
				infixOrder(node.left);
			}
			System.out.println(node);
			// 递归右子树
			if (node.right != null) {
				infixOrder(node.right);
			}
		} else {
			System.out.println("二叉树为空,无法遍历");
		}
	}

	// 后序遍历
	public void postOrder(HeroNode node) {
		if (node != null) {
			// 递归左子树
			if (node.left != null) {
				postOrder(node.left);
			}
			// 递归右子树
			if (node.right != null) {
				postOrder(node.right);
			}
			System.out.println(node);
		} else {
			System.out.println("二叉树为空,无法遍历");
		}
	}
}

// 创建结点
class HeroNode {
	private int no;
	private String name;
	HeroNode left;
	HeroNode right;

	// 生成构造方法
	public HeroNode(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 HeroNode getLeft() {
		return left;
	}

	public void setLeft(HeroNode left) {
		this.left = left;
	}

	public HeroNode getRight() {
		return right;
	}

	public void setRight(HeroNode right) {
		this.right = right;
	}

	@Override
	public String toString() {
		return "HeroNode [no=" + no + ", name=" + name + "]";
	}
}

五、查找

5.1  代码实现

package tree.find;

/*
 * 需求:
 *    A:请编写前序查找,中序查找和后序查找的方法
 *    B:分别使用三种查找方式,查找英雄编号为5的结点
 *    C:分析各种查找方式,分别比较了多少次 
 * 分析:
 *    A:前序查找应该怎么写呢?
 *     a:在前序遍历的基础上,就不是去输出当前结点,而是判断当前结点
 *       是不是要查找的值;
 *     b:是查找的值就返回,不是就递归查找
 */
public class FindDemo {
	public static void main(String[] args) {
		// 建立一棵树
		BinaryTree bt = new BinaryTree();
		// 创建结点对象
		HeroNode root = new HeroNode(1, "宋江");
		HeroNode node2 = new HeroNode(2, "吴用");
		HeroNode node3 = new HeroNode(3, "卢俊义");
		HeroNode node4 = new HeroNode(4, "林冲");
		HeroNode node5 = new HeroNode(5, "关胜");
		// 手动将结点连起来,后期自动生成
		root.setLeft(node2);
		root.setRight(node3);
		node3.setLeft(node5);
		node3.setRight(node4);
		// 把根结点传递给树对象
		bt.setRoot(root);

		// 前序查找
		System.out.println("前序查找:");
		HeroNode resNode = bt.preOrder(3);
		if (resNode != null) {
			System.out.println(resNode);
		} else {
			System.out.println("没有该结点");
		}
		System.out.println("------------");

		// 中序查找
		System.out.println("中序查找:");
		resNode = bt.infixOrder(5);
		if (resNode != null) {
			System.out.println(resNode);
		} else {
			System.out.println("没有该结点");
		}
		System.out.println("------------");

		// 后序查找
		System.out.println("后序遍历为:");
		resNode = bt.postOrder(4);
		if (resNode != null) {
			System.out.println(resNode);
		} else {
			System.out.println("没有该结点");
		}
	}
}

class HeroNode {
	// 英雄本身就具有的属性
	private int id;
	private String name;
	private HeroNode left;
	private HeroNode right;

	// 构造方法
	public HeroNode(int id, String name) {
		this.id = id;
		this.name = name;
	}

	// 自动生成get,set方法
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public HeroNode getLeft() {
		return left;
	}

	public void setLeft(HeroNode left) {
		this.left = left;
	}

	public HeroNode getRight() {
		return right;
	}

	public void setRight(HeroNode right) {
		this.right = right;
	}

	// toString方法
	@Override
	public String toString() {
		return "HeroNode [id=" + id + ", name=" + name + "]";
	}

	// 前序查找
	public HeroNode preOrder(int id) {
		// 判断当前结点是否是要查找的结点
		if (this.id == id) {
			return this;
		}
		HeroNode resNode = null;
		if (this.left != null) {
			resNode = this.left.preOrder(id);
		}
		// 说明在左子树找到了
		if (resNode != null) {
			return resNode;
		}
		if (this.right != null) {
			resNode = this.right.preOrder(id);
		}
		return resNode;
	}

	// 中序查找
	public HeroNode infixOrder(int id) {
		// 定义中间变量用于返回
		HeroNode resNode = null;
		// 存在左子树,则递归左子树结点
		if (this.left != null) {
			resNode = this.left.infixOrder(id);
		}
		if (resNode != null) {
			return resNode;
		}
		// 判断当前结点是否为待查找的值
		if (this.id == id) {
			return this;
		}
		// 存在右子树,则递归右子树结点
		if (this.right != null) {
			resNode = this.right.infixOrder(id);
		}
		return resNode;
	}

	// 后序遍历
	public HeroNode postOrder(int id) {
		HeroNode resNode = null;
		if (this.left != null) {
			resNode = this.left.postOrder(id);
		}
		if (resNode != null) {
			return resNode;
		}
		if (this.right != null) {
			resNode = this.right.postOrder(id);
		}
		if (resNode != null) {
			return resNode;
		}
		//在比较之前判断进入后序查找的次数
		System.out.println("进入后序查找");
		// 判断当前结点是否为待查找的值
		if (this.id == id) {
			return this;
		}
		return resNode;
	}
}

// 有了结点,那就可以建一棵树了
class BinaryTree {
	// 这个树只需有个根就行,通过这个根去和其它的结点连成树
	private HeroNode root;

	// 生成构造方法
	public BinaryTree() {

	}

	public void setRoot(HeroNode root) {
		this.root = root;
	}

	// 前序遍历
	public HeroNode preOrder(int id) {
		if (this.root != null) {
			return this.root.preOrder(id);
		} else {
			return null;
		}
	}

	// 中序遍历
	public HeroNode infixOrder(int id) {
		if (this.root != null) {
			return this.root.infixOrder(id);
		} else {
			return null;
		}
	}

	// 后序遍历
	public HeroNode postOrder(int id) {
		if (this.root != null) {
			return this.root.postOrder(id);
		} else {
			return null;
		}
	}
}

六、删除

6.1  需求

       A:如果删除的结点是叶子结点,则删除该结点;

       B:如果删除的结点是非叶子结点,则删除该子树;

       C:测试,删掉5号叶子结点和3号子树;

6.2  思路分析

6.3  代码实现

public class FindDemo {
	public static void main(String[] args) {
		// 建立一棵树
		BinaryTree bt = new BinaryTree();
		// 创建结点对象
		HeroNode root = new HeroNode(1, "宋江");
		HeroNode node2 = new HeroNode(2, "吴用");
		HeroNode node3 = new HeroNode(3, "卢俊义");
		HeroNode node4 = new HeroNode(4, "林冲");
		HeroNode node5 = new HeroNode(5, "关胜");
		// 手动将结点连起来,后期自动生成
		root.setLeft(node2);
		root.setRight(node3);
		node3.setLeft(node5);
		node3.setRight(node4);
		// 把根结点传递给树对象
		bt.setRoot(root);
		// 删除结点前
		System.out.println("删除结点前:");
		bt.preOrder();
		System.out.println("删除结点后:");
		bt.delNode(3);
		if (bt.isEmptyTree()) {
			System.out.println("根结点已删,空树无法遍历!");
		} else {
			bt.preOrder();
		}
	}
}

// 定义结点类
class HeroNode {
	// 英雄本身就具有的属性
	private int id;
	private String name;
	private HeroNode left;
	private HeroNode right;

	// 构造方法
	public HeroNode(int id, String name) {
		this.id = id;
		this.name = name;
	}

	// 自动生成get,set方法
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public HeroNode getLeft() {
		return left;
	}

	public void setLeft(HeroNode left) {
		this.left = left;
	}

	public HeroNode getRight() {
		return right;
	}

	public void setRight(HeroNode right) {
		this.right = right;
	}

	// toString方法
	@Override
	public String toString() {
		return "HeroNode [id=" + id + ", name=" + name + "]";
	}

	// 定义删除方法
	public void deleNode(int id) {
		if (this.left != null && this.left.id == id) {
			this.left = null;
			return;
		}
		if (this.right != null && this.right.id == id) {
			this.right = null;
			return;
		}
		if (this.left != null) {
			this.left.deleNode(id);
		}
		if (this.right != null) {
			this.right.deleNode(id);
		}
	}

	// 定义前序遍历方法
	public void preOrder() {
		// 该函数由根结点调用,在调用前判断是否为空即可
		System.out.println(this);
		if (this.left != null) {
			this.left.preOrder();
		}
		if (this.right != null) {
			this.right.preOrder();
		}
	}
}

// 有了结点,那就可以建一棵树了
class BinaryTree {
	// 这个树只需有个根就行,通过这个根去和其它的结点连成树
	private HeroNode root;

	// 生成构造方法
	public BinaryTree() {
	}

	public void setRoot(HeroNode root) {
		this.root = root;
	}

	// 判断是否为空树
	boolean isEmptyTree() {
		if (this.root == null)
			return true;
		else
			return false;
	}

	// 定义删除方法
	public void delNode(int id) {
		if (root != null) {
			if (root.getId() == id) {
				root = null;
			} else {
				root.deleNode(id);
			}
		} else {
			System.out.println("空树无法删除!");
		}
	}

	// 定义前序遍历
	public void preOrder() {
		this.root.preOrder();
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值