Java实现二叉树及相关遍历方式

Java实现二叉树及相关遍历方式

在计算机科学中。二叉树是每一个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

下面用Java实现对二叉树的先序遍历,中序遍历,后序遍历。广度优先遍历。深度优先遍历。转摘请注明:http://blog.csdn.net/qiuzhping/article/details/44830369

package com.qiuzhping.tree;

import java.util.ArrayDeque;
import java.util.LinkedList;
import java.util.List;

/**
 * 功能:把一个数组的值存入二叉树中,然后进行3种方式的遍历.
 * 构造的二叉树:
 *               1
 *             /    *            2     3
 *           / \   /  *          4   5  6  7
 *         /  *        8   9
 *  先序遍历:DLR
 *  1 2 4 8 9 5 3 6 7
 *  中序遍历:LDR
 *  8 4 2 9 5 1 6 3 7
 *  后序遍历:LRD
 *  8 9 4 5 2 6 7 3 1
 *  深度优先遍历
 *  1 2 4 8 9 5 3 6 7
 *  广度优先遍历
 *  1 2 3 4 5 6 7 8 9
 * @author  Peter.Qiu
 * @version  [Version NO, 2015年4月2日]
 * @see  [Related classes/methods]
 * @since  [product/module version]
 */
public class binaryTreeTest {

	private int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	private static List<Node> nodeList = null;

	/**
	 * 内部类:节点
	 *
	 */
	private static class Node {
		Node leftChild;
		Node rightChild;
		int data;

		Node(int newData) {
			leftChild = null;
			rightChild = null;
			data = newData;
		}
	}

	/** 二叉树的每个结点至多仅仅有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。

<BR>
	 * 二叉树的第i层至多有2^{i-1}个结点。深度为k的二叉树至多有2^k-1个结点;<BR>
	 * 对不论什么一棵二叉树T,假设其终端结点数为n_0,度为2的结点数为n_2。则n_0=n_2+1。<BR>
	 *一棵深度为k,且有2^k-1个节点称之为满二叉树;深度为k,有n个节点的二叉树,<BR>
     *当且仅当其每个节点都与深度为k的满二叉树中,序号为1至n的节点相应时。称之为全然二叉树.<BR>
	 * @author  Peter.Qiu [Parameters description]
	 * @return void [Return type description]
	 * @exception throws [Exception] [Exception description]
	 * @see [Related classes#Related methods#Related properties]
	 */
	public void createTree() {
		nodeList = new LinkedList<Node>();
		// 将一个数组的值依次转换为Node节点
		for (int nodeIndex = 0; nodeIndex < array.length; nodeIndex++) {
			nodeList.add(new Node(array[nodeIndex]));
		}
		// 对前lastParentIndex-1个父节点依照父节点与孩子节点的数字关系建立二叉树
		for (int parentIndex = 0; parentIndex < array.length / 2 - 1; parentIndex++) {
			// 左孩子
			nodeList.get(parentIndex).leftChild = nodeList
					.get(parentIndex * 2 + 1);
			// 右孩子
			nodeList.get(parentIndex).rightChild = nodeList
					.get(parentIndex * 2 + 2);
		}
		// 最后一个父节点:由于最后一个父节点可能没有右孩子,所以单独拿出来处理
		int lastParentIndex = array.length / 2 - 1;
		// 左孩子
		nodeList.get(lastParentIndex).leftChild = nodeList
				.get(lastParentIndex * 2 + 1);
		// 右孩子,假设数组的长度为奇数才建立右孩子
		if (array.length % 2 == 1) {
			nodeList.get(lastParentIndex).rightChild = nodeList
					.get(lastParentIndex * 2 + 2);
		}
	}

	/**
	 * 先序遍历
	 *
	 * 这三种不同的遍历结构都是一样的,仅仅是先后顺序不一样而已
	 *
	 * @param node
	 *            遍历的节点
	 */
	public  void preOrderTraverse(Node node) {
		if (node == null)
			return;
		System.out.print(node.data + " ");
		preOrderTraverse(node.leftChild);
		preOrderTraverse(node.rightChild);
	}

	/**
	 * 中序遍历
	 *
	 * 这三种不同的遍历结构都是一样的,仅仅是先后顺序不一样而已
	 *
	 * @param node
	 *            遍历的节点
	 */
	public  void inOrderTraverse(Node node) {
		if (node == null)
			return;
		inOrderTraverse(node.leftChild);
		System.out.print(node.data + " ");
		inOrderTraverse(node.rightChild);
	}

	/**
	 * 后序遍历
	 *
	 * 这三种不同的遍历结构都是一样的。仅仅是先后顺序不一样而已
	 *
	 * @param node
	 *            遍历的节点
	 */
	public  void postOrderTraverse(Node node) {
		if (node == null)
			return;
		postOrderTraverse(node.leftChild);
		postOrderTraverse(node.rightChild);
		System.out.print(node.data + " ");
	}

	/**
     * 深度优先遍历,相当于先根遍历
     * 採用非递归实现
     * 须要辅助数据结构:栈
     */
    public void depthOrderTraversal(Node root){
    	System.out.println("\n深度优先遍历");
        if(root==null){
            System.out.println("empty tree");
            return;
        }
        ArrayDeque<Node> stack=new ArrayDeque<Node>();
        stack.push(root);
        while(stack.isEmpty()==false){
        	Node node=stack.pop();
            System.out.print(node.data+ " ");
            if(node.rightChild!=null){
                stack.push(node.rightChild);
            }
            if(node.leftChild!=null){
                stack.push(node.leftChild);
            }
        }
        System.out.print("\n");
    }

