Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作

什么也不说了,直接上代码。

首先是节点类,大家都懂得

/**
 * 二叉树的节点类
 *
 * @author HeYufan
 *
 * @param <T>
 */
class Node<T extends Comparable<? super T>>
{
	/**
	 * 节点储存的值
	 */
	private T data;
	/**
	 * 左子节点
	 */
	private Node<T> leftNode;
	/**
	 * 右子节点
	 */
	private Node<T> rightNode;

	public Node()
	{
		this(null);
	}

	public Node(T data)
	{
		this.data = data;
		this.leftNode = null;
		this.rightNode = null;
	}

	/**
	 * @return data
	 */
	public T getData()
	{
		return data;
	}

	/**
	 * @param data
	 *            要设置的 data
	 */
	public void setData(T data)
	{
		this.data = data;
	}

	/**
	 * @return leftNode
	 */
	public Node<T> getLeftNode()
	{
		return leftNode;
	}

	/**
	 * @param leftNode
	 *            要设置的 leftNode
	 */
	public void setLeftNode(Node<T> leftNode)
	{
		this.leftNode = leftNode;
	}

	/**
	 * @return rightNode
	 */
	public Node<T> getRightNode()
	{
		return rightNode;
	}

	/**
	 * @param rightNode
	 *            要设置的 rightNode
	 */
	public void setRightNode(Node<T> rightNode)
	{
		this.rightNode = rightNode;
	}

}

  

然后是二叉搜索树的实现

/**
 *
 */
package dataStructure.tree.binarytree;

import java.util.LinkedList;
import java.util.Queue;

/**
 * 二叉排序树
 *
 * @author HeYufan
 *
 */
public class BinaryTree<T extends Comparable<? super T>>
{
	// 二叉树的根节点
	private Node<T> root;
	// 二叉树的节点总数
	private int size;

	public BinaryTree()
	{
		this.root = null;
		this.size = 0;
	}

	// 根据一个节点生成二叉树(该节点作为根节点)
	public BinaryTree(Node<T> root)
	{
		this.root = root;
		this.size = 1;
	}

	/**
	 * 插入
	 *
	 * @param value
	 *            要插入二叉树的值
	 */
	public void insert(T value)
	{
		root = insert(this.root, value);
	}

	/**
	 * 二叉树的节点总数
	 *
	 * @return
	 */
	public int size()
	{
		return this.size;
	}

	/**
	 * 二叉树是否为空树
	 *
	 * @return
	 */
	public boolean isEmpty()
	{
		return this.size == 0;
	}

	/**
	 * 检测二叉树的节点是否包含value
	 *
	 * @param value
	 * @return
	 */
	public boolean isContain(T value)
	{
		return isContain(root, value);
	}

	/**
	 * 递归比较node节点的值与value
	 *
	 * @param node
	 * @param value
	 * @return
	 */
	private boolean isContain(Node<T> node, T value)
	{
		// 如果指定节点为空,说明当前二叉树不包含value,返回false
		if(node == null)
		{
			return false;
		}

		// node节点的值与value比较的结果
		int result = node.getData().compareTo(value);
		// 如果result等于0,说明node节点的值与value值相同,说明二叉搜索树包含value,返回true
		if(result == 0)
		{
			return true;
		}
		// 如果result小于0,说明node节点的值小于value,继续递归比较node的右子节点与value
		else if(result < 0)
		{
			return isContain(node.getRightNode(), value);
		}
		// 如果result大于0,说明node节点的值大于value,继续递归比较node的左子节点与value
		else
		{
			return isContain(node.getLeftNode(), value);
		}
	}

	/**
	 * 获取二叉树中的最小值
	 *
	 * @return
	 */
	public T getMin()
	{
		// 如果二叉树为空,则返回null
		if(isEmpty())
		{
			return null;
		}
		return getMin(root).getData();
	}

	/**
	 * 根据二叉搜索树的性质,我们可以知道一颗二叉搜索树的最小值一定是这棵树最左边的节点
	 *
	 * @param node
	 *            要搜索的根节点
	 * @return
	 */
	private Node<T> getMin(Node<T> node)
	{
		Node<T> leftNode = node.getLeftNode();
		// 如果当前节点的左节点为空,说明这个节点的值就是这棵树最小的值
		if(leftNode == null)
		{
			return node;
		}
		else
		{
			// 否则,递归遍历当前节点的左子树
			return getMin(leftNode);
		}
	}

	/**
	 * 获取二叉树中的最大值(不采用递归方式,递归方式类似getMin)
	 *
	 * @return
	 */
	public T getMax()
	{
		// 如果当前二叉树为空,返回null
		if(isEmpty())
		{
			return null;
		}
		Node<T> rightNode = this.root;
		// 判断当前节点(从root节点开始)是否有右子节点
		// 如果没有,说明当前节点的值就是该二叉搜索树的做大值,当前循环结束
		// 否则,让rightNode指向当前节点的右子节点,继续while循环
		while (rightNode.getRightNode() != null)
		{
			rightNode = rightNode.getRightNode();
		}
		return rightNode.getData();
	}

