二叉树 排序 遍历 算法

二叉树节点
package BiTree;

public class Node {

	public int data;
	public Node left;
	public Node right;
	public Node(int data){
		this.data = data;
		this.right = null;
		this.left = null;
	}
	
}
构造二叉排序树
package BiTree;

public class CreateBinaryTree {
	// 二叉排序树根节点
	private static Node root;

	CreateBinaryTree() {
		this.root = null;
	}

	// 构造二叉排序树
	public static void insert(int data) {

		Node newNode = new Node(data);
		if (root == null) {
			root = newNode;
		} else {
				Node parent = null;
				Node current = root;
				while (true) {
					parent = current;
					if (data < current.data) {
						current = current.left;
						if (current == null) {
							parent.left = newNode;
							return;
						}
					}else if(data > current.data){
						current = current.right;
						if (current == null) {
							parent.right = newNode;
							return;
						}
					}else{//若存在重复元素,则将该重复元素剔除
						System.out.println("重复元素:"+data);
						return;
					}

				}
			}
	}

	public static Node createBiTree(int[] data) {

		for(int i=0;i<data.length;i++){
			insert(data[i]);
		}
		
		return root;
	}

}

//递归遍历二叉树

package BiTree;

public class RecursionOrder {

	// 递归前序遍历
	public void PreOrder(Node root) {
		if (root != null) {
			System.out.print(root.data+"  ");
			PreOrder(root.left);
			PreOrder(root.right);
		}

	}
	// 递归中序遍历
	public void InOrder(Node root) {
		if (root != null) {		
			InOrder(root.left);
			System.out.print(root.data+"  ");
			InOrder(root.right);
		}
	}
	//递归后续遍历
	public void PostOrder(Node root){
		if(root!=null){
			PostOrder(root.left);
			PostOrder(root.right);
			System.out.print(root.data+"  ");
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] data = { 2, 8, 7, 4, 9, 3, 1, 6, 7, 5 };
		RecursionOrder ro = new RecursionOrder();
		//构造二叉排序树
		Node root = CreateBinaryTree.createBiTree(data);
		ro.PreOrder(root); //递归前序
		System.out.println("");
		ro.InOrder(root);//递归中续
		System.out.println("");
		ro.PostOrder(root);//递归后续
	}

}
非递归遍历二叉树,其中前序和中序相对简单,后续复杂,算法思路已在程序中解释

package BiTree;

import java.util.LinkedList;

public class Order {

	//非递归前序遍历,借助LinkedList作为栈
	public void PreOrder(Node root){
		Node p = root;
		LinkedList<Node> llist = new LinkedList<Node>();
		while(p!=null||!llist.isEmpty()){
			if(p!=null){
				System.out.print(p.data+ " ");
				llist.push(p);
				p=p.left;
			}else{
				p=llist.pop();
				p=p.right;
			}
		}
	}
	
	//非递归中序遍历,借助LinkedList作为栈
	public void InOrder(Node root) {
		Node p = root;
		LinkedList<Node> llist = new LinkedList<Node>();
		while(p!=null||!llist.isEmpty()){
			if(p!=null){
				llist.push(p);
				p=p.left;
			}else{
				p=llist.pop();
				System.out.print(p.data + " ");
				p=p.right;
			}
		}
	}
	
	//非递归后续遍历,借助LinkedList作为栈
	/**
	 * 要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,
	 * 先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;
	 * 或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,
	 * 则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,
	 * 这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,
	 * 左孩子和右孩子都在根结点前面被访问。
	 * @param root
	 */
	public void PostOrder(Node root) {
		Node p = root;
		Node pre = null;
		LinkedList<Node> llist = new LinkedList<Node>();
		llist.push(p);
		while(!llist.isEmpty()){
			p = llist.peekFirst();
			if((p.right==null&&p.left==null)||
					(pre!=null&&(pre==p.right||pre==p.left))){
				p = llist.pop();
				System.out.print(p.data+"  ");
				pre = p;
			}else{
				if(p.right!=null){
					llist.push(p.right);
				}
				if(p.left!=null){
					llist.push(p.left);
				}
			}
		}
	}
	
	//层次遍历,借助LinkedList作为队列实现
	public void LevelOrder(Node root){
		Node p = root;
		LinkedList<Node> llist = new LinkedList<Node>();
		llist.offerLast(p);
		while(!llist.isEmpty()){
			p = llist.pollFirst();
			System.out.print(p.data + " ");
			if(p.left!=null){
				llist.offerLast(p.left);
			}
			if(p.right!=null){
				llist.offerLast(p.right);
			}
		}
	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int[] data = { 2, 8, 7, 4, 9, 3, 1, 6, 7, 5 };
		Order ro = new Order();
		//构造二叉排序树
		Node root = CreateBinaryTree.createBiTree(data);
		ro.PostOrder(root);
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值