首先说一下满二叉树,以下是百度对满二叉树的定义
满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。
完全二叉树:如果二叉树的深度为k,则除第k层外其余所有层节点的度都为2,且叶子节点从左到右依次存在。也即是,将满二叉树的最后一层从左到右依次删除若干节点就得到完全二叉树。满二叉树是一棵特殊的完全二叉树,但完全二叉树不一定是满二叉树。
线索二叉树:在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化。对于n个结点的二叉树,在二叉链存储结构中有n+1个空链域,利用这些空链域存放在某种遍历次序下该结点的前驱结点和后继结点的指针,这些指针称为线索,加上线索的二叉树称为线索二叉树。
下面我们先定义二叉树节点:
1 package ThreadBinaryTree; 2 3 public class BinaryTreeNode { 4 5 int data ; 6 7 //左节点 8 BinaryTreeNode leftNode = null; 9 10 //右节点 11 BinaryTreeNode RightNode = null; 12 13 //左标志 14 int LeftType ; 15 16 //右标志 17 int RightType ; 18 19 20 public BinaryTreeNode(int data) { 21 this.data = data; 22 this.LeftType = 0; 23 this.RightType = 0; 24 } 25 26 27 public void addLeftChild(BinaryTreeNode Node) { 28 this.leftNode = Node; 29 } 30 31 public void addRightChild(BinaryTreeNode Node) { 32 this.RightNode = Node; 33 } 34 35 public BinaryTreeNode getLeftChild() { 36 if(this.leftNode==null) { 37 System.out.println("不存在左子节点"); 38 } 39 return this.leftNode; 40 } 41 42 public BinaryTreeNode getRightChild() { 43 if(this.RightNode==null) { 44 System.out.println("不存在右子节点"); 45 } 46 return this.RightNode; 47 } 48 49 //中序遍历 50 public void midshow() { 51 52 if(this.leftNode!=null) { 53 this.leftNode.midshow(); 54 } 55 System.out.print(this.data+","); 56 57 if(this.RightNode!=null) { 58 this.RightNode.midshow(); 59 } 60 61 } 62 63 //线索化之后的中序遍历 64 public void afterThreadMidShow() { 65 66 if(this.leftNode!=null) { 67 if(this.LeftType==0) 68 this.leftNode.afterThreadMidShow(); 69 } 70 System.out.print(this.data+","); 71 72 if(this.RightNode!=null) { 73 if(this.RightType==0) 74 this.RightNode.afterThreadMidShow(); 75 } 76 77 } 78 79 }
这里左标志和右标志 是线索化二叉树会用到的节点,因为我们要标记出来哪个节点是左节点还是前序节点
下面是上面二叉树线索化的实例
1 package ThreadBinaryTree; 2 3 public class ThreadBinaryTreeDemo { 4 5 BinaryTreeNode preNode = null; 6 7 8 @SuppressWarnings("unused") 9 public void ThreadingBinaryTree(BinaryTreeNode Node) { 10 11 12 13 if(Node.leftNode!=null) { 14 ThreadingBinaryTree(Node.leftNode); 15 } 16 17 //前一个节点右边联系到本节点 18 19 if(preNode != null && preNode.RightNode==null) 20 { 21 preNode.RightNode=Node; 22 preNode.RightType=1; 23 } 24 25 //左边联系到前一个节点 26 if(Node.leftNode==null) { 27 Node.leftNode = preNode; 28 Node.LeftType = 1; 29 } 30 31 preNode = Node; 32 33 34 if(Node.RightNode!=null) { 35 ThreadingBinaryTree(Node.RightNode); 36 } 37 38 } 39 40 41 42 }
最后进行测试
package ThreadBinaryTree; public class BinaryTreeTest { public static void main(String[] args) { BinaryTreeNode root = new BinaryTreeNode(1); BinaryTreeNode Node1 = new BinaryTreeNode(2); BinaryTreeNode Node2 = new BinaryTreeNode(3); BinaryTreeNode Node3 = new BinaryTreeNode(4); BinaryTreeNode Node4 = new BinaryTreeNode(5); BinaryTreeNode Node5 = new BinaryTreeNode(6); BinaryTreeNode Node6 = new BinaryTreeNode(7); root.addLeftChild(Node1); root.addRightChild(Node2); Node1.addLeftChild(Node3); Node1.addRightChild(Node4); Node2.addLeftChild(Node5); Node2.addRightChild(Node6); root.midshow(); ThreadBinaryTreeDemo tbtd = new ThreadBinaryTreeDemo(); tbtd.ThreadingBinaryTree(root); System.out.println(); root.afterThreadMidShow(); // System.out.println(Node4.leftNode.data); // System.out.println(Node4.RightNode.data); } }
以上便完成了一个完全二叉树的线索化