二叉树实现(java)
2016-03-09 14:31
525 查看
从二叉树的定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行节点本身的访问,左子树节点的访问和右子树节点的访问。下面的示例代码实现了二叉树的构建、二叉树的遍历(包含递归和非递归方式的实现)、二叉树的索引等。具体解释在代码中都有注释。代码如下:
结果如下:
前序遍历结果:
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
/** * 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
相关文章推荐
- Springboot ServletContextListener @Autowired null 解决办法
- Java源码阅读之TreeMap
- Java ConcurrentModificationException异常原因和解决方法
- springMVC中发送邮件
- JAVA利用jxl读取Excel内容
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- 常用java正则表达式
- java程序语言之灵魂
- 关于Spring定时任务(定时器)用法
- Java 征途:行者的地图
- Java ServletContext 详解
- Java容器Set的使用
- ps -ef |grep java
- cxf与spring整合
- 我的第一篇博客 - java 环境变量设置
- 浅析Java设计模式 - 单例模式
- C# 加密(Encrypt) 解密(Decrypt) 操作类 java与 C# 可以相互加密解密
- Java--编码集与序列化
- JavaFX设置面板不捕获鼠标事件(透明或不计算边界)
- eclipse部署web项目中各种错误总汇