二叉树的创建、层次遍历、递归及非递归先中后序遍历

package w3ang.algorithms;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.Stack;

class BinaryTreeNode 
{
	BinaryTreeNode lchild;
	BinaryTreeNode rchild;
	boolean visit=false;
	String name;
	public BinaryTreeNode(String name)
	{
		this.name=name;
	}
}

public class CreateBinaryTree 
{
	/*
	 	****创建二叉树****
		二叉树节点数:11
		高度:3
		
		先序遍历:A B D E G H C F 
		非递归先序遍历:A B D E G H C F 
		中序遍历:D B G E H A F C 
		非递归中序遍历:D B G E H A F C 
		后序遍历:D G H E B F C A 
		非递归后序遍历:D G H E B F C A 
	 */
	public static void main(String[] args)
	{
		ArrayList<BinaryTreeNode> binaryTree=new ArrayList<>();
		System.out.println("****创建二叉树****");createBTree(binaryTree);
		//System.out.print("层次遍历:");levelOrder(binaryTree.get(0));
		System.out.print("\n先序遍历:");preOrder(binaryTree.get(0));
		//ArrayList<BinaryTreeNode>preTree=(ArrayList<BinaryTreeNode>) binaryTree.clone();
		//这里修改inTree,影响了binaryTree...
		//System.out.print("\n非递归先序遍历:");preOrderNoRecursive(preTree.get(0));
		System.out.print("\n非递归先序遍历:");preOrderNoRecursive(binaryTree.get(0));
		
		System.out.print("\n中序遍历:");inOrder(binaryTree.get(0));
		//ArrayList<BinaryTreeNode>inTree=(ArrayList<BinaryTreeNode>) binaryTree.clone();
		//这里修改inTree,影响了binaryTree...
		//System.out.print("\n非递归中序遍历:");inOrderNoRecursive(inTree.get(0));
		System.out.print("\n非递归中序遍历:");inOrderNoRecursive(binaryTree.get(0));
		
		System.out.print("\n后序遍历:");postOrder(binaryTree.get(0));
		initVist(binaryTree.get(0));
		System.out.print("\n非递归后序遍历:");postOrderNoRecursive(binaryTree.get(0));
		//ArrayList<BinaryTreeNode>postTree=(ArrayList<BinaryTreeNode>) binaryTree.clone();
		//System.out.print("\n非递归后序遍历:");postOrderNoRecursive(postTree.get(0));
	}
	
	private static void initVist(BinaryTreeNode bNode)
	{
		if(bNode==null || bNode.name.equals("#"))
			return;
		bNode.visit=false;
		initVist(bNode.lchild);
		initVist(bNode.rchild);
	}
	
	private static void createBTree(ArrayList<BinaryTreeNode>binaryTree)
	{
		//System.out.println((int)(Math.log(11)/Math.log(2)));
		@SuppressWarnings("resource")
		//Scanner scanner=new Scanner(System.in);//键盘输入
		Scanner scanner=new Scanner("A B C D E F # # # G H");//直接赋值
		int i=0;
		if(scanner.hasNext())
		{
			binaryTree.add(new BinaryTreeNode(scanner.next()));//二叉树节点也从0开始算
			i++;
		}
		while(scanner.hasNext())//A B C D E F # # # G H
		{
			binaryTree.add(new BinaryTreeNode(scanner.next()));
			//处理父子关系:
			if(i%2==0)//rchild
				binaryTree.get((i-1)/2).rchild=binaryTree.get(i);
			else//lchild
				binaryTree.get((i-1)/2).lchild=binaryTree.get(i);
			i++;//i计数加加;
		}
		System.out.println("二叉树节点数:"+binaryTree.size());
		System.out.println("高度:"+(int)(Math.log(binaryTree.size())/Math.log(2)));
	}
	
	private static void preOrder(BinaryTreeNode bNode)
	{
		if(bNode==null || bNode.name.equals("#"))
			return;
		System.out.print(bNode.name+" ");
		preOrder(bNode.lchild);
		preOrder(bNode.rchild);
	}
	