    /**
     * 广度优先遍历
     * 採用非递归实现
     * 须要辅助数据结构:队列
     */
    public void levelOrderTraversal(Node root){
    	System.out.println("广度优先遍历");
        if(root==null){
            System.out.println("empty tree");
            return;
        }
        ArrayDeque<Node> queue=new ArrayDeque<Node>();
        queue.add(root);
        while(queue.isEmpty()==false){
        	Node node=queue.remove();
            System.out.print(node.data+ " ");
            if(node.leftChild!=null){
                queue.add(node.leftChild);
            }
            if(node.rightChild!=null){
                queue.add(node.rightChild);
            }
        }
        System.out.print("\n");
    }
	/**
	 *构造的二叉树:
	 *               1
	 *             /   	 *            2     3
	 *           / \   / 	 *          4   5  6  7
	 *         / 	 *        8   9
	 *  先序遍历:DLR
	 *	1 2 4 8 9 5 3 6 7
	 *  中序遍历:LDR
	 *  8 4 2 9 5 1 6 3 7
	 *  后序遍历:LRD
	 *  8 9 4 5 2 6 7 3 1
	 *  深度优先遍历
	 *	1 2 4 8 9 5 3 6 7
	 *	广度优先遍历
	 *	1 2 3 4 5 6 7 8 9
	 */
	public static void main(String[] args) {
		binaryTreeTest binTree = new binaryTreeTest();
		binTree.createTree();
		// nodeList中第0个索引处的值即为根节点
		Node root = nodeList.get(0);

		System.out.println("先序遍历:");
		binTree.preOrderTraverse(root);
		System.out.println();

		System.out.println("中序遍历:");//LDR
		binTree.inOrderTraverse(root);
		System.out.println();

		System.out.println("后序遍历:");//LRD
		binTree.postOrderTraverse(root);

		binTree.depthOrderTraversal(root);//深度遍历
		binTree.levelOrderTraversal(root);//广度遍历
	}

}
时间: 2024-09-30 04:27:30

Java实现二叉树及相关遍历方式的相关文章

【数据算法】Java实现二叉树存储以及遍历

二叉树在java中我们使用数组的形式保存原数据,这个数组作为二叉树的数据来源,后续对数组中的数据进行节点化操作. 步骤就是原数据:数组 节点化数据:定义 Node节点对象 存储节点对象:通过LinkedList保存Node节点对象 在操作过程中我们需要将当前结点和前一节点.后一节点进行关系绑定 package tree; import java.util.LinkedList; import java.util.List; /** * 功能:把一个数组的值存入二叉树中,然后进行3种方式的遍历 *

java实现二叉树的相关操作

import java.util.ArrayDeque; import java.util.Queue; public class CreateTree { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Node root=new Node(); root.data=9; Node temp01=new Node(); temp01.data=1;

java list 的 四种遍历方式

在java中遍历一个list对象的方法主要有以下四种: 1. For Loop —— 普通for循环 2. Advanced For Loop —— 高级for循环 3. Iterator Loop —— 迭代器遍历 4. While Loop —— while循环 具体可以参考以下代码: import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Main { public

java创建二叉树并递归遍历二叉树

二叉树类代码: package binarytree; import linkqueue.LinkQueue; public class BinaryTree { class Node { public Object data; public Node lchild; public Node rchild; public Node(Object data) { this.data = data; this.lchild = null; this.rchild = null; } } //根节点

Java(8)中List的遍历方式

============Java8之前的方式==========Map<String, Integer> items = new HashMap<>();items.put("A", 10);items.put("B", 20);items.put("C", 30);items.put("D", 40);items.put("E", 50);items.put("F&quo

二叉树的六种遍历方式

一.递归实现前序.中序以及后序遍历 1 void printTree(node *T) 2 { 3 if(T) 4 { 5 printTree(T->left); 6 cout<<T->val;//调整输出节点T的顺序,可分别实现前序,后序 7 printTree(T->right); 8 } 9 } 二.循环实现前序.中序以及后序遍历 思路参见文章: http://blog.csdn.net/ns_code/article/details/12977901 (1)前序 1

java map的两种遍历方式

1.1.  通过key得到value //得到所有的key值 Set<String> keySet = map.keySet(); //根据key值得到value值 for (String key : keySet) { System.out.println(key+":"+map.get(key)); } 1.2.  通过entry得到key和value //得到所有的entry Set<Entry<String, String>> entrySe

Java中Map集合的遍历方式

方法一:在for-each循环中使用entries来遍历 1 Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 2 3 for (Map.Entry<Integer, Integer> entry : map.entrySet()) { 4 5 System.out.println("Key = " + entry.getKey() + ", Value = "

java集合四种遍历方式

package conection; import java.util.Iterator;import java.util.LinkedList;import java.util.List; public class Ergodic { public static void main(String[] args) {     // TODO Auto-generated method stub    /*    * java集合类的四种遍历方式    *     */    List<Integ