数据结构——Java实现二叉树

相关概念

  存储结构:

  1. 顺序存储结构:二叉树的顺序存储结构适用于完全二叉树,对完全二叉树进行顺序编号,通过二叉树的性质五(第1个结点为根结点,第i个结点的左孩子为第2i个结点,右孩子为第2i+1个结点)。
  2. 链式存储结构:一般情况下,采用链式存储结构来存储二叉树。每个结点有3个域:data、left、right。

  遍历:

  1. 先根次序:根->左->右。
  2. 中根次序:左->根->右。
  3. 后根次序:左->右->根。

  遍历算法:

  1. 递归
  2. 非递归:通过设立一个栈。

声明二叉树结点类

 1 /**
 2  * Copyright 2016 Zhengbin‘s Studio.
 3  * All right reserved.
 4  * 2016年7月16日 上午8:19:15
 5  */
 6 package Two;
 7
 8 /**
 9  * @author zhengbinMac
10  *
11  */
12 public class TreeNode {
13     int val;
14     TreeNode left;
15     TreeNode right;
16     TreeNode(int x) {
17         val = x;
18     }
19     /**
20      * 先根遍历
21      * @param p
22      */
23     public void preorder(TreeNode p) {
24         if(p != null) {
25             System.out.print(p.val + " ");
26             preorder(p.left);
27             preorder(p.right);
28         }
29     }
30     /**
31      * 中根遍历
32      * @param p
33      */
34     public void inorder(TreeNode p) {
35         if(p != null) {
36             preorder(p.left);
37             System.out.print(p.val + " ");
38             preorder(p.right);
39         }
40     }
41     /**
42      * 后根遍历
43      * @param p
44      */
45     public void postorder(TreeNode p) {
46         if(p != null) {
47             preorder(p.left);
48             preorder(p.right);
49             System.out.print(p.val + " ");
50         }
51     }
52 }

声明二叉树类 和 由先根遍历与中根遍历构造二叉树

  建立一颗二叉树必须明确以下两点:

  1. 结点与双亲结点及孩子结点间的层次关系。
  2. 兄弟结点间的左右子树的顺序关系。

  先根次序或后根次序反映双亲与孩子结点的层次关系,中根次序反映兄弟结点间的左右次序。所以,已知先根和中根两种遍历序列,或中根和后根两种遍历序列才能够唯一确定一颗二叉树。而已知先根和后根两种遍历序列仍无法唯一确定一颗二叉树。

  1 /**
  2  * Copyright 2016 Zhengbin‘s Studio.
  3  * All right reserved.
  4  * 2016年7月16日 上午9:30:01
  5  */
  6 package Two;
  7
  8 import java.util.Arrays;
  9
 10 /**
 11  * @author zhengbinMac
 12  *
 13  */
 14 public class Tree {
 15     protected TreeNode root;
 16     public Tree() {
 17         root = null;
 18     }
 19     public Tree(int[] pre, int[] in) {
 20 //        root = reConstructBinaryTree(pre, in);
 21         root = reConstructBinaryTree1(pre, in);
 22     }
 23     /**
 24      * 先根次序
 25      */
 26     public void preorderTraversal() {
 27         System.out.println("先根次序遍历:");
 28         if(root != null) {
 29             root.preorder(root);
 30         }
 31     }
 32     /**
 33      * 中根次序
 34      */
 35     public void inorderTraversal() {
 36         System.out.println("中根次序遍历:");
 37         if(root != null) {
 38             root.inorder(root);
 39         }
 40     }
 41     /**
 42      * 后根次序
 43      */
 44     public void postorderTraversal() {
 45         System.out.println("后根次序遍历:");
 46         if(root != null) {
 47             root.postorder(root);
 48         }
 49     }
 50     /**
 51      * 通过先根遍历与中根遍历构造二叉树(1)
 52      */
 53     public TreeNode reConstructBinaryTree1(int[] pre, int[] in) {
 54         if(pre.length == 0 || in.length == 0) {
 55             return null;
 56         }
 57         TreeNode p = new TreeNode(pre[0]);
 58         for (int i = 0; i < in.length; i++) {
 59             if(pre[0] == in[i]) {
 60                 p.left = reConstructBinaryTree1(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i));
 61                 p.right = reConstructBinaryTree1(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1, in.length));
 62             }
 63         }
 64         return p;
 65     }
 66     /**
 67      * 通过先根遍历与中根遍历构造二叉树(2)
 68      */
 69     public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
 70         if(pre == null || in == null) {
 71             return null;
 72         }
 73         TreeNode p = null;
 74         int first;
 75         int n = pre.length;
 76         int k = 0;
 77         if(n > 0) {
 78             // 取第一个为根
 79             first = pre[0];
 80             p = new TreeNode(first);
 81             // 确定根结点在中根序列中的位置
 82             for (int i = 0; i < in.length; i++) {
 83                 if(in[i] == first) {
 84                     k = i;
 85                     break;
 86                 }
 87             }
 88             // 左子树
 89             int[] presubLeft = new int[k];
 90             int[] insubLeft = new int[k];
 91             // 先根
 92             for (int i = 1, j = 0; i <= k; i++, j++) {
 93                 presubLeft[j] = pre[i];
 94             }
 95             // 中根
 96             for (int i = 0, j = 0; i <= k-1; i++, j    ++) {
 97                 insubLeft[j] = in[i];
 98             }
 99             p.left = reConstructBinaryTree(presubLeft, insubLeft);
100             // 右子树
101             int[] presubRight = new int[n-1-k];
102             int[] insubRight = new int[n-1-k];
103             // 先根
104             for (int i = k+1, j = 0; i <= n-1; i++,j++) {
105                 presubRight[j] = pre[i];
106             }
107             // 中根
108             for (int i = k+1, j = 0; i <= n-1; i++,j++) {
109                 insubRight[j] = in[i];
110             }
111             p.right = reConstructBinaryTree(presubRight, insubRight);
112         }
113         return p;
114     }
115 }

