二叉搜索树(Binary Search Tree, BST)---第一篇---遍历、判断是否包含某一元素

一、何为二叉搜索树

二叉搜索树是二叉树的一种,对于二叉搜索树中的每一个结点,它具有以下特点:

1. 结点的值大于左子树中所有结点的值

2. 结点的值小于右子树中所有结点的值

3. 满足递归定义,每一棵子树也是二叉搜索树

二、BST类定义

public class BST<E extends Comparable<E>> {
	
	//结点类
	private class TreeNode{
		public E element;
		public TreeNode right;
		public TreeNode left;
		
		public TreeNode(E element) {
			this.element = element;
			right = null;
			left = null;
		}
		
	}
	
	private TreeNode root;   //跟结点
	private int size = 0;    //结点个数
	
	//构造方法
	public BST() {
		root = null;
	}

三、判断BST中是否包含某一元素

3.1 非递归实现

	public boolean contains(E element) {

		TreeNode current = root;
		
		while(current != null) {
		     //元素小于当前结点的元素,则只需在左子树中进行判断
			if(element.compareTo(current.element) < 0) {
				current = current.left;
			}
			 //元素大于当前结点的元素,则只需在右子树中进行判断
			else if(element.compareTo(current.element) > 0) {
				current = current.right;
			}
			else
				return true;  //当前结点的元素与要进行判断的元素值相等
		}
		return false;
	}

3.2 递归实现

//判断树中是否包含某一元素
	public boolean contains(E element) {  //此方法展现给用户
		return contains(root,element);
	}
	
	//递归实现详解,此方法用于内部实现
	private boolean contains(TreeNode node, E element) {
		if(node == null)
			return false;
		
		//元素小于当前结点元素,在左子树中递归遍历
		if(element.compareTo(node.element) < 0) {
			return contains(node.left, element);
		}
		//元素大于当前结点元素,在右子树中递归遍历
		else if(element.compareTo(node.element) > 0)
			return contains(node.right,element);
		else //元素等于当前结点元素
			return true;
	}

四、BST的遍历

二叉树的前序、中序和后序遍历统称为广度优先遍历

二叉树的层序遍历也称为广度优先遍历

*************************************************************************************

4.1 前序遍历(递归实现 + 非递归实现)

4.1.1 递归实现

// 递归前序遍历
public void preOrder() {
	preOrder(root);
}

private void preOrder(TreeNode node) {
	if(node == null)
		return;
	System.out.print(node.element + " "); //访问当前结点
	preOrder(node.left);   //在左子树中进行遍历
	preOrder(node.right);  //在右子树中进行遍历
}

4.1.2 非递归实现

    //非递归遍历
    /*
	 * 思路: 1. 根结点先入栈
	 * 		 2. 判断栈是否为空,若为空则结束遍历;
	 * 			若不为空,则弹出栈顶元素,然后访问栈顶元素
	 * 		 3. 若右孩子不为空,则右孩子入栈,否则执行第 4 步
	 * 		 4. 若左孩子不为空,则左孩子入栈,否则执行第 2 步,依次循环
	 * 注意: 左右孩子入栈顺序和遍历左右孩子的先后顺序正好相反
	 */
	public void preOrder() {
		 Stack<TreeNode> stack = new Stack<>();
		 stack.push(root);
		 
		 while(!stack.isEmpty()) {
			 
			 TreeNode current = stack.pop();
			 System.out.println(current.element);
			 if(current.right != null)
				 stack.push(current.right);
			 if(current.left != null)
				 stack.push(current.left);
		 }
	}

4.2 中序遍历(递归实现)

    //2. 中序遍历
	public void inOrder() {
		inOrder(root);
	}
	
	private void inOrder(TreeNode node) {
		if(node == null)
			return;
		inOrder(node.left);
		System.out.print(node.element + " ");
		inOrder(node.right);
	}

4.3 后序遍历(递归实现)

public void postOrder() {
		postOrder(root);
	}
	
	private void postOrder(TreeNode node) {
		if(node == null)
			return;
		postOrder(node.left);
		postOrder(node.right);
		System.out.print(node.element + " ");
	}

关于递归遍历的总结

递归的前序、中序和后序遍历的大致思路是一致的,只是访问根结点,遍历左子树,遍历右子树的顺序不同而已,需要注意的是:无论何种遍历方法,递归遍历左子树的操作一定在递归遍历右子树的操作的前面。

4.4 层序遍历(广度优先遍历)

	/* 
	 * 层序遍历(广度优先遍历)步骤:
	 * 1. 需要使用到队列,每次先使根结点入队
	 * 2. 判断队列是否为空
	 *   2.1 队列为空 说明树为空或遍历完成
	 *   2.2 队列非空,则执行出队操作,然后让当前结点的左孩子、右孩子依次入队
	 */
	public void levelOrder() {
		Queue<TreeNode> queue = new LinkedList<>();
		queue.add(root);   //根结点入队
		
		while(!queue.isEmpty()) {
			TreeNode current = queue.remove();     //出队
			System.out.print(current.element + " ");  
			
			if(current.left != null)
				queue.add(current.left);       //左孩子入队
			
			if(current.right != null)
				queue.add(current.right);     //右孩子入队
		}
	}

由于篇幅有点过长,关于BST的插入操作、删除操作,请参考我的其它博文,都有详细讲述。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值