十七:顺序储存二叉树、线索化二叉树
一、顺序储存二叉树
1.1 概念
从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组,
看下面的示意图。

1.2 特点
- 顺序二叉树通常只考虑 完全二叉树:
1、 第n个元素的左子节点为2*n+1;
2、 第n个元素的右子节点为2*n+2;
3、 第n个元素的父节点为**(n-1)/2**;
- n : 表示二叉树中的第几个元素(按0开始编号如图所示,同时对应的也是数组的顺序)

复习一下完全二叉树:如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,我们称为 完全二叉树。
1.3 关系
树的存储方式可以与数组的方式可以互换,我看出来的一个规律,二叉树的层次遍历就是数组的储存方式。
如果要将二叉树转为数组存储,既可以层次遍历然后储存到数组中即可。
1.4 案例
1、 上图的二叉树的结点,要求以数组的方式来存放array:[1,2,3,4,5,6,7];
2、 要求在遍历数组array时,仍然可以以**前序遍历,中序遍历和后序遍历**的方式完成结点的遍历;
3、 手写三种遍历,与代码进行比较;
前序遍历:1 2 4 5 3 6 7
中序遍历:4 2 5 1 6 3 7
后序遍历:4 5 2 6 7 3 1
1.5 代码实现
1.5.1 ArrayBinaryTree 二叉树类
package com.feng.ch12_tree.t2_arraybinarytree;
/*
* 编写一个 ArrayBinaryTree, 实现顺序存储二叉树遍历
* 数组 和 二叉树的 对应规律
* */
class ArrayBinaryTree {
private int[] array; // 存储数据结点的数组
public ArrayBinaryTree(int[] array) {
this.array = array;
}
// 重载perOrder()
public void preOrder() {
this.preOrder(0);
}
public void infixOrder() {
this.infixOrder(0);
}
public void postOrder() {
this.postOrder(0);
}
/*
* 编写一个方法,完成顺序储存二叉树的一个前序遍历
* @param index 数组的下标
* */
public void preOrder(int index) {
// 如果数组为空,或者 array。length = 0
if (array == null || array.length == 0) {
System.out.println("数组为空,不能按照二叉树的前序遍历");
}
// 输出当前这个元素
System.out.print(array[index] + " ");
// 向左递归遍历
if ((index * 2 + 1) < array.length) {
preOrder(2 * index + 1);
}
// 向右递归遍历
if ((index * 2 + 2) < array.length) {
preOrder(2 * index + 2);
}
}
/*
* 方法,完成顺序储存二叉树的一个中序遍历
* @param index 数组的下标
* */
public void infixOrder(int index){
// 如果数组为空,或者 array。length = 0
if (array == null || array.length == 0) {
System.out.println("数组为空,不能按照二叉树的前序遍历");
}
// 向左递归遍历
if ((index * 2 + 1) < array.length) {
infixOrder(2 * index + 1);
}
// 输出当前这个元素
System.out.print(array[index] + " ");
// 向右递归遍历
if ((index * 2 + 2) < array.length) {
infixOrder(2 * index + 2);
}
}
/*
* 方法,完成顺序储存二叉树的一个后序遍历
* @param index 数组的下标
* */
public void postOrder(int index){
// 如果数组为空,或者 array。length = 0
if (array == null || array.length == 0) {
System.out.println("数组为空,不能按照二叉树的前序遍历");
}
// 向左递归遍历
if ((index * 2 + 1) < array.length) {
postOrder(2 * index + 1);
}
// 向右递归遍历
if ((index * 2 + 2) < array.length) {
postOrder(2 * index + 2);
}
// 输出当前这个元素
System.out.print(array[index] + " ");
}
}