您的位置:首页 > 编程语言 > Java开发

二叉树实现(java)

2016-03-09 14:31 525 查看
从二叉树的定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行节点本身的访问,左子树节点的访问和右子树节点的访问。下面的示例代码实现了二叉树的构建、二叉树的遍历(包含递归和非递归方式的实现)、二叉树的索引等。具体解释在代码中都有注释。代码如下:

/**
* BinaryTree.java
* Copyright (C) @2016 GuangDong Eshore Techonlogy Co. Ltd
* @version: 1.0
*/
package com.learn.test;

import java.util.Stack;

/**
* @desc:二叉树(递归与非递归方式实现)
*/
public class BinaryTree {

private static Node rootNode;  //根节点

/**
* 构建树
* @desc:
* @param node
*/
public void addNode(Node node){
if(rootNode == null){
rootNode = new Node();
rootNode.setValue(node.getValue());
}else{
int rootValue = rootNode.getValue();
if(node.getValue() < rootValue){
addChildNode(rootNode, node, 1);
}else{
addChildNode(rootNode, node, 2);
}
}
}

public void addChildNode(Node rootNode, Node node, int flag){ //flag: 1:左边节点;2:右边节点
Node nextNode = null;
if(flag == 1){
nextNode = rootNode.getLeftNode();
}else{
nextNode = rootNode.getRightNode();
}
if(nextNode == null){
if(flag == 1){
rootNode.setLeftNode(node);
}else{
rootNode.setRightNode(node);
}
}else{
if(node.getValue() < nextNode.getValue()){
addChildNode(nextNode, node, 1);
}else{
addChildNode(nextNode, node, 2);
}
}
}

/**
* 前序遍历(递归)
* @desc:遍历顺序:根节点----左子树----右子树
* @param rootNode
*/
public void preOrder(Node rootNode){
if(rootNode != null){
System.out.print(rootNode.getValue() + ",");
preOrder(rootNode.getLeftNode());
preOrder(rootNode.getRightNode());
}
}

/**
* 前序遍历(非递归实现1)
* @desc:遍历顺序:根节点----左子树----右子树
* @param node
*/
public void preOrderWithNonRecursive1(Node node){
Stack<node> stack = new Stack<node>();
while(node != null || stack.size() > 0){
while(node != null){
System.out.print(node.getValue() + ",");
stack.push(node);
node = node.getLeftNode();
}
if(stack.size() > 0){
node = stack.pop();
node = node.getRightNode();
}
}
}

/**
* 前序遍历(非递归实现2)
* @desc:遍历顺序:根节点----左子树----右子树
* @param node
*/
public void preOrderWithNonRecursive2(Node node){
Stack<node> stack = new Stack<node>();
while(node != null || stack.size() > 0){
//遍历左子树
while(node != null){
System.out.print(node.getValue() + ",");
stack.push(node);
node = node.getLeftNode();
}
//遍历右子树
Node rightNode = null;
while(stack.size() > 0){
node = stack.pop();
rightNode = node.getRightNode();
if(rightNode != null){
System.out.print(rightNode.getValue() + ",");
if(rightNode.getRightNode() != null){
stack.push(rightNode);
}
node = rightNode.getLeftNode();
break;
}
}
}
}

/**
* 中序遍历(递归)
* @desc:遍历顺序:左子树----根节点----右子树
* @param node
*/
public void midOrder(Node node){
if(node != null){
midOrder(node.getLeftNode());
System.out.print(node.getValue() + ",");
midOrder(node.getRightNode());
}
}

/**
* 中序遍历(非递归实现)
* @desc:左子树----根节点----右子树
* @param node
*/
public void midOrderWithNonRecursive(Node node){
Stack<node> stack = new Stack<node>();
while(node != null || stack.size() > 0){
while(node != null){
stack.push(node);
node = node.getLeftNode();
}
if(stack.size() > 0){
node = stack.pop();
System.out.print(node.getValue() + ",");
node = node.getRightNode();
}
}
}

/**
* 后序遍历(递归)
* @desc:左子树----右子树----根节点
* @param node
*/
public void lastOrder(Node node){
if(node != null){
lastOrder(node.getLeftNode());
lastOrder(node.getRightNode());
System.out.print(node.getValue() + ",");
}
}

/**
* 后序遍历(非递归实现)
* @desc:左子树----右子树----根节点
* @param node
*/
public void lastOrderWithNonRecursive1(Node node){
Stack<node> stack = new Stack<node>();
Stack<node> tempStack = new Stack<node>();  //存放已经遍历过且含有右子树的节点
Node tempNode = null;
while(node != null || stack.size() > 0){
//遍历左子树
while(node != null){
stack.push(node);
node = node.getLeftNode();
}
if(stack.size() > 0){
node = stack.peek();   //获取一个节点
if(tempStack.size() > 0){
tempNode = tempStack.peek();
if(node == tempNode){       //说明此节点右子树已经遍历,下面处理时直接输出结果,不再遍历其右节点
tempStack.pop();
}
}
if(node.getRightNode() == null || node == tempNode){ //若无右子树或此节点已经遍历过,则输出根节点结果,否则继续遍历右子树
System.out.print(node.getValue() + ",");
stack.pop();
node = null;
}else{   //若有右子树,然后继续遍历右子树
tempStack.push(node);  //将此节点放入栈中,目的是当再次遍历到此节点时(说明此节点右子树已经遍历),直接输出结果,不再遍历其右节点
node = node.getRightNode();
}
}
}
}

/**
* 后序遍历(非递归实现)
* @desc:左子树----右子树----根节点
* @param node
*/
public void lastOrderWithNonRecursive2(Node node){
Node tempNode = null;  //存储最新输出过结果的节点,当一个节点的右节点等于tempNode,说明此节点已经遍历过(但未输出结果),直接输出结果
Stack<node> stack = new Stack<node>();
while(node != null || stack.size() > 0){
//遍历左子树
while(node != null){
stack.push(node);
node = node.getLeftNode();
}
if(stack.size() > 0){
node = stack.peek().getRightNode(); //获取栈顶节点的右节点,若无右子树或此节点已经遍历过(但未输出结果),则输出结果;否则,若有右子树,则继续遍历右子树
if(node == null || tempNode == node){ //若无右子树或此节点已经遍历过(但未输出结果),则输出根节点结果;否则继续遍历右子树
node = stack.pop();
System.out.print(node.getValue() + ",");
tempNode = node;  //将当前节点保存起来
node = null;
}
}
}
}

/**
* 在二叉树中查找节点是否存在
* @desc:
* @param value
* @return
*/
public boolean searchInBinaryTree(int value){
boolean flag = false;
while(rootNode != null){
if(value == rootNode.getValue()){
flag = true;
break;
}else if(value < rootNode.getValue()){  //遍历左子树
rootNode = rootNode.getLeftNode();
}else{  //遍历右子树
rootNode = rootNode.getRightNode();
}
}
return flag;
}

/**
* 初始化一棵树
*/
public void buildBinaryTree(){
Node node1 = new Node(10);
Node node2 = new Node(7);
Node node3 = new Node(16);
Node node4 = new Node(8);
Node node5 = new Node(5);
Node node6 = new Node(3);
Node node7 = new Node(1);
Node node8 = new Node(6);
Node node9 = new Node(19);
Node node10 = new Node(12);
Node node11 = new Node(9);
this.addNode(node1);
this.addNode(node2);
this.addNode(node3);
this.addNode(node4);
this.addNode(node5);
this.addNode(node6);
this.addNode(node7);
this.addNode(node8);
this.addNode(node9);
this.addNode(node10);
this.addNode(node11);
}

/**
* 树结构定义
* @desc:
*/
class Node{
private int value;
private Node leftNode;
private Node rightNode;

public Node(){};

public Node(int value){
this.value = value;
}

public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getLeftNode() {
return leftNode;
}
public void setLeftNode(Node leftNode) {
this.leftNode = leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
}

/**
* @desc:
* @param args
*/
public static void main(String[] args) {
BinaryTree test = new BinaryTree();
//*************构建树**********************
test.buildBinaryTree();
//*************前序遍历(递归算法)*************
System.out.println("前序遍历结果:");
test.preOrder(rootNode);
System.out.println();
//*************前序遍历(非递归算法)*************
test.preOrderWithNonRecursive1(rootNode);
System.out.println();
test.preOrderWithNonRecursive2(rootNode);
System.out.println();

//*************中序遍历(递归算法)*************
System.out.println();
System.out.println("中序遍历结果:");
test.midOrder(rootNode);
System.out.println();
//*************中序遍历(非递归算法)*************
test.midOrderWithNonRecursive(rootNode);
System.out.println();

//*************后序遍历(递归算法)*************
System.out.println();
System.out.println("后序遍历结果:");
test.lastOrder(rootNode);
System.out.println();
//*************后序遍历(非递归算法)*************
test.lastOrderWithNonRecursive1(rootNode);
System.out.println();
test.lastOrderWithNonRecursive2(rootNode);
System.out.println();

//*************在二叉树中查找节点是否存在**********
System.out.println();
System.out.println("在二叉树中查找节点是否存在:");
System.out.println("查找节点【7】是否存在:" + test.searchInBinaryTree(7));
System.out.println("查找节点【9】是否存在:" + test.searchInBinaryTree(9));
System.out.println("查找节点【27】是否存在:" + test.searchInBinaryTree(27));
}
}


结果如下:

前序遍历结果:

10,7,5,3,1,6,8,9,16,12,19,

10,7,5,3,1,6,8,9,16,12,19,

10,7,5,3,1,6,8,9,16,12,19,

中序遍历结果:

1,3,5,6,7,8,9,10,12,16,19,

1,3,5,6,7,8,9,10,12,16,19,

后序遍历结果:

1,3,6,5,9,8,7,12,19,16,10,

1,3,6,5,9,8,7,12,19,16,10,

1,3,6,5,9,8,7,12,19,16,10,

在二叉树中查找节点是否存在:

查找节点【7】是否存在:true

查找节点【9】是否存在:true

查找节点【27】是否存在:false
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: