二叉树的存储结构
顺序存储:就是用一组数组来存储二叉树中节点,并且节点的存储位置,也就是数组的下标要能体现节点之间的逻辑关系。
考虑一种极端情况,一棵深度为k的右斜数,它只有k个节点,却需要分配2^k-1个存储单元,这显然是对空间的浪费,所以顺序的存储结构只适用于完全二叉树。
二叉链表:既然顺序存储结构实用性不强,我们就要考虑练市存储结构。二叉树每个节点最多有两个孩子,所以它设计一个数据域和两个指针域是比较自然的想法。我们称这样的链表叫做二叉链表。
二叉树遍历原理
二叉树的遍历是从根节点出发,按照某种次序依次访问二叉树中所有节点,使得每个节点的被访问一次且仅被访问一次。
二叉树的遍历方法
前序遍历:根-->左-->右
中序遍历:左-->根-->右
后序遍历:左-->右-->根
二叉树遍历的JAVA实现
public class BinaryTree {
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
System.out.print("前序遍历:");
binaryTree.preOrderTraverse(binaryTree.init());
System.out.println();
System.out.print("中序遍历:");
binaryTree.InOrderTraverse(binaryTree.init());
System.out.println();
System.out.print("后序遍历:");
binaryTree.PostOrderTraverse(binaryTree.init());
}
private BinaryTreeNode init() {
BinaryTreeNode root = new BinaryTreeNode("a");
BinaryTreeNode nodeB = new BinaryTreeNode("b");
BinaryTreeNode nodeC = new BinaryTreeNode("c");
root.setLchild(nodeB);
root.setRchild(nodeC);
BinaryTreeNode nodeD = new BinaryTreeNode("d");
BinaryTreeNode nodeE = new BinaryTreeNode("e");
nodeB.setLchild(nodeD);
nodeB.setRchild(nodeE);
BinaryTreeNode nodeH = new BinaryTreeNode("h");
nodeD.setLchild(nodeH);
BinaryTreeNode nodeK = new BinaryTreeNode("k");
nodeH.setRchild(nodeK);
BinaryTreeNode nodeF = new BinaryTreeNode("f");
BinaryTreeNode nodeG = new BinaryTreeNode("g");
nodeC.setLchild(nodeF);
nodeC.setRchild(nodeG);
BinaryTreeNode nodeI = new BinaryTreeNode("i");
nodeF.setLchild(nodeI);
BinaryTreeNode nodeJ = new BinaryTreeNode("j");
nodeG.setRchild(nodeJ);
return root;
}
/**
* 前序遍历
*
* @param binaryTreeNode
*/
private void preOrderTraverse(BinaryTreeNode binaryTreeNode) {
if (binaryTreeNode == null) {
return;
}
System.out.print(binaryTreeNode.getData() + " ");
preOrderTraverse(binaryTreeNode.getLchild());
preOrderTraverse(binaryTreeNode.getRchild());
}
/**
* 中序遍历
*
* @param binaryTreeNode
*/
private void InOrderTraverse(BinaryTreeNode binaryTreeNode) {
if (binaryTreeNode == null) {
return;
}
InOrderTraverse(binaryTreeNode.getLchild());
System.out.print(binaryTreeNode.getData() + " ");
InOrderTraverse(binaryTreeNode.getRchild());
}
/**
* 后序遍历
*
* @param binaryTreeNode
*/
private void PostOrderTraverse(BinaryTreeNode binaryTreeNode) {
if (binaryTreeNode == null) {
return;
}
PostOrderTraverse(binaryTreeNode.getLchild());
PostOrderTraverse(binaryTreeNode.getRchild());
System.out.print(binaryTreeNode.getData() + " ");
}
class BinaryTreeNode {
private String data;
private BinaryTreeNode lchild;
private BinaryTreeNode rchild;
public BinaryTreeNode() {
}
public BinaryTreeNode(String data) {
this.data = data;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public BinaryTreeNode getLchild() {
return lchild;
}
public void setLchild(BinaryTreeNode lchild) {
this.lchild = lchild;
}
public BinaryTreeNode getRchild() {
return rchild;
}
public void setRchild(BinaryTreeNode rchild) {
this.rchild = rchild;
}
}
}
线索二叉树
指向前驱和后继的指针为线索,加上线索的二叉链表称为线索链表。相应的二叉树就称为线索二叉树。
二叉树以某种次序遍历使其变为线索二叉树的过程称作是线索化。
线索化的实质
就是将二叉链表中的空指针改为指向前驱和后继的线索。由于前驱和后继的信息只有在遍历该二叉树时才能得到。所以线索化的过程就是在遍历的过程中修改空指针。