(学习java)线索二叉树的实现以及遍历

来源:互联网 发布:tm商标域名 编辑:程序博客网 时间:2024/06/07 16:42
//线索二叉树的实现public class ThreadBinTree<T> {// 定义结点类class TreeNode {private Object data;private TreeNode lchild;// 判断左孩子是否为线索private boolean ltag;private TreeNode rchild;// 判断右孩子是否为线索private boolean rtag;public TreeNode() {}public TreeNode(Object data) {this.data = data;lchild = null;ltag = false;rchild = null;rtag = false;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public TreeNode getLchild() {return lchild;}public void setLchild(TreeNode lchild) {this.lchild = lchild;}public boolean isLtag() {return ltag;}public void setLtag(boolean ltag) {this.ltag = ltag;}public TreeNode getRchild() {return rchild;}public void setRchild(TreeNode rchild) {this.rchild = rchild;}public boolean isRtag() {return rtag;}public void setRtag(boolean rtag) {this.rtag = rtag;}}// 根结点private TreeNode root;// 结点个数private int size;// 线索化时记录前一个结点private TreeNode preNode;//定义头结点private TreeNode head;// 获取根结点public TreeNode getRoot() {return root;}// 建立二叉树public ThreadBinTree(T[] data) {this.size = data.length;this.root = createBinTree(data, 1);}public TreeNode createBinTree(T[] data, int index) {if (index > data.length) {return null;}TreeNode node = new TreeNode(data[index - 1]);TreeNode left = createBinTree(data, 2 * index);TreeNode right = createBinTree(data, 2 * index + 1);node.setLchild(left);node.setRchild(right);return node;}// 先初始化前驱结点,然后中序线索化二叉树public void inOrderThread(TreeNode node){//定义头结点,将preNode初始化为头结点head = new TreeNode();head.rtag = true;head.rchild = null;if(root == null){head.lchild = null;}else{//头结点左孩子默认连接根结点head.lchild = node;preNode = head;//中序线索遍历二叉树inThread(node);//遍历完后.preNode指向最后一个结点,将他右孩子指向头结点preNode.rtag = true;preNode.rchild = head;head.rchild = preNode;}}// 中序线索化二叉树public void inThread(TreeNode node) {if (node == null) {return;}// 线索化左子树inThread(node.lchild);// 假设前驱结点存在// 如果左孩子为空,则将ltag置为true,并指向前驱结点if (null == node.lchild) {node.ltag = true;node.lchild = preNode;}// 如果前驱的右孩子为空 ,则将rtag置为true,并指向后继结点if (preNode != null && null == preNode.rchild) {preNode.rtag = true;preNode.rchild = node;}preNode = node;// 线索化右子树inThread(node.rchild);}// 中序遍历线索二叉树public void inThreadList(TreeNode node) {// 寻找到中序遍历开始的结点,最左边的结点while (node != null && !node.ltag) {node = node.lchild;}while (node != null) {System.out.print(node.data + " ");// 如果rtag为true,则node的右孩子指向后继结点if (node.rtag) {node = node.rchild;//最后一个结点指向定义的头结点,故当node指向头结点时,二叉树已经完全遍历,退出方法if(node == head){return;}} else {node = node.rchild;//如果node的右子树不是线索,则先找到改子树下的最左孩子,所以看ltag是否为线索while (node != null && !node.ltag) {node = node.lchild;}}}}//中序遍历线索二叉树public void inPreThreadList(TreeNode node){//找到最后遍历的结点 while(node!=null&&!node.rtag){node = node.rchild;}while(node!=null){System.out.print(node.data + " ");if(node.ltag){node = node.lchild;if(node == head){return;}}else{node = node.lchild;while(node!=null&&!node.rtag){node = node.rchild;}}}}}
测试类
/* * A * BC * D      E   FG *  *  * */public class ThreadDemo {public static void main(String[] args) {Character[] data = {'A','B','C','D','E','F','G'};ThreadBinTree<Character> tb = new ThreadBinTree<Character>(data);tb.inOrderThread(tb.getRoot());System.out.print("中序遍历按后继结点遍历结果: ");tb.inThreadList(tb.getRoot());System.out.println();System.out.print("中序遍历按前驱结点遍历结果: ");tb.inPreThreadList(tb.getRoot());}}