码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-04-03 06:45:14      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

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

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

/**
 * 二叉树的节点类
 * 
 * @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

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

标签:

原文地址:http://www.cnblogs.com/fange666/p/4388945.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!