赞
踩
树示意图:
结点
根节点
父节点
子节点
叶子结点(没有子节点的结点)
结点的权(结点值)
路劲(从root结点找到该节点的路线)
层
子树
树的高度(最大层数)
森林(多棵二叉树构成森林)
树有很多种,每个结点最多只能有两个子节点的一种形式称为二叉树。
二叉树的字子节点分为左结点和右结点
示意图:
如果 该二叉树的所有叶子结点都在最后一层,并且结点总数为:2n-1,n为层数,则我们称之为满二叉树。
如果该二叉树的所有叶子结点都在最后一层或者倒数第二层,而且最后一层的叶子结点在左边连续,倒数第二层的叶子结点在右边连续,我们称之为完全二叉树。
/* file:BinaryTreeDemo.java */ class BinaryTreeDemo{ public static void main(String[] args){ //先构建一颗二叉树 BinaryTree binaryTree = new BinaryTree(); //创建常见需要的结点 HeroNode root = new HeroNode(1, "宋江"); HeroNode node2 = new HeroNode(2, "吴用"); HeroNode node3 = new HeroNode(3, "卢俊义"); HeroNode node4 = new HeroNode(4, "林冲"); HeroNode node5 = new HeroNode(5, "关胜"); binaryTree.setRoot(root); // 说明:这里我们先手动创建二叉树吗,后面再使用递归的方式创建二叉树 root.setLeft(node2); root.setRight(node3); node3.setRight(node4); node3.setLeft(node5); // 测试遍历 System.out.println("测试遍历~~~"); System.out.println("前序遍历:"); binaryTree.preOder(); // 1,2,3,5,4 System.out.println("中序遍历:"); binaryTree.infixOrder(); // 2,1,5,3,4 System.out.println("后序遍历:"); binaryTree.position(); // 2,5,4,3,1 } } // 定义二叉树 class BinaryTree{ private HeroNode root; public void setRoot(HeroNode root){ this.root = root; } // 前序遍历 public void preOder(){ if(this.root != null){ this.root.preOrder(); }else{ System.out.println("二叉树为空,无法遍历!!!"); } } // 中序遍历 public void infixOrder(){ if(this.root != null){ this.root.infixOrder(); }else{ System.out.println("二叉树为空,无法遍历!!!"); } } // 后序遍历 public void position(){ if(this.root != null){ this.root.position(); }else{ System.out.println("二叉树为空,无法遍历!!!"); } } } // 先创建结点 class HeroNode{ private int no; private String name; private HeroNode left; private HeroNode right; 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; } @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 position(){ // 遍历左子节点 if(this.left != null){ this.left.position(); } // 遍历右子节点 if(this.right != null){ this.right.position(); } // 输出当前结点 System.out.println(this); } }
要求
/* file:BinaryTreeDemo.java */ class BinaryTreeDemo{ public static void main(String[] args){ //先构建一颗二叉树 BinaryTree binaryTree = new BinaryTree(); //创建常见需要的结点 HeroNode root = new HeroNode(1, "宋江"); HeroNode node2 = new HeroNode(2, "吴用"); HeroNode node3 = new HeroNode(3, "卢俊义"); HeroNode node4 = new HeroNode(4, "林冲"); HeroNode node5 = new HeroNode(5, "关胜"); binaryTree.setRoot(root); // 说明:这里我们先手动创建二叉树吗,后面再使用递归的方式创建二叉树 root.setLeft(node2); root.setRight(node3); node3.setRight(node4); node3.setLeft(node5); // // 测试遍历 // System.out.println("测试遍历~~~"); // System.out.println("前序遍历:"); // binaryTree.preOder(); // 1,2,3,5,4 // System.out.println("中序遍历:"); // binaryTree.infixOrder(); // 2,1,5,3,4 // System.out.println("后序遍历:"); // binaryTree.position(); // 2,5,4,3,1 // 测试查找 System.out.println("测试查找~~~"); int num = 5; //查找目标 HeroNode resNode; //中序查找 System.out.println("前序查找:"); resNode = binaryTree.preOrderSearch(num); if(resNode != null){ System.out.printf("找到了,信息为: no = %d,name = %s\n",resNode.getNo(), resNode.getName()); }else{ System.out.printf("没有找到 no = %d 的英雄!\n",num); } //中序查找 System.out.println("中序查找:"); resNode = binaryTree.infixOrderSearch(num); if(resNode != null){ System.out.printf("找到了,信息为: no = %d,name = %s\n",resNode.getNo(), resNode.getName()); }else{ System.out.printf("没有找到 no = %d 的英雄!\n",num); } //中序查找 System.out.println("后续查找:"); resNode = binaryTree.positOrderSearch(num); if(resNode != null){ System.out.printf("找到了,信息为: no = %d,name = %s\n",resNode.getNo(), resNode.getName()); }else{ System.out.printf("没有找到 no = %d 的英雄!\n",num); } } } // 定义二叉树 class BinaryTree{ private HeroNode root; public void setRoot(HeroNode root){ this.root = root; } // // 前序遍历 // public void preOder(){ // if(this.root != null){ // this.root.preOrder(); // }else{ // System.out.println("二叉树为空,无法遍历!!!"); // } // } // // 中序遍历 // public void infixOrder(){ // if(this.root != null){ // this.root.infixOrder(); // }else{ // System.out.println("二叉树为空,无法遍历!!!"); // } // } // // 后序遍历 // public void position(){ // if(this.root != null){ // this.root.position(); // }else{ // System.out.println("二叉树为空,无法遍历!!!"); // } // } // 前序查找 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 positOrderSearch(int no){ if(root != null){ return root.positOrderSearch(no); }else{ return null; } } } // 先创建结点 class HeroNode{ private int no; private String name; private HeroNode left; private HeroNode right; 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; } @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 position(){ // // 遍历左子节点 // if(this.left != null){ // this.left.position(); // } // // 遍历右子节点 // if(this.right != null){ // this.right.position(); // } // // 输出当前结点 // System.out.println(this); // } // 前序遍历查找 /* * * @param no 查找no * @return 如果找到就返回Node,如果没有找到就返回 null */ public HeroNode preOrderSearch(int no){ System.out.println("进入前序查找~"); // 比较当前结点是不是要找的结点 if(this.no == no){ return this; } HeroNode resNode = null; // 1.判断当前结点的左子节是否为空,如果不为空,则递归前序查找 // 2.如果左递归前序查找,找到结点,返回结点 if(this.left != null){ resNode = this.left.preOrderSearch(no); } if(resNode != null){ return resNode; } // 1.左递归前序查找,找到结点,则返回,否则继续判断, // 2.判断当前的结点的右子结点是否为空,如果不空,则继续向右递归前序查找 if(this.right != null){ resNode = this.right.preOrderSearch(no); } return resNode; } // 中序遍历查找 public HeroNode infixOrderSearch(int no){ HeroNode resNode = null; // 1.判断当前结点的左子节是否为空,如果不为空,则递归中序查找 if(this.left != null){ resNode = this.left.infixOrderSearch(no); } if(resNode != null){ return resNode; } System.out.println("进入中序查找~"); // 判断当前结点是否为查找结点,是返回,否则继续 if(this.no == no){ return this; } // 右递归中序查找 if(this.right != null){ resNode = this.right.infixOrderSearch(no); } return resNode; } // 后续遍历查找 public HeroNode positOrderSearch(int no){ HeroNode resNode = null; // 左递归后续查找 if(this.left != null){ resNode = this.left.positOrderSearch(no); } if(resNode != null){ return resNode; } // 右递归后序查找 if(this.right != null){ resNode = this.right.positOrderSearch(no); } if(resNode != null){ return resNode; } System.out.println("进入后续查找~"); // 判断当前结点是否为查找结点,是返回,否则继续 if(this.no == no){ return this; } return resNode; } }
/* file:BinaryTreeDemo.java */ // 在 HeroNode 类中增加代码 // 递归删除指定结点 // 1.如果删除的结点为叶子结点,则删除该结点 // 2.如果删除结点不是叶子结点,则删除该子树 public void delNode(int no){ // 思路: /* * 1.因为我们的二叉树是单向的,所以我们是判断当前结点的子结点是否需要删除结点,而不能去判断当前这个结点是不是需要删除结点, 2.如果当前结点的左子结点不为空,并且左子结点就是要删除结点,就将this.left=nul1;并且就返回(结束递归删除) 3.如果当前结点的右子结点不为空,并且右子结点就是要删除结点,就将this.right=null;并且就返回(结束递归删除) 4.如果第2和第3步没有删除结点,那么我们就需要向左子树进行递归删除 5.如果第4步也没有删除结点,则应当向右子树进行递归删除。 */ // 2.如果当前结点的左子结点不为空,并且左子结点就是要删除结点,就将this.left=nul1;并且就返回(结束递归删除) if(this.left != null && this.left.no == no){ this.left = null; return; } // 3.如果当前结点的右子结点不为空,并且右子结点就是要删除结点,就将this.right=null;并且就返回(结束递归删除) if(this.right != null && this.right.no == no){ this.right = null; return; } // 4.如果第2和第3步没有删除结点,那么我们就需要向左子树进行递归删除 if(this.left != null){ this.left.delNode(no); } // 5.如果第4步也没有删除结点,则应当向右子树进行递归删除。 if(this.right != null){ this.right.delNode(no); } } // 在 BinaryTree 类中增加代码 // 删除结点 public void delNode(int no){ // 判断root结点是否为空 if(this.root != null){ // 这里马上就要判断删除结点是否为root结点,否则后面就没机会了 if(this.root.getNo() == no){ this.root = null; return; }else{ this.root.delNode(no); } }else{ System.out.println("空树,无法进行删除结点操作!!!"); } } // 在 BinaryTreeDemo类 main方法中增加代码 // 测试删除结点 System.out.println("删除前,进行前序遍历"); binaryTree.preOder(); // binaryTree.delNode(5); binaryTree.delNode(3); System.out.println("删除后,前序遍历:"); binaryTree.preOder();
基本说明
要求
二叉树存储的特点:
顺序存储二叉树的遍历
/* file:ArrBinaryTreeDemo.java */ public class ArrBinaryTreeDemo{ public static void main(String[] args){ int[] arr = {1,2,3,4,5,6,7}; // 创建一个ArrBinaryTree ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr); System.out.print("前序遍历:"); // arrBinaryTree.preOrder(0); //1,2,4,5,3,6, //使用重载的前序遍历方法,这样可以省去传0参的步骤,使代码更加整洁 arrBinaryTree.preOrder(); System.out.println(); System.out.print("中序遍历:"); // arrBinaryTree.infixOrder(0); //4,2,5,1,6,3,7 arrBinaryTree.infixOrder(); System.out.println(); System.out.print("后续遍历:"); // arrBinaryTree.followUp(0); //4,5,2,6,7,3,1 arrBinaryTree.followUp(); System.out.println(); } } class ArrBinaryTree{ private int[] arr; //存储二叉树数据结点的数组 public ArrBinaryTree(int[] arr){ this.arr = arr; } // 重载 preOder() public void preOrder(){ this.preOrder(0); } // 重载 infixOrder() public void infixOrder(){ this.infixOrder(0); } // 重载 followUp() public void followUp(){ this.followUp(0); } //编写一个方法完成顺序存储二叉树的前序遍历 /** * * @param index 数组的下标 */ public void preOrder(int index){ // 如果数组为空,或者arr.length = 0 if(arr == null || arr.length == 0){ System.out.println("数组为空,不能按照二叉树的前序遍历!!!"); } //输出当前这个元素 System.out.print(arr[index]); //向左递归遍历 if(index * 2 + 1 < arr.length){ preOrder(index * 2 + 1); } //向右递归遍历 if(index * 2 + 2 < arr.length){ preOrder(index * 2 + 2); } return; } //编写一个方法完成顺序存储二叉树的中序遍历 /** * * @param index 数组的下标 */ public void infixOrder(int index){ if(arr == null && arr.length == 0){ System.out.println("数组为空,不能按照二叉树的中序遍历!!!"); } if(index * 2 + 1 < arr.length){ infixOrder(index * 2 + 1); } System.out.print(arr[index]); if(index * 2 + 2 < arr.length){ infixOrder(index * 2 + 2); } return; } //编写一个方法完成顺序存储二叉树的后续遍历 /** * * @param index 数组的下标 */ public void followUp(int index){ if(arr == null && index == arr.length){ System.out.println("数组为空,不能按照二叉树的中序遍历!!!"); } if(index * 2 + 1 < arr.length){ followUp(index * 2 + 1); } if(index * 2 + 2 < arr.length){ followUp(index * 2 + 2); } System.out.print(arr[index]); } }
/* file:ThreadedBinaryTreeDemo.java */ 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"); extracted(root, node2); root.setRight(node3); extracted(node2, node4); node2.setRight(node5); extracted(node3, node6); //测试线索化 ThreadeBinaryTree threadeBinaryTree = new ThreadeBinaryTree(); threadeBinaryTree.setRoot(root); threadeBinaryTree.threadedNodes(); // 测试:以10号结点测试 HeroNode leftNode = node5.getLeft(); HeroNode rightNode = node5.getRight(); System.out.println("10号结点的前驱结点是= " + leftNode); //3 System.out.println("10号结点的后继结点是= " + rightNode); //1 // 当线索化二叉树后,再用原来的遍历方式会出现问题 // 因为原来的二叉树遍历是通过结点左右子节点为空来进行的 // 线索化后的二叉树将结点的左右指针都有值了 // threadeBinaryTree.infixOrder(); System.out.println("使用线索化的方式遍历 线索化二叉树"); threadeBinaryTree.threadedList(); // 8,3,10,1,14,6 } private static void extracted(HeroNode node2, HeroNode node4) { node2.setLeft(node4); } } // 定义 ThreadeBinaryTree 实现了线索化功能的二叉树 class ThreadeBinaryTree{ private HeroNode root; // 为了实现线索化,需要创建要给指向当前结点的前驱结点的指针 // 在递归进行线索化时,pre 总是保留前一个结点 private HeroNode pre = null; public void setRoot(HeroNode root){ this.root = root; } // 重载 threadedNodes 方法 public void threadedNodes(){ this.threadedNodes(root); } // 遍历线索化二叉树的方法 public void threadedList(){ // 定义一个变量,临时存储当前遍历的结点,从root开始 HeroNode node = root; while(node != null){ // 循环遍历找到leftType = 1 的这个结点,第一个找到的就是 8 结点 // 后面随着遍历而变化,因当leftType = 1 时,说明该结点是按照线索化 // 处理后的有效结点 while(node.getleftType() == 0){ node = node.getLeft(); } // 打印当前结点 System.out.println(node); // 如果当前结点的右指针指向的是后继结点,就一直输出 while(node.getRitghtType() == 1){ node = node.getRight(); System.out.println(node); } // 替换这个遍历的结点 node = node.getRight(); } } // 编写对二叉树进行对中序线索化的方法 /* * * @param node 就是当前需要线索化的结点 */ public void threadedNodes(HeroNode node) { // 如果node == null,就不能线索化 if(node == null){ return; } // (一)先线索化左子树 threadedNodes(node.getLeft()); // (二)线索化当前结点 // 处理当前结点的前驱结点 if(node.getLeft() == null){ // 让当前结点的左指针指向前驱结点 node.setLeft(pre); // 修改当前结点的左指针类型,指向前驱结点 node.setleftType(1); } // 处理后继结点 if(pre != null && pre.getRight() == null){ // 让前驱结点的右指针指向当前结点 pre.setRight(node); // 修改前驱结点的右指针类型 pre.setRitghtType(1); } // !!! 没处理一个结点后,让当前结点是下一个结点的前驱结点 pre = node; // (三)在线索化右子树 threadedNodes(node.getRight()); } // 删除结点 public void delNode(int no){ // 判断root结点是否为空 if(this.root != null){ // 这里马上就要判断删除结点是否为root结点,否则后面就没机会了 if(this.root.getNo() == no){ this.root = null; return; }else{ this.root.delNode(no); } }else{ System.out.println("空树,无法进行删除结点操作!!!"); } } // 前序遍历 public void preOder(){ if(this.root != null){ this.root.preOrder(); }else{ System.out.println("二叉树为空,无法遍历!!!"); } } // 中序遍历 public void infixOrder(){ if(this.root != null){ this.root.infixOrder(); }else{ System.out.println("二叉树为空,无法遍历!!!"); } } // 后序遍历 public void position(){ if(this.root != null){ this.root.position(); }else{ System.out.println("二叉树为空,无法遍历!!!"); } } // 前序查找 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 positOrderSearch(int no){ if(root != null){ return root.positOrderSearch(no); }else{ return null; } } } // 先创建结点 class HeroNode{ private int no; private String name; private HeroNode left; private HeroNode right; // 说明 // 1.如果leftType == 0 表示指向的是左子树,如果1则表示指向前驱结点 // 2.如果rightType == 0 表示指向的是右子树,如果为1表示指向后继结点 private int leftType; private int ritghtType; public int getleftType(){ return leftType; } public void setleftType(int leftType){ this.leftType = leftType; } public int getRitghtType() { return ritghtType; } public void setRitghtType(int ritghtType) { this.ritghtType = ritghtType; } 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; } @Override public String toString() { return "HeroNode [no="+ no +",name="+ name +"]"; } // 递归删除指定结点 // 1.如果删除的结点为叶子结点,则删除该结点 // 2.如果删除结点不是叶子结点,则删除该子树 public void delNode(int no){ // 思路: /* * 1.因为我们的二叉树是单向的,所以我们是判断当前结点的子结点是否需要删除结点,而不能去判断当前这个结点是不是需要删除结点, 2.如果当前结点的左子结点不为空,并且左子结点就是要删除结点,就将this.left=nul1;并且就返回(结束递归删除) 3.如果当前结点的右子结点不为空,并且右子结点就是要删除结点,就将this.right=null;并且就返回(结束递归删除) 4.如果第2和第3步没有删除结点,那么我们就需要向左子树进行递归删除 5.如果第4步也没有删除结点,则应当向右子树进行递归删除。 */ // 2.如果当前结点的左子结点不为空,并且左子结点就是要删除结点,就将this.left=nul1;并且就返回(结束递归删除) if(this.left != null && this.left.no == no){ this.left = null; return; } // 3.如果当前结点的右子结点不为空,并且右子结点就是要删除结点,就将this.right=null;并且就返回(结束递归删除) if(this.right != null && this.right.no == no){ this.right = null; return; } // 4.如果第2和第3步没有删除结点,那么我们就需要向左子树进行递归删除 if(this.left != null){ this.left.delNode(no); } // 5.如果第4步也没有删除结点,则应当向右子树进行递归删除。 if(this.right != null){ this.right.delNode(no); } } // 前序遍历 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 position(){ // 遍历左子节点 if(this.left != null){ this.left.position(); } // 遍历右子节点 if(this.right != null){ this.right.position(); } // 输出当前结点 System.out.println(this); } // 前序遍历查找 /* * * @param no 查找no * @return 如果找到就返回Node,如果没有找到就返回 null */ public HeroNode preOrderSearch(int no){ System.out.println("进入前序查找~"); // 比较当前结点是不是要找的结点 if(this.no == no){ return this; } HeroNode resNode = null; // 1.判断当前结点的左子节是否为空,如果不为空,则递归前序查找 // 2.如果左递归前序查找,找到结点,返回结点 if(this.left != null){ resNode = this.left.preOrderSearch(no); } if(resNode != null){ return resNode; } // 1.左递归前序查找,找到结点,则返回,否则继续判断, // 2.判断当前的结点的右子结点是否为空,如果不空,则继续向右递归前序查找 if(this.right != null){ resNode = this.right.preOrderSearch(no); } return resNode; } // 中序遍历查找 public HeroNode infixOrderSearch(int no){ HeroNode resNode = null; // 1.判断当前结点的左子节是否为空,如果不为空,则递归中序查找 if(this.left != null){ resNode = this.left.infixOrderSearch(no); } if(resNode != null){ return resNode; } System.out.println("进入中序查找~"); // 判断当前结点是否为查找结点,是返回,否则继续 if(this.no == no){ return this; } // 右递归中序查找 if(this.right != null){ resNode = this.right.infixOrderSearch(no); } return resNode; } // 后续遍历查找 public HeroNode positOrderSearch(int no){ HeroNode resNode = null; // 左递归后续查找 if(this.left != null){ resNode = this.left.positOrderSearch(no); } if(resNode != null){ return resNode; } // 右递归后序查找 if(this.right != null){ resNode = this.right.positOrderSearch(no); } if(resNode != null){ return resNode; } System.out.println("进入后续查找~"); // 判断当前结点是否为查找结点,是返回,否则继续 if(this.no == no){ return this; } return resNode; } }
线索化二叉树,各个节点可以通过线型方式遍历,因此无需使用递归方式,这样也提高了遍历的效率。遍历 的次序应当和中序遍历保持一致。
/* file:ThreadedBinaryTreeDemo.java */ // 在 ThreadeBinaryTree类 添加代码 // 遍历线索化二叉树的方法 public void threadedList(){ // 定义一个变量,临时存储当前遍历的结点,从root开始 HeroNode node = root; while(node != null){ // 循环遍历找到leftType = 1 的这个结点,第一个找到的就是 8 结点 // 后面随着遍历而变化,因当leftType = 1 时,说明该结点是按照线索化 // 处理后的有效结点 while(node.getleftType() == 0){ node = node.getLeft(); } // 打印当前结点 System.out.println(node); // 如果当前结点的右指针指向的是后继结点,就一直输出 while(node.getRitghtType() == 1){ node = node.getRight(); System.out.println(node); } // 替换这个遍历的结点 node = node.getRight(); } } // 在 main方法中添加代码 // 当线索化二叉树后,再用原来的遍历方式会出现问题 // 因为原来的二叉树遍历是通过结点左右子节点为空来进行的 // 线索化后的二叉树将结点的左右指针都有值了 // threadeBinaryTree.infixOrder(); System.out.println("使用线索化的方式遍历 线索化二叉树"); threadeBinaryTree.threadedList(); // 8,3,10,1,14,6
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。