线索二叉树(Java)

线索二叉树(Java)

在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化

定义
  • 对二叉树进行遍历,可以把二叉树中所有结点排列为一个线性序列;
  • 为了保留结点在某种遍历序列中 直接前驱和直接后继 的位置信息,可以利用二叉树的二叉链表存储结构中的空指针域 来指示
意义
  • 一个具有n 个结点的二叉树若采用二叉链表存储结构,在2n 个指针域中只有n -1 个指针域是用来存储结点孩子的引用,而另外n +1 个指针域 存放的都是NULL
  • 对二叉树进行遍历,时间复杂度大,且一次遍历之后无法记忆某结点的前驱或者后继
举个栗子

原二叉树如下:
在这里插入图片描述
经过先序线索化后的二叉树如下:
在这里插入图片描述

public void prethreadbinary(Node no) {//先序线索化
		if(no==null) {
			return ;
		}
		
		if(no.getLeft()==null) {
			no.setLeft(pre);
			no.setLeftype(1);
		}
		if(pre!=null&&pre.getRight()==null) {
			pre.setRight(no);
			pre.setRighttype(1);
		}
		pre=no;
	if(no.getLeftype()==0) {
		prethreadbinary(no.getLeft());//线索化右8子树
	}
	if(no.getRighttype()==0) {
		prethreadbinary(no.getRight());
	}
	
	}

经过中序线索化后的二叉树如下:
在这里插入图片描述


	public void infixthreadbinary(Node no) {//中序线索化
		if(no==null) {
			return;
		}
		infixthreadbinary(no.getLeft());//线索化左子树
		if(no.getLeft()==null) {//处理前驱结点
			no.setLeft(pre);
			no.setLeftype(1);
		}
		if(pre!=null&&pre.getRight()==null) {//处理后继结点
			pre.setRight(no);
			pre.setRighttype(1);
		}
		pre=no;//处理一个结点后,让当前结点为下一个结点的前驱
		infixthreadbinary(no.getRight());//线索化右子树
	}
	
遍历线索二叉树

因线索化后有前驱和后继,所以之前的遍历方式会出现死循环
先序遍历先序线索化二叉树:

	//先序遍历
	public void prethread() {
		Node no=root;
		while(no!=null) {
			while(no.getLeftype()==0) {
				System.out.println(no);
				no=no.getLeft();
			}
			System.out.println(no);
			no=no.getRight();
		}
	}

中序遍历中序线索化二叉树:

//中序遍历
	public void infixthread() {
		Node no=root;
		while(no!=null) {
			while(no.getLeftype()==0) {//找到leftype==1的结点,即被线索化结点
				no=no.getLeft();
			}
			System.out.println(no);
			while(no.getRighttype()==1) {//获取当前结点的后继结点
				no=no.getRight();
				System.out.println(no);
			}
			no=no.getRight();//用后继结点替换当前结点
		}
	}
	
完整代码


public class Threadbinarytree2 {

	public static void main(String[] args) {
		Threadbinarytree binarytree=new Threadbinarytree();//创建二叉树
		Node root =  new Node( "A");//创建结点
		Node node2 = new Node( "B");
		Node node3 = new Node( "C");
		Node node4 = new Node( "D");
		Node node5 = new Node( "E");
		Node node6 = new Node("F");
		root.setLeft( node2);//建立结点间的关系
		root.setRight(node3);
		node2.setLeft(node4);
		node2.setRight(node5);
		node3.setLeft(node6);
		binarytree.setRoot(root);
//		System.out.println("-----先序线索化二叉树后------");
//		binarytree.prethreadbinary();//线索化二叉树
//		Node lnode=node5.getLeft();
//		Node rnode=node5.getRight();
//		
//		System.out.println("E结点的前驱结点为:"+lnode);		
//		System.out.println("E结点的后继结点为:"+rnode);
//		System.out.println("前序遍历二叉树结果为:");
//		binarytree.prethread();
		
		System.out.println("-----中序线索化二叉树后------");
		binarytree.infixthreadbinary();//线索化二叉树
		Node lnode=node5.getLeft();
		Node rnode=node5.getRight();
		System.out.println("E结点的前驱结点为:"+lnode);		
		System.out.println("E结点的后继结点为:"+rnode);
		System.out.println("中序遍历二叉树结果为:");
		binarytree.infixthread();
	}

}

class Threadbinarytree {//定义二叉树
	private Node root;
	private Node pre=null;//前驱指针
	public void setRoot(Node root) {  
		this.root = root;
	}
	public void prethreadbinary() {
		this.prethreadbinary(root);
	}
	public void infixthreadbinary() {//重载
		this.infixthreadbinary(root);
	}
	public void prethreadbinary(Node no) {//先序线索化
		if(no==null) {
			return ;
		}
		
		if(no.getLeft()==null) {
			no.setLeft(pre);
			no.setLeftype(1);
		}
		if(pre!=null&&pre.getRight()==null) {
			pre.setRight(no);
			pre.setRighttype(1);
		}
		pre=no;
	if(no.getLeftype()==0) {
		prethreadbinary(no.getLeft());//线索化右8子树
	}
	if(no.getRighttype()==0) {
		prethreadbinary(no.getRight());
	}
	
	}
	