	/**
	 * 将值value插入到以node为根节点的二叉树下
	 *
	 * @param node
	 *            目标子树的根节点
	 * @param value
	 *            要插入的值
	 * @return 这里返回的node其实就是更新后的根节点
	 */
	private Node<T> insert(Node<T> node, T value)
	{
		// 如果要插入的目标根节点为null,则这个节点就是要插入值的地方
		if(node == null)
		{
			node = new Node<T>(value);
			this.size++;
			return node;
		}
		// 0表示value等于node的值;-1表示value小于node的值;1表示value大于node的值
		int result = value.compareTo(node.getData());
		if(result < 0)
		{
			// 当value小于node的值,则将value插入到node节点的左子树中,此时value的目标节点就是node.getLeftNode()
			node.setLeftNode(insert(node.getLeftNode(), value));
		}
		else if(result > 0)
		{
			// 当value大于node的值,则将value插入到node节点的右子树中,此时value的目标节点就是node.getRightNode()
			node.setRightNode(insert(node.getRightNode(), value));
		}
		else
		{
			// 如果result = 0,说明插入的值已经存在了,可以选择更新值或者什么也不做
		}
		return node;
	}

	/**
	 * 先序遍历
	 */
	public void preorder()
	{
		preorder(root);
	}

	/**
	 * 后序遍历
	 */
	public void postorder()
	{
		postorder(root);
	}

	/**
	 * 中序遍历
	 */
	public void inorder()
	{
		inorder(root);
	}

	/**
	 * 层序遍历
	 */
	public void level()
	{
		if(root == null)
			return;
		Queue<Node<T>> queue = new LinkedList<Node<T>>();
		queue.add(root);
		Node<T> node = null;
		while (queue.size() != 0)
		{
			node = queue.poll();
			System.out.println(node.getData());
			if(node.getLeftNode() != null)
				queue.add(node.getLeftNode());
			if(node.getRightNode() != null)
				queue.add(node.getRightNode());
		}
	}

	/**
	 * 先序遍历:遍历以node为根节点的子树 先打印节点的值,再遍历节点的左子树,最后遍历节点的右子树
	 *
	 * @param node
	 *            要遍历的子树的根节点
	 */
	private void preorder(Node<T> node)
	{
		if(node == null)
		{
			return;
		}
		else
		{
			// 打印节点的值
			System.out.println(node.getData());
			// 递归遍历该节点的左子树
			preorder(node.getLeftNode());
			// 递归遍历该节点的右子树
			preorder(node.getRightNode());
		}
	}

	/**
	 * 后序遍历:遍历以node为根节点的子树;先遍历节点的左子树,再遍历节点的右子树,最后打印节点的值
	 *
	 * @param node
	 *            要遍历的子树的根节点
	 */
	private void postorder(Node<T> node)
	{
		if(node == null)
		{
			return;
		}
		else
		{
			// 递归遍历该节点的左子树
			postorder(node.getLeftNode());
			// 递归遍历该节点的右子树
			postorder(node.getRightNode());
			// 打印节点的值
			System.out.println(node.getData());
		}
	}

	/**
	 * 中序遍历:遍历以node为根节点的子树;先遍历左子树,再打印节点的值,最后遍历右子树
	 *
	 * @param node
	 */
	private void inorder(Node<T> node)
	{
		if(node == null)
		{
			return;
		}
		else
		{
			// 递归遍历该节点的左子树
			inorder(node.getLeftNode());
			// 打印节点的值
			System.out.println(node.getData());
			// 递归遍历该节点的右子树
			inorder(node.getRightNode());
		}
	}
}

  

测试:

/**
 *
 */
package dataStructure.test;

import dataStructure.tree.binarytree.BinaryTree;

/**
 * @author Administrator
 *
 */
public class TestBinaryTree
{
	public static void main(String[] args)
	{
		BinaryTree<Integer> tree = new BinaryTree<Integer>();
		tree.insert(5);
		tree.insert(3);
		tree.insert(2);
		tree.insert(7);
		tree.insert(8);
		tree.insert(4);
		tree.insert(1);
		tree.insert(4);
		tree.insert(1);
		System.out.println("是否包含1:" + tree.isContain(1));
		System.out.println("是否包含10:" + tree.isContain(10));
		System.out.println("树的节点数:" + tree.size());
		System.out.println("树的最大值:" + tree.getMax());
		System.out.println("树的最小值:" + tree.getMin());
		System.out.println("先序遍历:");
		tree.preorder();
		System.out.println("后序遍历:");
		tree.postorder();
		System.out.println("中序遍历:");
		tree.inorder();
		System.out.println("层序遍历:");
		tree.level();

	}
}

  

树的结构:

输出结果:

