数据结构线索化二叉树

我们知道,对于一个n个节点的二叉树,除了根节点外每个节点都有一个指向父亲的引用,因此有n-1个引用,而n个节点总共有2*n个引用,因此还有n+1个引用没有使用,如果把这些引用分别指向当前节点的前驱或者后继,则将此二叉树线索化。线索化后的二叉树遍历比较方便,不需要递归,效率快。以下使用java语言描述二叉树的线索化。

二叉树的节点Node类的代码如下:

package edu.qc.tree.thread;


public class Node {
private int data;
private Node left;
private boolean leftIsThread;//左孩子是否为线索
private Node right;
private boolean rightIsThread;//右孩子是否为线索

public Node(int data){
this.data = data ;
this.left = null ;
this.leftIsThread = false ;
this.right = null ;
this.rightIsThread = false ;
}


public int getData() {
return data;
}


public void setData(int data) {
this.data = data;
}


public Node getLeft() {
return left;
}


public void setLeft(Node left) {
this.left = left;
}


public boolean isLeftIsThread() {
return leftIsThread;
}


public void setLeftIsThread(boolean leftIsThread) {
this.leftIsThread = leftIsThread;
}


public Node getRight() {
return right;
}


public void setRight(Node right) {
this.right = right;
}


public boolean isRightIsThread() {
return rightIsThread;
}


public void setRightIsThread(boolean rightIsThread) {
this.rightIsThread = rightIsThread;
}


@Override
public boolean equals(Object obj) {
if(obj instanceof Node){
Node temp = (Node)obj ;
if(temp.getData() == this.data){
return true ;

}
return false;
}


@Override
public int hashCode() {
return super.hashCode() + this.data ;
}
}


然后具体的线索化二叉树ThreadTree类的代码如下:

package edu.qc.tree.thread;


public class ThreadTree {
private Node root;// 跟节点
private int size;// 大小
private Node pre = null ;//线索化的时候保存前驱

public ThreadTree(){
this.root = null ;
this.size = 0 ;
this.pre = null ;
}

public ThreadTree(int[] data){
this.pre = null ;
this.size = data.length ;
this.root = createTree(data , 1) ;//创建二叉树
}

/**
* 创建二叉树
* @param data
*/
public Node createTree(int[] data , int index){
if(index > data.length){
return null ;
}
Node node = new Node(data[index-1]) ;
Node left = createTree(data , 2*index) ;
Node right = createTree(data , 2*index+1) ;
node.setLeft(left) ;
node.setRight(right) ;
return node ;
}

/**
* 将以root为根节点的二叉树线索化
* @param root
*/
public void inThread(Node root){
if(root != null){
inThread(root.getLeft()) ;//线索化左孩子
if(null == root.getLeft()){//左孩子为空
root.setLeftIsThread(true) ;//将左孩子设置为线索
root.setLeft(pre) ;
}
if(pre!=null&&null == pre.getRight()){//右孩子为空
pre.setRightIsThread(true) ;
pre.setRight(root) ;
}
pre = root ;
inThread(root.getRight()) ;//线索化右孩子
}
}

/**
* 中序遍历线索二叉树
* @param root
*/
public void inThreadList(Node root){
if(root != null){
while(root!=null && !root.isLeftIsThread()){//如果左孩子不是线索
root = root.getLeft() ;//
}

do{
System.out.print(root.getData() + ",");
if(root.isRightIsThread()){//如果右孩子是线索
root = root.getRight() ;
}else{//有右孩子
root = root.getRight() ;
while(root!=null && !root.isLeftIsThread()){
root = root.getLeft() ;
}
}
}while(root != null) ; 
}
}

/**
* 先序遍历递归算法
* @param root
*/
public void preList(Node root){
if(root != null){
System.out.print(root.getData() + ",");
preList(root.getLeft()) ;
preList(root.getRight()) ;
}
}

/**
* 中序遍历
* @param root
*/
public void inList(Node root){
if(root != null){
inList(root.getLeft()) ;
System.out.print(root.getData() + ",");
inList(root.getRight()) ;
}
}


public Node getRoot() {
return root;
}


public void setRoot(Node root) {
this.root = root;
}


public int getSize() {
return size;
}


public void setSize(int size) {
this.size = size;
}


}


然后具体的测试类ThreadTreeTest的代码如下:

package edu.qc.tree.thread;


public class ThreadTreeTest {
public static void main(String[] args) {
int[] data = {1,2,3,4,5,6,7,8,9,10} ;
ThreadTree tt = new ThreadTree(data) ;//创建普通二叉树
tt.inList(tt.getRoot()) ;//中序递归遍历二叉树
System.out.println("");

tt.inThread(tt.getRoot()) ;//采用中序遍历将二叉树线索化
tt.inThreadList(tt.getRoot()) ;//中序遍历线索化二叉树
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值