二叉查找树的实现
本文根据《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;
}
}
}