二叉树的存储
顺序存储二叉树
1.基本说明
从数据存储来看,数据存储方式和数的存储方式可以相互转换。
2.特点
1)顺序二叉树通常只考虑完全二叉树;
2)第n个元素的左子节点为2 * n + 1;
3)第n个元素的右子节点为2 * n + 2;
4)第n个元素的父节点为(n-1)/2;
- n为下标,从0开始。
package com.sratct.tree;
public class ArrBinaryTreeDemo {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7};
ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr);
arrBinaryTree.getList();
}
}
class ArrBinaryTree {
private int[] arr;
public ArrBinaryTree(int[] arr) {
this.arr = arr;
}
public void getList() {
getList(0);
}
// 顺序存储二叉树的前序遍历
public void getList(int n) {
if (arr == null || arr.length ==0) {
System.out.println("链表为空");
return;
}
System.out.println(arr[n]);
// 左递归:2*n+1为当前节点的左子节点的下标
if ((2 * n + 1) < arr.length) {
getList(2*n+1);
}
if ((2 * n + 2) < arr.length) {
getList(2*n+2);
}
}
}
线索二叉树
1.基本介绍
1)n个结点二叉链表中含有n+1个空指针域(公式:2n - (n - 1))。利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为‘线索’)。
2)这种加了线索的二叉链表为线索链表,相应的二叉树为线索二叉树。
2.创建以及遍历线索二叉树
package com.sratct.tree;
public class ThreadTreeDemo {
public static void main(String[] args) {
ThreadTree threadTree = new ThreadTree();
TNode root = new TNode(1);
TNode node1 = new TNode(3);
TNode node2 = new TNode(6);
TNode node3 = new TNode(8);
TNode node4 = new TNode(10);
TNode node5 = new TNode(14);
root.left = node1;
root.right = node2;
node1.left = node3;
node1.right = node4;
node2.left = node5;
threadTree.zThread(root);
threadTree.threadList(root);
}
}
class ThreadTree {
private TNode pre = null; //指向当前节点的前驱结点的指针
// 对二叉树中序线索化的方法
public void zThread(TNode root) {
if (root == null) {
System.out.println("二叉树为空");
return;
}
// 线索化左子树
if (root.left != null) {
zThread(root.left);
}
// 线索化当前元素
// 处理当前结点的前驱结点
if (root.left == null) {
// 当前节点的做指针指向前序结点
root.left = pre;
root.leftType = 1;
}
// 处理当前结点的后继结点,需要到下一个结点
if (pre != null && pre.right == null) {
// 让前驱结点的右指针指向当前节点
pre.right = root;
pre.rightType = 1;
}
// pre后移到下一个
pre = root;
// 线索化右子树
if (root.right != null) {
zThread(root.right);
}
}
// 遍历线索二叉树
public void threadList(TNode root) {
TNode node = root;
while (node != null) {
// 找到第一个leftType=1的结点为处理后的有效结点,就是8
while (node.leftType == 0) {
node = node.left;
}
// 输出当前结点
System.out.println(node.no);
// 找到第一个有效结点后(rightType ==1),判断右指针是否为后继结点,是就输出
while (node.rightType ==1) {
node = node.right;
System.out.println(node.no);
}
// rightType == 0,则直接向后移
node = node.right;
}
}
}
class TNode {
public int no;
public TNode left;
public TNode right;
public int leftType; // 如果leftType = 0指向左子树,为1则指向前驱结点
public int rightType; // 如果rightType = 0 指向右子树,为1时则指向后继结点
public TNode(int no) {
this.no = no;
}
}