有了昨天对于链表的积累,今天看起二叉树感觉就比较轻松了。先贴一下代码,暂时实现了查找、新增和遍历功能。其实呢,这些数据结构在Java中,都已经被封装的很好了,之后再来说这一块。在这次之了解数据结构的实现之后,确实让我的理解更深一层。
package datastructure;
import java.util.Stack;
class Node{
int value;
Node leftchild;
Node rightchild;
public Node(int value) {
this.value = value;
}
public void dispaly(){
System.out.print("{value:" + this.value + "}");
}
}
public class BinaryTree {
private Node root;
public Node getRoot(){
return root;
}
public void insert(int value){
Node node = new Node(value);
if(root == null){
root = node;
}else{
Node current = root;
Node parent = root;
while(true){
parent = current;
if(value < current.value){
current = current.leftchild;
if(current == null){
parent.leftchild = node;
return;
}
}else{
current = current.rightchild;
if(current == null){
parent.rightchild = node;
return;
}
}
}
}
}
public Node find(int key){
Node current = root;
while(key != current.value){
if(key < current.value){
current = current.leftchild;
}else{
current = current.rightchild;
}
if(current == null){
System.out.println("Not Found");
return null;
}
}
return current;
}
/**
* 中序遍历
* @param current
*/
public void displayInOrder(Node current){
if(current != null){
displayInOrder(current.leftchild);
current.dispaly();
displayInOrder(current.rightchild);
}
}
/**
* 中序遍历 非递归实现
* @param current
*/
public void displayInOrderWithNoRecursion(Node current){
if(current == null){
System.out.println("Null Tree");
return;
}
Stack stack = new Stack();
while(current != null || !stack.isEmpty()){
while(current != null){
stack.push(current);
current = current.leftchild;
}
current = stack.pop();
current.dispaly();
current = current.rightchild;
}
}
/**
* 前序遍历
* @param current
*/
public void displayPreOrder(Node current){
if(current != null){
current.dispaly();
displayPreOrder(current.leftchild);
displayPreOrder(current.rightchild);
}
}
/**
* 后序遍历
*/
public void displayPostOrder(Node current){
if(current != null){
displayPostOrder(current.leftchild);
displayPostOrder(current.rightchild);
current.dispaly();
}
}
}
下面是测试段代码:
package datastructure;
public class TreeApp {
public static void main(String args[]){
BinaryTree btree = new BinaryTree();
btree.insert(4);
btree.insert(2);
btree.insert(1);
btree.insert(3);
btree.insert(6);
btree.insert(5);
btree.displayInOrder(btree.getRoot());
System.out.println();
btree.displayInOrderWithNoRecursion(btree.getRoot());
}
}
在这里想记一下 在遍历时的递归实现和非递归实现。之前一直对递归比较不感冒,第一是因为觉得不好理解,加上一些教材说的递归的内存开销大。但是看起书来,就是用的递归实现,也就逼着自己去了解递归。发现,递归调用过程,就像是将函数压入一个栈中,在到达某个条件之后,在从栈中取出执行。
/**
* 中序遍历
* @param current
*/
public void displayInOrder(Node current){
if(current != null){
displayInOrder(current.leftchild);
current.dispaly();
displayInOrder(current.rightchild);
}
}
在这个递归中,终止递归调用的条件是current == null,即当前节点没有左子树时。那在这之前呢,首先传入进来的是根节点,第一次就相当于把displayInOrder(Root)给压入到栈底,接着压入Root.leftchild,接着在压入其左子树,直到没有左子树之后,开始从栈中取出顶端的函数,并执行,current.display()相当于访问该节点,访问完之后,在访问其右子树,如果右子树不为空,则将右子树压入到栈中,直到全部压入栈中之后,在从顶端取出,访问节点。
按照这样的思路,我就借助stack栈类,实现了中序遍历的非递归实现方法:
/**
* 中序遍历 非递归实现
* @param current
*/
public void displayInOrderWithNoRecursion(Node current){
if(current == null){
System.out.println("Null Tree");
return;
}
Stack stack = new Stack();
while(current != null || !stack.isEmpty()){
while(current != null){
stack.push(current);
current = current.leftchild;
}
current = stack.pop();
current.dispaly();
current = current.rightchild;
}
}