java实现二叉树的先序、中序和后序迭代器

       二叉树是每个节点最多有两个子树的有序树,通常子树的根被称作左子树(left subtree)和右子树(right subtree)。二叉树常被用作二叉查找树和二叉堆或者是二叉排序树。二叉树的每个节点至多只有两棵子树(不存在度大于2的节点),二叉树的子树有左右之分,不能颠倒。而访问一棵二叉树中的所有结点,必须(1)访问根(2)访问根的左子树中的所有结点(3)访问根的右子树中的所有结点。访问根是在访问子树之前、中间还是之后决定了三种常见的顺序:先序遍历(preorder traversal)、中序遍历(inorder traversal)和后序遍历(postorder traversal)。其中,先序遍历中,访问根是在访问根的子树之前,然后,访问根的左子树中的所有结点是在访问右子树中的所有结点之前;中序遍历是先访问根的左子树中的所有结点,然后访问根,最后访问根的右子树的所有结点;后序遍历则是先访问根的左子树,右子树,最后是根。

       实现二叉树的先序、中序和后序的递归方法并不困难,但是递归遍历有它的局限,就是该方法在遍历过程中只显示数据,一旦该方法被调用就进行整个二叉树的遍历。为了给客户提供更多的灵活性,应该将遍历定义为迭代器。这样,客户在访问时能做的就不只是显示数据,而且可以控制访问。下面就以下图的二叉树实现其三种顺序的迭代器版本:

                                                                                                                    

先序的迭代器版本:在定义迭代器之前,先考虑先序遍历的迭代版本。下图为使用栈对上图的二叉树进行先序遍历的结果。首先将根节点a压入栈,随后从栈中弹出并显示之,再将a的右结点c(如果有右结点)压入栈,然后将a的左结点b压入栈,并弹出显示,再将b以根的右结点e压入栈,然后将以b为根的左结点d压入栈并弹出。该过程继续下去,直到访问了所有结点,即直到栈为空并且当前结点为null。

中序的迭代器版本:首先将根结点a压入栈,然后尽可能地向左前进,将每个结点都压入栈,随后从栈中弹出并显示之,由于d没有右孩子,再次出栈并显示b,现在b有右孩子e,后者被压入栈,由于e没有孩子,将它从栈中弹出并显示。该过程继续下去,直到访问了所有的结点。

后序的迭代器版本:首先将根节点a压入栈,然后尽可能地向左前进,将每个结点都压入栈,然后检查栈顶结点是否存在右孩子,由于d没有右孩子,则弹出并显示之,而b存在右孩子,则将e压入栈中,随后弹出并显示,再将b弹出并显示。该过程继续下去,直到访问了所有的结点。

                                                     

下面是三种排序的迭代器java源代码:

先序迭代器类实现:

private class PreorderIterator implements Iterator<T>
	{
        Stack<BinaryNodeInterface<T>> nodeStack;
        BinaryNodeInterface<T> currentNode;
        PreorderIterator()
        {
        	nodeStack=new Stack<BinaryNodeInterface<T>>();
        	currentNode=root;
        }
		@Override
		public boolean hasNext() {
			// TODO Auto-generated method stub
			return (currentNode!=null)||(!nodeStack.empty());
		}

		@Override
		public T next() {
			// TODO Auto-generated method stub
			BinaryNodeInterface<T> nextNode=null;
			if(currentNode!=null)
			{
				nodeStack.push(currentNode);
			}
			if(!nodeStack.empty())
			{
				nextNode=nodeStack.pop();
				if(nextNode.hasRightChild())
				nodeStack.push(nextNode.getRightChild());
				currentNode=nextNode.getLeftChild();
			}
			return nextNode.getData();
		}

		@Override
		public void remove() {
			// TODO Auto-generated method stub
			throw new UnsupportedOperationException();
		}
		
	}
中序迭代器类实现:
private class InorderIterator implements Iterator<T>
	{
        private Stack<BinaryNodeInterface<T>> nodeStack;
        private BinaryNodeInterface<T> currentNode;
        public InorderIterator()
        {
        	nodeStack=new Stack<BinaryNodeInterface<T>>();
        	currentNode=root;
        }
		@Override
		public boolean hasNext() {
			// TODO Auto-generated method stub
			return (currentNode!=null||!nodeStack.empty());
		}

		@Override
		public T next() {
			// TODO Auto-generated method stub
			BinaryNodeInterface<T> nextNode=null;
			while(currentNode!=null)
			{
				nodeStack.push(currentNode);
				currentNode=currentNode.getLeftChild();
			}
			if(!nodeStack.isEmpty())
			{
				nextNode=nodeStack.pop();
				currentNode=nextNode.getRightChild();
			}
			return nextNode.getData();
		}

		@Override
		public void remove() {
			// TODO Auto-generated method stub
			throw new UnsupportedOperationException();
		}
		
	}
后序迭代器类实现:

private class PostorderIterator implements Iterator<T>
	{
		Stack<BinaryNodeInterface<T>> nodeStack;
	    BinaryNodeInterface<T> currentNode;
	    BinaryNodeInterface<T> preNode;
	    PostorderIterator()
	    {
	    	nodeStack=new Stack<BinaryNodeInterface<T>>();
	    	currentNode=root;
	    	preNode=null;
	    }
		@Override
		public boolean hasNext() {
			// TODO Auto-generated method stub
			return (currentNode!=null)||(!nodeStack.empty()) ;
		}

		@Override
		public T next() {
			// TODO Auto-generated method stub
			BinaryNodeInterface<T> nextNode=null;
			while(true)
			{
				if(currentNode!=null)
			  {
				nodeStack.push(currentNode);
				currentNode=currentNode.getLeftChild();
			  }else
				{
				    currentNode=nodeStack.peek();
					if(currentNode.hasRightChild()&&preNode!=currentNode.getRightChild())
					{
						currentNode=currentNode.getRightChild();
					}else
						break;
				}
			}
				currentNode=preNode=nodeStack.pop();
				nextNode=currentNode;
				currentNode=null;
			   return nextNode.getData();
		}

		@Override
		public void remove() {
			// TODO Auto-generated method stub
			
		}
		
	}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值