线索化二叉树

(1)概念:普通的二叉树遍历的时候左右指针并没有很好地利用,要完全利用每个结点的左右指针,就必须用到线索化二叉树。在遍历过程中使二叉树变成线索化二叉树的过程称为二叉树的线索化。在n个结点的二叉树中,有n+1个空链域,利用这些空链域存储某次遍历中结点的前续和后继结点。因为在特定的遍历方式下结点的遍历顺序是一定的。

(2)结点:

public class ClueNode {
	private int no;
	private String name;
	private ClueNode left;
	private ClueNode right;
	/*
	 * 分别用两个标识符来表示是否有前驱和后继(在遍历中)
	 * 如果没有的化表明指向树结构中的左右子树
	 */
	private int flgLeft;
	private int flgRight;
	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 ClueNode getLeft() {
		return left;
	}
	public void setLeft(ClueNode left) {
		this.left = left;
	}
	public ClueNode getRight() {
		return right;
	}
	public void setRight(ClueNode right) {
		this.right = right;
	}
	public int getFlgLeft() {
		return flgLeft;
	}
	public void setFlgLeft(int flgLeft) {
		this.flgLeft = flgLeft;
	}
	public int getFlgRight() {
		return flgRight;
	}
	public void setFlgRight(int flgRight) {
		this.flgRight = flgRight;
	}
	@Override
	public String toString() {
		return "ClueNode [no=" + no + ", name=" + name + "]";
	}
	//删除结点
	public void delNode(int no) {
		if ((this.left!=null)&&(this.left.getNo()==no)) {
			this.setLeft(null);return;
		}
		if ((this.right!=null)&&(this.right.getNo()==no)) {
			this.right=null;
		}
		/*
		 * 注意递归的时候先判断是否为空
		 */
		if (this.left!=null) {
			this.left.delNode(no);
		}
		if (this.right!=null) {
			this.right.delNode(no);
		}
	}
	//使用中序遍历所有
	public void midList() {
		if (this.left!=null) {
			this.left.midList();
		}
		System.out.println(this);
		if (this.right!=null) {
			this.right.midList();
		}
	}
	//使用中序根据编号查找结点
	public ClueNode seaNode(int no) {
		ClueNode node=null;
		if (this.left!=null) {
			node=this.left.seaNode(no);
			if (node!=null) {
				return node;
			}
		}
		if (this.no==no) {
		return this;	
		}
		if (this.right!=null) {
			node=this.right.seaNode(no);
			if (node!=null) {
				return node;
			}
		}
		return node;
	}
}

(3)线索二叉树的实现以及对其线索化

public class ClueBinaryTree {
	private ClueNode root;
	private ClueNode pre=null;
	//当前结点的前驱
	public ClueBinaryTree(ClueNode root) {
		this.root=root;
	}
	//这个函数进行线索化
	public void clue(ClueNode node) {
		//判断当前结点是否为空
		if (node==null) {
			return;
		}
		//先从最左边的子树开始,遇到空的了自然会由上面的if语句返回
		clue(node.getLeft());
		//找到最左边没有前驱的结点,添加前驱
		if (node.getLeft()==null) {
			node.setLeft(pre);
			node.setFlgLeft(1);
		}
		//处理当前结点的后继,因为现在是线索化左子树
		//所以应该都有后继,可以pre下手,因为pre的后继就是node
		if((pre!=null)&&(pre.getRight()==null)) {
			pre.setRight(node);
			pre.setFlgRight(1);
		}
		//直接把node给pre,相当于继续下一个结点
		pre=node;
		//再对右子树遍历
		clue(node.getRight());
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值