	public void infixthreadbinary(Node no) {//中序线索化
		if(no==null) {
			return;
		}
		infixthreadbinary(no.getLeft());//线索化左子树
		if(no.getLeft()==null) {//处理前驱结点
			no.setLeft(pre);
			no.setLeftype(1);
		}
		if(pre!=null&&pre.getRight()==null) {//处理后继结点
			pre.setRight(no);
			pre.setRighttype(1);
		}
		pre=no;//处理一个结点后,让当前结点为下一个结点的前驱
		infixthreadbinary(no.getRight());//线索化右子树
	}
	//前序遍历
	public void prethread() {
		Node no=root;
		while(no!=null) {
			while(no.getLeftype()==0) {
				System.out.println(no);
				no=no.getLeft();
			}
			System.out.println(no);
			no=no.getRight();
		}
	}
	//中序遍历
	public void infixthread() {
		Node no=root;
		while(no!=null) {
			while(no.getLeftype()==0) {//找到leftype==1的结点,即被线索化结点
				no=no.getLeft();
			}
			System.out.println(no);
			while(no.getRighttype()==1) {//获取当前结点的后继结点
				no=no.getRight();
				System.out.println(no);
			}
			no=no.getRight();//用后继结点替换当前结点
		}
	}
	
	}

class Node{
	private String no;
	private Node left;
	private Node right;
	private int leftype;
	private int righttype;
	public Node(String no) {
		this.no=no;
	}
	public String getNo() {
		return no;
	}
	public void setNo(String no) {
		this.no = no;
	}
	public Node getLeft() {
		return left;
	}
	public void setLeft(Node left) {
		this.left = left;
	}
	public Node getRight() {
		return right;
	}
	public void setRight(Node right) {
		this.right = right;
	}
	public int getLeftype() {
		return leftype;
	}
	public void setLeftype(int leftype) {
		this.leftype = leftype;
	}
	public int getRighttype() {
		return righttype;
	}
	public void setRighttype(int righttype) {
		this.righttype = righttype;
	}
	@Override
	public String toString() {
		return "Node [no=" + no + "]";
	}
	
	
	 
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线索二叉树是一种特殊的二叉树,它在节点的左右子树指针上添加了线索。线索指向的是该节点在中序遍历中的前驱或后继节点。以下是一个简单的线索二叉树Java程序示例: ``` class Node { int data; Node left, right; boolean leftThread, rightThread; public Node(int value) { data = value; left = right = null; leftThread = rightThread = false; } } public class ThreadedBinaryTree { Node root; public ThreadedBinaryTree() { root = null; } // 中序遍历线索化二叉树 public void inOrderThread() { if (root == null) return; Node cur = root; Node prev = null; while (cur != null) { while (!cur.leftThread && cur.left != null) { cur = cur.left; } if (cur.left == null) { cur.leftThread = true; cur.left = prev; } if (prev != null && prev.right == null) { prev.rightThread = true; prev.right = cur; } prev = cur; cur = cur.right; } } // 中序遍历线索二叉树 public void inOrderTraversal() { if (root == null) return; Node cur = root; while (cur.left != null) { cur = cur.left; } while (cur != null) { System.out.print(cur.data + " "); if (cur.rightThread) { cur = cur.right; } else { cur = cur.right; while (cur != null && !cur.leftThread) { cur = cur.left; } } } System.out.println(); } public static void main(String[] args) { ThreadedBinaryTree tree = new ThreadedBinaryTree(); tree.root = new Node(1); tree.root.left = new Node(2); tree.root.right = new Node(3); tree.root.left.left = new Node(4); tree.root.left.right = new Node(5); tree.root.right.left = new Node(6); tree.root.right.right = new Node(7); tree.inOrderThread(); tree.inOrderTraversal(); } } ``` 在上述程序中,我们定义了一个`Node`类来表示二叉树的节点。每个节点包含数据、左右子树指针和左右线索指针。我们还定义了一个`ThreadedBinaryTree`类来表示线索二叉树。该类包含一个根节点和两个方法:`inOrderThread()`和`inOrderTraversal()`。`inOrderThread()`方法用于将二叉树线索化,即在每个节点的左右子树指针上添加线索。该方法使用中序遍历的方式将二叉树遍历,并在遍历过程中添加线索。`inOrderTraversal()`方法用于中序遍历线索二叉树,并输出每个节点的数据。 在`main()`方法中,我们创建了一个示例二叉树,并调用`inOrderThread()`方法将其线索化。然后,我们调用`inOrderTraversal()`方法中序遍历线索二叉树,并输出每个节点的数据。输出结果应该为:`4 2 5 1 6 3 7`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值