一、定义
对二叉树的节点加上线索的二叉树,叫做线索二叉树
二、原理
从百度中查到定义,对于n个结点的二叉树,在二叉链存储结构中有n+1个空链域,利用这些空链域存放在某种遍历次序下该结点的前驱结点和后继结点的指针,这些指针称为线索,加上线索的二叉树称为线索二叉树。
这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded BinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。
注意:线索链表解决了无法直接找到该结点在某种遍历序列中的前驱和后继结点的问题,解决了二叉链表找左、右孩子困难的问题。
二叉树的遍历本质上是将一个复杂的非线性结构转换为线性结构,使每个结点都有了唯一前驱和后继(第一个结点无前驱,最后一个结点无后继)
三、代码
public static void main(String[] args) { //left指向左子树,也可能指向前驱节点;right节点指向右子树,也可能指向后继节点 Node root = new Node(1,"jack"); Node node2 = new Node(2,"tom"); Node node3 = new Node(3,"mary"); Node node4 = new Node(4,"smith"); Node node5 = new Node(5,"dim"); Node node6 = new Node(6,"king"); root.setLeft(node2); root.setRight(node3); node2.setLeft(node4); node2.setRight(node5); node3.setLeft(node6); ThreadedBinary threadedBinary = new ThreadedBinary(root); threadedBinary.midThreadedNode(); System.out.println(node5.getLeft()); System.out.println(node5.getRight()); System.out.println("线索化方式遍历二叉树"); threadedBinary.list(); } } class ThreadedBinary{ private Node root; private Node pre; public ThreadedBinary(Node root){ this.root = root; } //中序线索二叉树遍历->线性遍历,速度快一些 public void list() { Node node = root; while(node != null) { //循环查找leftType等于1,随着遍历而变化 while(node.getLeftType() == 0) { node = node.getLeft(); } System.out.println(node); //如果当前节点的后指针指向右指针,一直输出 while(node.getRightType() == 1) { //获取到当前节点的后继接待你 node = node.getRight(); System.out.println(node); } //替换遍历的节点 node = node.getRight(); } } public void midThreadedNode() { midThreadedNode(root); } public void midThreadedNode(Node node) { if(node == null) { return; } //1.先线索化左子树 midThreadedNode(node.getLeft()); //2.线索化当前节点 if(node.getLeft() == null) {//指向前驱节点 node.setLeft(pre); node.setLeftType(1); } //处理根节点时,才会把前一个节点(左或者右叶子节点)与根节点绑定 if(pre != null && pre.getRight() == null) {//处理后继节点 pre.setRight(node); pre.setRightType(1); } pre = node; //3.线索化右子树 midThreadedNode(node.getRight()); } } class Node { private int id; private String name; private Node left; private Node right; //0是左子树,1是前驱节点 private int leftType; //0是右子树,1是后继节点 private int rightType; public Node(int id,String name) { this.id = id; this.name = name; } @Override public String toString() { return "Node [id=" + id + ", name=" + name + ", leftType=" + leftType + ", rightType=" + rightType + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } 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 getLeftType() { return leftType; } public void setLeftType(int leftType) { this.leftType = leftType; } public int getRightType() { return rightType; } public void setRightType(int rightType) { this.rightType = rightType; } |