二叉树

二叉查找树的实现
本文根据《Java程序员面试笔试》总结

二叉树的基本概念

二叉树
1)结点的度:某一结点所用的子树的个数成为该结点的度。
2)树的度:树种各结点的最大值叫树的度。
3)叶结点:度为0的结点(D、E、F、G)。
4)分支结点:度不为0的结点。一棵树除叶结点外,其余的都是分支结点。
5)路径、路径的长度:一棵树的一串结点n1,n2,…,nk有如下关系:结点ni是ni+1的父结点(1<=i<k),就把n1,n2,…,nk称为一条由n1至nk的路径。这条路径的长度是k-1。
6)树的深度:树中所有结点的最大层数是树的深度。
7)满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子结点都在同一层,这样的二叉树叫满二叉树。
8)完全二叉树:一棵有n个结点的二叉树,对树的结点按从上到下,从左到右的顺序进行编号,如果编号为i(1<=i<=n)的结点的位置与满二叉树中编号为i的结点的位置相同,那么这样的树被称为完全二叉树。

二叉树的基本性质

性质1:一棵非空二叉树的第i层上最多有2^(i-1)个结点。
性质2:一棵深度为k的二叉树中,最多具有2^k-1个结点,最少有k个结点。
性质3:对于一棵非空的二叉树,度为0的结点(叶结点)总比度为2的结点多1个。
证明:a为度为0的结点总数,b为度为1的结点总数,c为度为2的结点总数,n为整个树的结点总数,所以n=a+b+c,根据二叉树的性质,n=b+2c+1(所有结点的度数之和+1=结合总数),根据上式,a+b+c=b+2c+1,所以a=c+1。
性质4:具有n个结点的完全二叉树的深度为log2(n)+1。

二叉查找树的实现及遍历(用JAVA实现)

class Node{
	public int data;
	public Node left;
	public Node right;
	public Node(int data) {
		this.data=data;
		this.left=left;
		this.right=right;
	}
}
public class Binary_Tree {
	public Node root;
	public Binary_Tree() {
		root=null;
	}
	//将data插到排序二叉树中
	public void insert(int data) {
		Node newNode=new Node(data);
		if(root==null) {
			root=newNode;
		}
		else {
			Node current=root;
			Node parent;
			
			while(true) {
				parent=current;
				if(data<current.data) {
					current=current.left;
					if(current==null) {
						parent.left=newNode;
						return;
					}
				}else {
					current=current.right;
					if(current==null) {
						parent.right=newNode;
						return;
					}
				}
			}
			
		}
	}
	//将数值输入构建二叉树
	public void buildTree(int[] data) {
		for(int i=0;i<data.length;i++) {
			insert(data[i]);
		}
	}
//先序遍历(递归)
	public void preOrder(Node localRoot) {
		if(localRoot!=null) {
			System.out.print(localRoot.data+"");
			if(localRoot.left!=null) {
				preOrder(localRoot.left);
			}
			if(localRoot.right!=null) {
				preOrder(localRoot.right);
			}
		}
	}
	public void preOrder() {
		this.preOrder(this.root);
	}
	//先序遍历(非递归)
	public void preOrder_1(Node localRoot) {
		Stack<Node> s=new Stack<Node>();
		while(localRoot!=null||!s.empty()){//节点非空或栈非空就遍历
			while(localRoot!=null) {
				System.out.println(localRoot.data);//压入所有左孩子节点,压入前输出
				s.push(localRoot);
				localRoot=localRoot.left;
			}
			if(!s.empty()) {
				localRoot=s.pop();
				localRoot=localRoot.right;
			}
		}
		System.out.println();
	}
//中序遍历(递归)
	public void InOrder(Node localRoot) {
		if(localRoot!=null) {
			InOrder(localRoot.left);
			System.out.print(localRoot.data+"");
			InOrder(localRoot.right);
		}
	}
	public void InOrder() {
		this.InOrder(this.root);
	}
	//中序遍历(非递归)
	public void InOrder_1(Node localRoot) {
		Stack<Node> s=new Stack<Node>();
		while(localRoot!=null||!s.empty()) {
			while(localRoot!=null) {
				s.push(localRoot);
				localRoot=localRoot.left;
			}
			while(!s.empty()) {
				localRoot=s.pop();
				System.out.println(localRoot.data);
				localRoot=localRoot.right;
			}
		}
	}
//后序遍历(递归)
	public void postOrder(Node localRoot) {
		if(localRoot!=null) {
			postOrder(localRoot.left);
			postOrder(localRoot.right);
			System.out.print(localRoot.data+"");
		}
	}
	public void postOrder() {
		this.postOrder(this.root);
	}
	//后序遍历(非递归)
	public void postOrder_1(Node localRoot) {
		Stack<Node> s=new Stack<Node>();
		Stack<Integer> s1=new Stack<Integer>();
		Integer i=new Integer(1);
		while(localRoot!=null||!s.empty()) {
			//将左子树压栈
			while(localRoot!=null) {
				s.push(localRoot);
				s1.push(0);
				localRoot=localRoot.left;
			}
			//检查s不为空并且s1顶端为1就输出
			while(!s.empty()&&s1.peek().equals(i)) {
				s.pop();
				System.out.println(s);
			}
			//查看右子树
			while(!s.empty()) {
				s1.pop();
				s1.push(1);
				localRoot=s.peek();
				localRoot=localRoot.right;
			}
		}
	}