`
128kj
  • 浏览: 584835 次
  • 来自: ...
社区版块
存档分类
最新评论

二叉树的顺序存储实现(java)

阅读更多
  顺序存储对完全二叉树而,简单又节省空间。对于一般二叉树,为了能用结点在数组中的相对位置表示结点之间的逻辑关系,也必须按完全二叉树的形式来存储树中的结点,这必然造成空间的浪费,随着二叉树高度的增大,空结点的数量也会急速增多。
 
/**
 * 顺序二叉树
 * 
 * @author liuyan
 */
public class ArrayBinaryTree<T> {

	// 节点数组
	private Object[] datas;

	// 指定的树的深度
	private int treeDeep;

	// datas数组的实际大小
	private int arraySize;

	/**
	 * 默认构造函数
	 */
	public ArrayBinaryTree() {
		// 设置默认的树深度
		treeDeep = 4;
		arraySize = (int) Math.pow(2, 4) - 1;
		datas = new Object[arraySize];
	}

	/**
	 * 指定深度构建二叉树 
	 * @param deep
	 */
	public ArrayBinaryTree(int deep) {
		// 按指定深度
		treeDeep = deep;
		arraySize = (int) Math.pow(2, treeDeep) - 1;
		datas = new Object[arraySize];
	}

	/**
	 * 指定深度和指定根节点构建二叉树 
	 * @param deep
	 * @param data
	 */
	public ArrayBinaryTree(int deep, T data) {
		// 按指定深度
		treeDeep = deep;
		arraySize = (int) Math.pow(2, treeDeep) - 1;
		datas = new Object[arraySize];
		datas[0] = data;
	}

	/**
	 * 为下标是index的节点增加子节点 
	 * @param index
	 * @param data
	 * @param isLeft
	 * @return
	 */
       public boolean addNode(int index, T data, boolean isLeft) {
	if (index * 2 + 2 > arraySize-1 || datas[index] == null) {
			throw new RuntimeException("下标无效");
		}
		if (isLeft) {
			datas[index * 2 + 1] = data;
		} else {
			datas[index * 2 + 2] = data;
		}
		return true;
	}

	/**
	 * 判断二叉树是否为空
	 * 
	 * @return
	 */
	public boolean isEmpty() {
              for(int i=0;i<datas.length;i++)
                  if(datas[i]!=null) return false;
		return true;
	}

	/**
	 * 返回根节点
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public T getRoot() {
		return (T) datas[0];
	}

	/**
	 * 返回指定节点的父节点 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public T getParent(int index) {
		if (index > arraySize-1 || datas[index] == null) {
			throw new RuntimeException("下标无效");
		}
		if (datas[(index - 1) / 2] == null) {
			throw new RuntimeException("无父节点");
		}
		return (T) datas[(index - 1) / 2];
	}

	/**
	 * 返回左子节点 
	 * @return
	 */
	@SuppressWarnings("unchecked")
       public T getLeftNode(int index) {
	if (index * 2 + 1 > (arraySize-1) || datas[index] == null) {
			throw new RuntimeException("下标无效");
		}
		return (T) datas[index * 2 + 1];
	}

	/**
	 * 返回右子节点 
	 * @return
	 */
	@SuppressWarnings("unchecked")
       public T getRightNode(int index) {
	if (index * 2 + 2 > (arraySize-1) || datas[index] == null) {
			throw new RuntimeException("下标无效");
		}
		return (T) datas[index * 2 + 2];
	}

	/**
	 * 返回树的深度 
	 * @return
	 */
	public int getTreeDeep() {
		return treeDeep;
	}

	/**
	 * 返回指定节点的索引位置 
	 * @param data
	 * @return
	 */
	public int getNodeIndex(T data) {

		for (int i = 0; i < arraySize; i++) {
			if (data == datas[i]) {
				return i;
			}
		}
		return -1;
	}

	@Override
	public String toString() {
		StringBuffer str = new StringBuffer("[");
		for (int i = 0; i < datas.length; i++) {
			str.append("[" + datas[i] + "],");
		}

	   if (datas.length > 0) {
	     return str.substring(0, str.lastIndexOf(",")) + "]";
	   }
		return str.append("]").toString();
	}

   //测试代码如下
      public static void main(String[] args) {
          ArrayBinaryTree<String> arrayBinaryTree1 =
               new ArrayBinaryTree<String>(4);
          System.out.println(arrayBinaryTree1.isEmpty());
	 ArrayBinaryTree<String> arrayBinaryTree = 
               new ArrayBinaryTree<String>(4,"汉献帝");
	 System.out.println(arrayBinaryTree);
	 arrayBinaryTree.addNode(0, "刘备", true);
	 arrayBinaryTree.addNode(0, "曹操", false);
	 arrayBinaryTree.addNode(1, "关羽", true);
	 arrayBinaryTree.addNode(1, "张飞", false);
	 arrayBinaryTree.addNode(2, "张辽", true);
	 arrayBinaryTree.addNode(2, "许褚", false);
          System.out.println("现在二叉树是:");
	 System.out.println(arrayBinaryTree);

          System.out.println();
          System.out.print("刘备的左手是: ");
	 System.out.println(arrayBinaryTree.getLeftNode(1));
          System.out.print("汉献帝的右手是:");
	 System.out.println(arrayBinaryTree.getRightNode(0));
          System.out.println();
          System.out.print("张飞的上司是:");
		
	 System.out.println(arrayBinaryTree.getParent(4));
          System.out.println(arrayBinaryTree.isEmpty());
	}
   }


运行:
true
[[汉献帝],[null],[null],[null],[null],[null],[null],[null],[null],[null],[null],[null],[null],[null],[null]]

现在二叉树是:
[[汉献帝],[刘备],[曹操],[关羽],[张飞],[张辽],[许褚],[null],[null],[null],[null],[null],[null],[null],[null]]

刘备的左手是: 关羽
汉献帝的右手是:曹操

张飞的上司是:刘备
false

下载源码:
分享到:
评论

相关推荐

    Java创建二叉树的3种方式

    Java实现二叉树的3种方式,顺序二叉树的实现,二叉树的三叉链表存储,二叉树的二叉链表实现

    java 二叉排序树与平衡二叉树的实现

    分别采用二叉链表和顺序表作存储结构,实现对二叉排序树与平衡二叉树的操作。 重庆理工大学,软件工程系,课程设计。

    Java数据结构和算法

    JAVA数据结构和算法,经典java算法书籍,完美中文版哟

    数据结构(Java版)-学生成绩管理系统

    学生成绩管理系统---使用数据结构中的二叉树排序,利用数据库实现学生查询、删除、修改信息、按学号或班级或课程成绩查询学生信息等。主要是字符界面显示

    ArrayBinaryTreeDemo.java

    用Java实现【顺序存储二叉树】 从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组

    数据结构java版第4章课后习题答案

    (1)一棵度为2 的树与一棵二叉树有何区别?树与二叉树之间有何区别? 【解答】 ①二叉树是有序树,度为 2 的树是...1)它的顺序存储结构示意图; 2)它的二叉链表存储结构示意图; 3)它的三叉链表存储结构示意图。

    java算法大全源码包.zip

    Java实现如下算法: 1.链表 链表用来存储数据,由一系列的结点组成。这些结点的物理地址不一定是连续的,即可能连续,也可能不连续,但链表里的结点是有序的。一个结点由数据的值和下一个数据的地址组成。一个链表...

    java算法与数据结构

    (1)顺序表的特点及存储结构 (2)链表的特点及存储结构 (3)栈的特点及基本操作 (4)队列的特点及基本操作 (5)顺序串和链串的存储结构 (6)二维数组的地址计算 (7)稀疏矩阵的概念及存储结构 (8)线性表的...

    Java常用算法手册源代码

    **章 算法和实现算法的Java语法 1.1 建立算法初步概念 1.1.1 什么是算法 1.1.2 算法的发展历史 1.1.3 算法的分类 1.2 算法相关概念的区别 1.2.1 算法与公式的关系 1.2.2 算法与程序的关系 1.2.3 算法与数据结构的...

    数据结构与算法复习(Java):排序、字符串、数组、链表、二分查找、二叉树.zip

    逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何...

    数据结构面试题 java面试题

    12.线性表的顺序存储结构和线性表的链式存储结构分别是(随机存取的存储结构、顺序存取的存储结构) 13.树是结点的集合,它的根结点数目是(有且只有1) 14.在深度为5的满二叉树中,叶子结点的个数为(31) 15.具有3...

    Java面试宝典-经典

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    Java面试宝典2010版

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    java面试题

    用JAVA实现一个快速排序。 40 59. 请对以下在J2EE中常用的名词进行解释(或简单描述) 40 59.1. web 容器 40 59.2. EJB容器 40 59.3. JNDI 40 59.4. JMS 41 59.5. JTA 41 59.6. JAF 41 59.7. RMI/IIOP 41 60. JAVA语言...

    java面试题大全(2012版)

    5、说明生活中遇到的二叉树,用java实现二叉树 66 6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 71 7、写一个Singleton出来。 75 8、递归算法题1 77 9、递归...

    全国计算机二级JAVA笔试分类模拟题算法和数据结构、程序设计基础.docx

    各数据节点的存储空间可以不连续,但它们的存储顺序与逻辑顺序必须一致 B.各数据节点的存储顺序与逻辑顺序可以不一致,但它们的存储空间必须连续 C.进行插入与删除时,不需要移动表中的元素 D.以上三种说法都不对 ...

    java试题,来下吧

    若某线性表中最常用的操作是取第I个元素和找第I个元素的前趋元素,则采用___存储方式最节省时间。 A、顺序表 B、单链表 C、双链表 D、单循环链表 C 2.设在栈中,由顶向下已存放元素c、b、a,在第4个元素d入栈之前...

    数据结构与算法Java实现.zip

    逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何...

Global site tag (gtag.js) - Google Analytics