测试类

 1 /**
 2  * Copyright 2016 Zhengbin‘s Studio.
 3  * All right reserved.
 4  * 2016年7月16日 上午9:27:40
 5  */
 6 package Two;
 7
 8 /**
 9  * @author zhengbinMac
10  *
11  */
12 public class Test {
13
14     public static void main(String[] args) {
15         int[] pre = {1,2,4,3,5,6};
16         int[] in = {4,2,1,5,3,6};
17         Tree t = new Tree(pre, in);
18         t.inorderTraversal();
19         System.out.println();
20         t.postorderTraversal();
21         System.out.println();
22         t.preorderTraversal();
23     }
24 }

在线编程:

牛客网——《剑指Offer》-重建二叉树

时间: 2024-10-10 14:14:33

数据结构——Java实现二叉树的相关文章

【数据结构】之二叉树的java实现

二叉树的定义: 二叉树是树形结构的一个重要类型.许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要. 二叉树(BinaryTree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的.分别称作这个根的左子树和右子树的二叉树组成. 这个定义是递归的.由于左.右子树也是二叉树, 因此子树也可为空树.下图中展现了五种不同基本形态的二叉树. 其中 (a) 为空树, (b

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

Java实现二叉树及相关遍历方式 在计算机科学中.二叉树是每一个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree).二叉树常被用于实现二叉查找树和二叉堆. 下面用Java实现对二叉树的先序遍历,中序遍历,后序遍历.广度优先遍历.深度优先遍历.转摘请注明:http://blog.csdn.net/qiuzhping/article/details/44830369 package com.qiuz

9.6-全栈Java笔记:二叉树和红黑二叉树

二叉树的定义 二叉树是树形结构的一个重要类型. 许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要. 二叉树(BinaryTree)由一个结点及两棵互不相交的.分别称作这个根的左子树和右子树的二叉树组成.下图中展现了五种不同基本形态的二叉树. (a) 为空树 (b) 为仅有一个结点的二叉树 (c) 是仅有左子树而右子树为空的二叉树 (d) 是仅有右子树而左子树为空的二叉树 (e) 是左.右子树均非

纯数据结构Java实现(4/11)(BST)

个人感觉,BST(二叉查找树)应该是众多常见树的爸爸,而不是弟弟,尽管相比较而言,它比较简单. 二叉树基础 理论定义,代码定义,满,完全等定义 不同于线性结构,树结构用于存储的话,通常操作效率更高.就拿现在说的二叉搜索树(排序树)来说,如果每次操作之后会让剩余的数据集减少一半,这不是太美妙了么?(当然不当的运用树结构存储,也会导致从 O(logN) 退化到 O(n)). 值得说明,O(logN) 其实并不准确,准确来说应该说 O(树的高度) 定义&性质&行话 树里面常见的二叉树: BST,

纯数据结构Java实现(6/11)(二叉堆&amp;优先队列)

堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). 但是二叉堆,需要满足一些特殊性质: 其一.二叉堆一定是一棵完全二叉树 (完全二叉树可以用数组表示,见下面) 完全二叉树缺失的部分一定是在右下方.(每层一定是从左到右的顺序优先存放) 完全二叉树的结构,可以简单理解成按层安放元素的.(所以数组是不错的底层实现) 其二.父节点一定比子节点大 (针对大顶堆

数据结构Java实现05----栈:顺序栈和链式堆栈

数据结构Java实现05----栈:顺序栈和链式堆栈 一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除操作. 先进后出:堆栈中允许进行插入和删除操作的一端称为栈顶,另一端称为栈底.堆栈的插入和删除操作通常称为进栈或入栈,堆栈的删除操作通常称为出栈或退栈. 备注:栈本身就是一个线性表,所以我们之前讨论过线性表的顺序存储和链式存储,对于栈来说,同样适

SDUT 3343 数据结构实验之二叉树四:还原二叉树

数据结构实验之二叉树四:还原二叉树 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度. Input 输入数据有多组,每组数据第一行输入1个正整数N(1 <= N <= 50)为树中结点总数,随后2行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区分大小写)的字符串. Output 输出一个整数,即该二叉树的

数据结构Java实现06----中缀表达式转换为后缀表达式

数据结构Java实现06----中缀表达式转换为后缀表达式 本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则),如:2 1 + 3 *.又比如3+(6-4/2)*5=23的后缀表达式为:3642/-5*+# (#符号为结束符

数据结构Java实现04----循环链表、仿真链表

数据结构Java实现04----循环链表.仿真链表 单向循环链表 双向循环链表 仿真链表 一.单向循环链表: 1.概念: 单向循环链表是单链表的另一种形式,其结构特点是链表中最后一个结点的指针不再是结束标记,而是指向整个链表的第一个结点,从而使单链表形成一个环. 和单链表相比,循环单链表的长处是从链尾到链头比较方便.当要处理的数据元素序列具有环型结构特点时,适合于采用循环单链表. 和单链表相同,循环单链表也有带头结点结构和不带头结点结构两种,带头结点的循环单链表实现插入和删除操作时,算法实现较为