线索二叉树模型的建立与遍历
2015-08-03 14:34
447 查看
线索二叉树是在普通二叉树模型上建立线索后的树模型,再建立了线索后我们可以在O(n)的时间内遍历该树,并且很方便的找出某个节点的前驱节点和后继节点,我们的代码首先建立一棵普通的二叉树,然后利用递归的方式建立线索,并且提供一个遍历算法,其中有一些细节是需要我们多加注意的。不多说了,上代码
/** * @author pc * 线索二叉树模型 */ public class ThreadTree { private Node root; private Node pre; private class Node{ private Node left; private Node right; private int data; private int ltag; //ltag=0表示指向左孩子节点,ltag=1表示指向线索即前驱节点 private int rtag; //rtag=0表示指向右孩子节点,rtag=1表示指向线索即后继节点 public Node(int data){ this.left = null; this.right = null; this.data = data; this.ltag =0; this.rtag =0; } 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 getData() { return data; } public void setData(int data) { this.data = data; } public int getLtag() { return ltag; } public void setLtag(int ltag) { this.ltag = ltag; } public int getRtag() { return rtag; } public void setRtag(int rtag) { this.rtag = rtag; } } public ThreadTree(){ root=null; pre=null; } /** * 首先根据一个数组来创建普通二叉树 * * @param a * n+1个数据组成的数组,其中a[0]=-1不参与树的创建,a[1]~a 代表数的节点,a[2*i]是a[i]的左子结点, * a[2*i+1]是右子节点 */ private Node buildTreeByArray(int[] a, int n) { Node[] p = new Node[n + 1]; p[0] = null; for (int i = 1; i <= n; i++) { if (a[i] == -1) { p[i] = null; } else { p[i] = new Node(a[i]); } } for (int i = 1; i <= n / 2; i++) { if (a[i] != -1) { if ((2 * i <= n) && a[2 * i] != -1) { p[i].setLeft(p[2 * i]); } if ((2 * i + 1 <= n) && (a[2 * i + 1] != -1)) { p[i].setRight(p[2 * i + 1]); } } } return p[1]; } /** * 递归的线索化过程 * pre指向前驱节点,p指向当前节点 */ private void Thread(Node p){ if(p!=null){ Thread(p.left); if(p.left==null){ p.ltag=1; p.left=pre; } else{ p.ltag=0; } if(pre.right==null){ pre.rtag=1; pre.right=p; } else{ pre.rtag=0; } pre=p; Thread(p.right); } } /** * 真正建立二叉线索树的函数 * 其中首先建立一棵普通二叉树,然后再对其进行线索化 * 最后返回一个root节点,left指向二叉树的根节点,right指向遍历时的最后一个节点 * @param a * @param n */ public Node createThreadTree(int[] a, int n){ Node bt=buildTreeByArray(a, n); root=new Node(0); root.ltag=0; root.rtag=1; root.right=bt; //这一步不能少,否则线索化时会把root节点的右指针指向遍历时的第一个节点 if(bt==null){ root.left=root; } else{ root.left=bt; pre=root; Thread(bt); pre.right=root; pre.rtag=1; root.right=pre; } return root; } /** * 对中序线索二叉树进行遍历 * @param root */ public void ThInOrder(Node root){ Node p=root.left; while(p!=root){ //注意现在空树的条件是p==root即root.left=root while(p.ltag==0) //找出最左下方节点 p=p.left; System.out.print(p.data+" "); while(p.rtag==1&&p.right!=root){ //当访问完最左下节点后顺着右线索访问即可 p=p.right; System.out.print(p.data+" "); } p=p.right; } } public static void main(String args[]){ int[] a={-1,2,4,6,7,8,9,-1,12,13}; ThreadTree thread=new ThreadTree(); Node node=thread.createThreadTree(a, 9); thread.ThInOrder(node); } }
相关文章推荐
- 电影节 SDUT 2797
- Help Me with the Game(POJ--2996
- VISIBLE INVISIBLE GONE
- ios自动布局
- My97DatePicker用法及下载
- python安装error: Unable to find vcvarsall.bat
- struts--token防止表单重复提交(源码分析)
- Qt的二维图形
- DevExpress ChartControl 设置它的标题
- shell脚本之间互相调用
- p3145 汉诺塔游戏
- acp,amv:command not found
- 13.Roman to Integer (罗马数字转成整数)
- Cent Savings (DP)
- 怎么将Word转换成PDF的方法分享
- poj 1860 Currency Exchange (最短路,Bellman-Ford算法)
- DataGridView 某一列单元格内容居中显示
- Linux 任务后台运行
- codeforces 545C C. Woodcutters(dp+二分)
- 15-07-22 数据库--存储过程、触发器