先看一个问题 将数列{1,3,6,8,10,14}构成一颗二叉树 问题分析: 1.当我们对上面的二叉树进行中序遍历时,数列为{8,3,10,1,6,14} 2.但是6,8,10,14这几个节点的左右指针没有完全利用上 3.如果我们希望充分利用各个节点的左右指针,让各个节点指向自己的前后节点怎么办 4.解决方法:线索化二叉树
线索二叉树基本介绍
1.n个节点的二叉链表中含有n+1个空指针域(公式:2n-(n-1)=n+1),利用二叉链表的空指针域,存放指向该节点再某种遍历次序下的前驱和后继节点的指针(这种附加的指针称为线索) 2.这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded Binary Tree),根据线索性质的不同,线索二叉树可以分为前序线索二叉树,中序线索二叉树和后续线索二叉树三种 3.一个节点的前一个节点叫做前驱节点,后一个节点叫做后继节点
线索二叉树应用案例
应用案例说明:将下面的二叉树,进行中序线索二叉树。中序遍历的数列为{8,3,10,1,14,6} 思路分析:中序遍历的结果:{8,3,10,1,14,6} 说明:当线索化二叉树后,Node节点的属性left和right有如下情况 1)left指向的是左子树,也可能指向的是前驱节点 2)right指向的是右子树,也可能是后继节点
代码实现
class HeroNode{
private int no
;
private String name
;
private HeroNode left
;
private HeroNode right
;
private int leftType
;
private int rightType
;
public HeroNode(int no
, String name
) {
super();
this.no
= no
;
this.name
= name
;
}
public int
getLeftType() {
return leftType
;
}
public void setLeftType(int leftType
) {
this.leftType
= leftType
;
}
public int
getRightType() {
return rightType
;
}
public void setRightType(int rightType
) {
this.rightType
= rightType
;
}
public int
getNo() {
return no
;
}
public void setNo(int no
) {
this.no
= no
;
}
public String
getName() {
return name
;
}
public void setName(String name
) {
this.name
= name
;
}
public HeroNode
getLeft() {
return left
;
}
public void setLeft(HeroNode left
) {
this.left
= left
;
}
public HeroNode
getRight() {
return right
;
}
public void setRight(HeroNode right
) {
this.right
= right
;
}
@Override
public String
toString() {
return "Node [no=" + no
+ ", name=" + name
+ "]";
}
public void delNode(int no
) {
if(this.left
!=null&&this.left
.no
==no
) {
this.left
=null;
return;
}
if(this.right
!=null&&this.right
.no
==no
) {
this.right
=null;
return;
}
if(this.left
!=null) {
this.left
.delNode(no
);
return;
}
if(this.right
!=null) {
this.right
.delNode(no
);
return;
}
}
public void preOrder(){
System
.out
.println(this);
if(this.left
!=null) {
this.left
.preOrder();
}
if(this.right
!=null) {
this.right
.preOrder();
}
}
public void infixOrder() {
if(this.left
!=null) {
this.left
.infixOrder();
}
System
.out
.println(this);
if(this.right
!=null) {
this.right
.infixOrder();
}
}
public void postOrder() {
if(this.left
!=null) {
this.left
.postOrder();
}
if(this.right
!=null) {
this.right
.postOrder();
}
System
.out
.println(this);
}
public HeroNode
preOrderSearch(int no
) {
if(this.no
==no
) {
return this;
}
HeroNode resNode
=null;
if(this.left
!=null) {
resNode
=this.left
.preOrderSearch(no
);
}
if(resNode
!=null) {
return resNode
;
}
if(this.right
!=null) {
resNode
=this.right
.preOrderSearch(no
);
}
return resNode
;
}
public HeroNode
infixOrderSearch(int no
) {
HeroNode resNode
=null;
if(this.left
!=null) {
resNode
=this.left
.infixOrderSearch(no
);
}
if(resNode
!=null) {
return resNode
;
}
if(this.no
==no
) {
return this;
}
if(this.right
!=null) {
resNode
=this.right
.infixOrderSearch(no
);
}
return resNode
;
}
public HeroNode
postOrderSearch(int no
) {
HeroNode resNode
=null;
if(this.left
!=null) {
resNode
=this.left
.postOrderSearch(no
);
}
if(resNode
!=null) {
return resNode
;
}
if(this.right
!=null) {
resNode
=this.right
.postOrderSearch(no
);
}
if(resNode
!=null) {
return resNode
;
}
if(this.no
==no
) {
return this;
}
return resNode
;
}
}
class ThreadedBinaryTree{
private HeroNode root
;
private HeroNode pre
=null;
public void setRoot(HeroNode root
) {
this.root
= root
;
}
public void threadedNode() {
this.threadedNodes(root
);
}
public void threadedNodes(HeroNode node
) {
if(node
==null) {
return;
}
threadedNodes(node
.getLeft());
if(node
.getLeft()==null) {
node
.setLeft(pre
);
node
.setLeftType(1);
}
if(pre
!=null&&pre
.getRight()==null) {
pre
.setRight(node
);
pre
.setRightType(1);
}
pre
=node
;
threadedNodes(node
.getRight());
}
public void delNode(int no
) {
if(root
!=null) {
if(root
.getNo()==no
) {
root
=null;
}else {
root
.delNode(no
);
}
}else {
System
.out
.println("空树, 不能删除");
}
}
public void preOrder() {
if(this.root
!=null) {
this.root
.preOrder();
}else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void infixOrder() {
if(this.root
!=null) {
this.root
.infixOrder();
}else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void postOrder() {
if(this.root
!=null) {
this.root
.postOrder();
}else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public HeroNode
preOrderSearch(int no
) {
if(root
!=null) {
return root
.preOrderSearch(no
);
}else {
return null;
}
}
public HeroNode
infixOrderSearch(int no
) {
if(root
!=null) {
return root
.infixOrderSearch(no
);
}else {
return null;
}
}
public HeroNode
postOrderSearch(int no
) {
if(root
!=null) {
return root
.postOrderSearch(no
);
}else {
return null;
}
}
}
public static void main(String
[] args
) {
HeroNode root
=new HeroNode(1,"q");
HeroNode node2
=new HeroNode(3,"w");
HeroNode node3
=new HeroNode(6,"e");
HeroNode node4
=new HeroNode(8,"r");
HeroNode node5
=new HeroNode(10,"t");
HeroNode node6
=new HeroNode(14,"y");
root
.setLeft(node2
);
root
.setRight(node3
);
node2
.setLeft(node4
);
node2
.setRight(node5
);
node3
.setLeft(node6
);
ThreadedBinaryTree threadedBinaryTree
=new ThreadedBinaryTree();
threadedBinaryTree
.setRoot(root
);
threadedBinaryTree
.threadedNode();
HeroNode leftNode
=node5
.getLeft();
HeroNode rightNode
=node5
.getRight();
System
.out
.println("10的前驱节点是="+leftNode
);
System
.out
.println("10的后继结点是="+rightNode
);
}