	private static void preOrderNoRecursive(BinaryTreeNode bNode)
	{
		LinkedList<BinaryTreeNode>btList=new LinkedList<>();
		btList.add(bNode);
		while(!btList.isEmpty())
		{
			BinaryTreeNode tempNode=btList.getFirst();
			System.out.print(tempNode.name+" ");
			btList.removeFirst();
			if(tempNode.rchild!=null && !tempNode.rchild.name.equals("#"))
				btList.addFirst(tempNode.rchild);
			if(tempNode.lchild!=null && !tempNode.lchild.name.equals("#"))
				btList.addFirst(tempNode.lchild);
		}
	}
	
	private static void levelOrder(BinaryTreeNode bNode)
	{
		LinkedList<BinaryTreeNode>btList=new LinkedList<>();
		btList.addLast(bNode);
		while(!btList.isEmpty())
		{
			BinaryTreeNode tmpNode=btList.getFirst();
			System.out.print(tmpNode.name+" ");
			btList.removeFirst();//移除遍历过的元素
			
			if(tmpNode.lchild!=null && !tmpNode.lchild.name.equals("#"))
				btList.addLast(tmpNode.lchild);
			if(tmpNode.rchild!=null && !tmpNode.rchild.name.equals("#"))
				btList.addLast(tmpNode.rchild);
		}
	}
	
	private static void inOrder(BinaryTreeNode bNode)
	{
		if(bNode==null||bNode.name.equals("#"))
			return;
		inOrder(bNode.lchild);
		System.out.print(bNode.name+" ");
		inOrder(bNode.rchild);
	}
	
	//中序的非递归不好写?
	private static void inOrderNoRecursive(BinaryTreeNode bNode)
	{
		LinkedList<BinaryTreeNode>btList=new LinkedList<>();
		btList.addFirst(bNode);
		bNode=bNode.lchild;
		while(!btList.isEmpty()||bNode!=null)//bNode!=null防止还有结点没有访问。。。
		{
			while(bNode!=null&& !bNode.visit && !bNode.name.equals("#"))
			{
				btList.addFirst(bNode);
				bNode=bNode.lchild;
			}
			
			BinaryTreeNode tmpNode=btList.getFirst();
			System.out.print(tmpNode.name+" ");//最左孩子
			tmpNode.visit=true;	btList.removeFirst();
			
			if(tmpNode.rchild!=null && !tmpNode.rchild.name.equals("#"))
				bNode=tmpNode.rchild;//最左孩子的右孩子
		}
	}
	
	private static void postOrder(BinaryTreeNode bNode)
	{
		if(bNode==null||bNode.name.equals("#"))
			return;
		postOrder(bNode.lchild);
		postOrder(bNode.rchild);
		System.out.print(bNode.name+" ");
	}
	
	//后序的非递归不好写?
	private static void postOrderNoRecursive(BinaryTreeNode bNode)
	{
		LinkedList<BinaryTreeNode>btList=new LinkedList<>();
		btList.addFirst(bNode);
		bNode=bNode.lchild;
		while(btList.size()>0)
		{
			while(bNode!=null&& !bNode.visit && !bNode.name.equals("#"))
			{
				while(bNode!=null && !bNode.visit && !bNode.name.equals("#"))
				{
					btList.addFirst(bNode);
					bNode=bNode.lchild;
				}
				BinaryTreeNode tmpNode=btList.getFirst();
				if(tmpNode.rchild!=null && !tmpNode.rchild.name.equals("#"))
					bNode=tmpNode.rchild;//最左孩子的右孩子
			}//找到后序遍历的第一个孩子
			
			BinaryTreeNode tmpNode=btList.getFirst();
			System.out.print(tmpNode.name+" ");//输出当前后序遍历的第一个孩子
			btList.removeFirst();tmpNode.visit=true;
			
			if(btList.size()>0 && btList.getFirst().rchild!=null && !btList.getFirst().rchild.name.equals("#"))
				bNode=btList.getFirst().rchild;
		}
	}
}
/*
	   A
	 /   \
	B    C
   /\   /
  D  E F
    /\
   G  H
中序:D B G E H A F C
	【首先:找到当前结点的最左孩子
	sysout...
	然后:右孩子
	其次:父节点】
	中间:中序和后序算法的方法体写成preOrder了,
	          导致错误,其实中序、后序二者和前序是一样的simple。。。
	

后序:D G H E B F C A 
ABCDEF###G H
0123456789 10
i:2i+1 2i+2 (lchild-1)/2=parent (rchild-1)/2=parent 

123456789
i:2i 2i+1 lchild/2=parent rchild/2=parent 
*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值