线索化二叉树
Posted bingbug
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线索化二叉树相关的知识,希望对你有一定的参考价值。
线索化二叉树的特点是:每一个节点都有前驱和后继节点(第一个和最后一个除外)所以查找某一节点会很容易
缺点:也很明显就是在插入新节点和删除时过于麻烦,实际应用需自己取舍
public class ThreadedBinaryTreeDemo { public static void main(String[] args) { HeroNode root = new HeroNode(1, "tom"); HeroNode node2 = new HeroNode(3, "jack"); HeroNode node3 = new HeroNode(6, "smith"); HeroNode node4 = new HeroNode(8, "mary"); HeroNode node5 = new HeroNode(10, "king"); HeroNode node6 = new HeroNode(14, "dim"); root.setLeft(node2); root.setRight(node3); node2.setLeft(node4); node2.setRight(node5); node3.setLeft(node6); // node2.setParent(root); // node3.setParent(root); // node4.setParent(node2); // node5.setParent(node2); // node6.setParent(node3); ThreadedBinaryTree threadedBinaryTree = new ThreadedBinaryTree(); threadedBinaryTree.setRoot(root); threadedBinaryTree.threadedNodes(); //8 10 3 14 6 1 HeroNode leftNode = node4.getLeft(); HeroNode rightNode = node4.getRight(); // System.out.println(leftNode);//null // System.out.println(rightNode);//10 threadedBinaryTree.threadedList(); } } class ThreadedBinaryTree { private HeroNode root; //指向当前节点的前驱节点 private HeroNode pre = null; public void setRoot(HeroNode root) { this.root = root; } //重载 public void threadedNodes() { this.threadedNodes(root); } public void threadedNodes(HeroNode node) { if (node == null) { return; } if (node.getLeft() == null) { node.setLeft(pre); node.setLeftType(1); } //后继节点 if (pre != null && pre.getRight() == null) { //让前驱节点的右指针指向当前节点 pre.setRight(node); //修改前驱节点的右指针类型 pre.setRightType(1); } //让当前节点是下一个节点的前驱节点 pre = node; if (node.getLeftType()!=1){ threadedNodes(node.getLeft()); } if (node.getRightType()!=1){ threadedNodes(node.getRight()); } // //线索化左子树 // 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()); // threadedNodes(node.getLeft()); // threadedNodes(node.getRight()); // if (node.getLeft() == null) { // node.setLeft(pre); // node.setLeftType(1); // } // //后继节点 // if (pre != null && pre.getRight() == null) { // //让前驱节点的右指针指向当前节点 // pre.setRight(node); // //修改前驱节点的右指针类型 // pre.setRightType(1); // } // //让当前节点是下一个节点的前驱节点 // pre = node; } //遍历线索化二叉树 public void threadedList() { HeroNode node = root; while (node != null) { while (node.getLeftType() == 0) { System.out.println(node); node = node.getLeft(); } System.out.println(node); node = node.getRight(); } // while (node != null) { // 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(); // } // while ( node != null && node.getLeftType() == 0 ) { // node = node.getLeft(); // } // while (node != null) { // if (node.getRightType() == 1) { // System.out.println(node); // pre = node; // node = node.getRight(); // } else { // //如果上个处理的节点是当前节点的右节点 // if (node.getRight() == pre) { // System.out.println(node); // if (node == root) { // return; // } // pre = node; // node = node.getParent(); // } else { //如果从左节点的进入则找到有子树的最左节点 // node = node.getRight(); // while ( node != null && node.getLeftType() == 0 ) { // node = node.getLeft(); // } // } // } // } } //前 public void preOrder() { if (this.root != null) { this.root.preOrder(); } else { System.out.println("null"); } } //中 public void infixOrder() { if (this.root != null) { this.root.infixOrder(); } else { System.out.println("null"); } } //后 public void postOrder() { if (this.root != null) { this.root.postOrder(); } else { System.out.println("null"); } } //查找 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 void delNode(int no) { if (root != null) { if (root.getNo() == no) { root = null; } else { root.delNode(no); } } else { System.out.println("空树"); } } public void del(int no) { if (root != null) { if (root.getNo() == no) { root = null; } else { root.del(no); } } else { System.out.println("空树"); } } } class HeroNode { private int no; private String name; private HeroNode left; private HeroNode right; private HeroNode parent; public HeroNode getParent() { return parent; } public void setParent(HeroNode parent) { this.parent = parent; } private int leftType;//0 指向左子树 1 指向前驱节点 private int rightType;//0 指向右子树 1 指向后继节点 public HeroNode(int no, String name) { this.no = no; this.name = name; } 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; } 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; } @Override public String toString() { return "HeroNode[" + "no=" + no + ", name=‘" + name + ‘‘‘ + ‘]‘; } /* 是什么遍历看什么时候输出父节点 */ //前序遍历 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; } 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); } if (this.right != null) { this.right.delNode(no); } } public void del(int no) { if (this.left != null && this.left.no == no) { this.left = null; return; } if (this.right != null && this.right.no == no) { if (this.right.left != null && this.right.right != null) { this.right.left.right = this.right.right; this.right = this.right.left; return; } else { this.right = null; return; } } if (this.left != null) { this.left.delNode(no); } if (this.right != null) { this.right.delNode(no); } } }
以上是关于线索化二叉树的主要内容,如果未能解决你的问题,请参考以下文章