是否包含1:true
是否包含10:false
树的节点数:7
树的最大值:8
树的最小值:1

先序遍历:

5
3
2
1
4
7
8
后序遍历:
1
2
4
3
8
7
5
中序遍历:
1
2
3
4
5
7
8
层序遍历:
5
3
7
2
4
8
1

时间: 2024-10-13 11:50:13

Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作的相关文章

Java实现二叉搜索树

原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11406176.html 尝试一下用Java实现二叉搜索树/二叉查找树,记录自己的学习历程. 1. 首先先来设计实现一下节点Node. ??一个二叉树的节点需要以下几个元素: key 关键字 value 节点的值(key也可以代替value) parent 父节点 leftChildren 左儿子节点 rightChildren 右儿子节点 那就开始吧! /** * 节点 */ class N

Java实现二叉搜索树节点的删除

前言: 之前写过一篇关于二叉搜索树的博客:Java对二叉搜索树进行插入.查找.遍历.最大值和最小值的操作  二叉查找树重要性质: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉排序树: 如图: 这次我想分享的是二叉搜索树中节点是如何删除的,删除节点是二叉搜索树常用的一般操作中最复杂的,删除节点要从查找要删除的节点开始入手 ,找到节点后,这个要删除的节点可能会有三种情况需要考虑: 1

Java数据结构——二叉搜索树

定义二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉排序树. 性质1,任意节点x,其左子树中的key不大于x.key,其右子树中的key不小于x.key.2,不同的二叉搜索树可以代表同一组值的集合.3,二叉搜索树的基本操作和树的高度成正比,所以如果是一棵完全二叉树

[98]验证二叉搜索树&amp;[105]从前序与中序遍历序列构造二叉树

扯闲话时间...很长一段时间没有刷题了,因为工作做得一团糟,惨遭领导怒批,心理压力大得一批导致工作时间特别长又没产出,所以刷题就搁置了... (小声BB)其实感觉领导有点刀子嘴豆腐心,一面说着"公司没义务从零培养新人,我自己也很久不带新人了",一面又给我讲了好多基础知识... 好了,言归正传,今天分享两道题,同类型的,力扣(leetcode中国)给的标签都是深度优先搜索,但是我都没想出来怎么用深度优先,所以都采用了递归. 这里提一句,曾经有位前辈和我说实际工作中递归并不常用,因为递归长

Java对二叉搜索树进行插入、查找、遍历、最大值和最小值的操作

1.首先,需要一个节点对象的类.这些对象包含数据,数据代表存储的内容,而且还有指向节点的两个子节点的引用 class Node { public int iData; public double dData; public Node leftChild; public Node rightChild; public void displayNode() { System.out.print("{"); System.out.print(iData); System.out.print(

26.二叉搜索树与双向链表

题目描述: ??输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路分析: ??要将二叉搜索树转换为一个排序的双向链表,且不能创建新的节点.首先要求是排序的,那么由于二叉搜索树的特殊性,只要我们中序遍历二叉树,就能得到有序序列,然后我们可以将每个节点的指向左右孩子的指针,改成指向前节点和后节点.这样就可以实现题目要求,我们可以先用队列保存中序遍历后节点的顺序.然后改变每个节点的left,right指针,得到排序的双向链表. 代码

二叉树-二叉搜索树(中序)

题型: (1)验证 (2)修复(排列不正确,修复) (3)构造(给排列求树-平衡的:种类) (4)利用性质求第n个结点 二叉搜索树的思路:中序输出+相关操作 如果要求空间复杂度O(1),考虑莫里斯遍历 98. 验证二叉搜索树    面试题 04.05. 合法二叉搜索树 (1) 思路:中序排列,看次序 1 class Solution { 2 public boolean isValidBST(TreeNode root) { 3 // if(root==null){ // 题目空树是true 4

二叉搜索树 思想 JAVA实现

二叉搜索树:一棵二叉搜索树是以一棵二叉树来组织的,这样一棵树可以使用链表的数据结构来表示(也可以采用数组来实现).除了key和可能带有的其他数据外,每个节点还包含Left,Right,Parent,它们分别指节点的左孩子,右孩子,和父节点. 一个二叉搜索树总是满足 :node.left.key<node.key<=node.right.key. 以下是一个用java实现的二叉搜索树,包含了查找最大值,最小值,查找某一节点,插入和删除操作. 接下来通过代码来分析二叉搜索树中的思想:在代码实现二叉

剑指Offer面试题24(Java版):二叉搜索树的后序遍历序列

题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 例如输入数组{5,7,6,9,11,10,8}则返回true,因为这个整数序列是下图二叉树的后序遍历的结果.如果输入的数组是{7,4,6,5},由于没有哪颗二叉搜索树的后续遍历的结果是这个序列,因此返回false. 在后序遍历得到的序列中,最后一个数字是树的根节点的值.数组中前面的数字可以分为两部分:第一部分是左子树结点的值,它们都比根节点的值