二叉树的基本操作,遍历,子结构,镜像,构建
来源:互联网 发布:圆方软件论坛 编辑:程序博客网 时间:2024/06/10 19:24
总结了二叉树的一些基本操作,包括
- 1)判断给定两个序列,一个作为前序,一个作为中序,是否可以构成一棵二叉树,测试用例:前序:{1,2,4,7,3,10,6,8}中序: {4,7,2,1,10,3,8,6} —-public BinaryTreeNode ConstructCore(int[] Preorder,int[] Inorder,int startPreorder,int endPreorder,int startInorder,int endInorder);
- 2)树的前序递归遍历—public void printfBinaryTree(BinaryTreeNode node);
- 3)树的非递归前序遍历—public void printfBinaryTreeNotRecurision(BinaryTreeNode node);
- 4)树的中序递归遍历—printfBinaryTreeByInOrder(BinaryTreeNode node);
- 5)树的非递归中序遍历—public void printfBinaryTreeInOrderNotRecurision(BinaryTreeNode node);
- 6)树的后序递归遍历—public void printfBinaryTreeLastOrder(BinaryTreeNode node);
- 7)树的非递归后序遍历—public void printfBinaryTreeLastOrderNotRecurision(BinaryTreeNode node);
- 8)树的层次遍历—-public void printfBinaryFromTopToBottom(BinaryTreeNode node)
- 9)查找树的子结构—boolean HasSubTree(BinaryTreeNode treeA,BinaryTreeNode treeB);
- 10)打印树的镜像—public void MirrorRecursively(BinaryTreeNode tree)
- 11)判断指定序列是否是一个二叉排序树的后序遍历—public boolean verfiySequenceOfBST(int[] sequence);
- 12)查找二叉树的路径和与给定值相等的路径—FindPath(BinaryTreeNode pRoot,int expectedSum);
package findKeyInArray;import java.util.Arrays;import java.util.Queue;import java.util.Stack;import java.util.Vector;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;class BinaryTreeNode{ int m_value; BinaryTreeNode m_pLeft; BinaryTreeNode m_pRight; public BinaryTreeNode(int value){ m_value = value; }}public class ConstructBinaryTree { BinaryTreeNode root = null; final int FILE_QUEUE_SIZE = 100;// 阻塞队列大小 //前序遍历打印树节点;采用递归算法 public void printfBinaryTree(BinaryTreeNode node){ System.out.print(node.m_value+" "); if(node.m_pLeft != null){ printfBinaryTree(node.m_pLeft); } if(node.m_pRight != null){ printfBinaryTree(node.m_pRight); } } //前序遍历采用非递归树 public void printfBinaryTreeNotRecurision(BinaryTreeNode node){ if(node==null) return; //System.out.print(node.m_value+" "); Stack<BinaryTreeNode> s = new Stack<BinaryTreeNode>();//建立一个栈 BinaryTreeNode p = node; while(!s.isEmpty() || p!=null ){ if(p!=null){ System.out.print(p.m_value+" "); s.push(p); p = p.m_pLeft; }else{ p = s.peek(); s.pop(); p = p.m_pRight; } } } //中序遍历打印树节点; public void printfBinaryTreeByInOrder(BinaryTreeNode node){ if(node.m_pLeft != null){ printfBinaryTreeByInOrder(node.m_pLeft); } System.out.print(node.m_value+" "); if(node.m_pRight != null){ printfBinaryTreeByInOrder(node.m_pRight); } } //中序遍历采用非递归树 public void printfBinaryTreeInOrderNotRecurision(BinaryTreeNode node){ if(node==null) return; //System.out.print(node.m_value+" "); Stack<BinaryTreeNode> s = new Stack<BinaryTreeNode>();//建立一个栈 BinaryTreeNode p = node; while(!s.isEmpty() || p!=null ){ if(p!=null){ s.push(p); p = p.m_pLeft; }else{ p = s.peek(); System.out.print(p.m_value+" "); s.pop(); p = p.m_pRight; } } } //后序遍历,采用递归 public void printfBinaryTreeLastOrder(BinaryTreeNode node){ if(node==null) return; if(node.m_pLeft!=null){ printfBinaryTreeLastOrder(node.m_pLeft); } if(node.m_pRight!=null){ printfBinaryTreeLastOrder(node.m_pRight); } System.out.print(node.m_value+" "); } //后序遍历采用非递归树 public void printfBinaryTreeLastOrderNotRecurision(BinaryTreeNode node){ if(node==null) return; //System.out.print(node.m_value+" "); Stack<BinaryTreeNode> s = new Stack<BinaryTreeNode>();//建立一个栈 BinaryTreeNode p = node; BinaryTreeNode r=null; while(!s.isEmpty() || p!=null ){ if(p!=null){ //System.out.print(p.m_value+" "); s.push(p); p = p.m_pLeft; }else{ //当左子树为空的时候,查看当前节点有没有右子树 //左子树为空,并且右子树为空,则当前是叶子节点; //如果左子树为空,右子树不为空,则当前节点是有右子树的根节点,此时应该打印当前节点的右子树节点。 p = s.peek(); if(p.m_pRight!=null && p.m_pRight!=r){ //如果p有右子树 p = p.m_pRight; //System.out.println(p); }else{ //当前节点就是叶子节点 System.out.print(p.m_value+" "); s.pop(); r=p; p = null; } } } } //层次遍历树节点 public void printfBinaryFromTopToBottom(BinaryTreeNode node){ if(node==null){ return; } BlockingQueue<BinaryTreeNode> queue = new ArrayBlockingQueue<BinaryTreeNode>(FILE_QUEUE_SIZE); queue.add(node); while(queue.size()!=0){ BinaryTreeNode pNode = queue.peek(); queue.remove(); System.out.print(pNode.m_value+" "); if(pNode.m_pLeft!=null){ queue.add(pNode.m_pLeft); } if(pNode.m_pRight!=null){ queue.add(pNode.m_pRight); } } } //递归构建树 public BinaryTreeNode ConstructCore(int[] Preorder,int[] Inorder,int startPreorder,int endPreorder,int startInorder,int endInorder){ int rootValue = Preorder[startPreorder]; BinaryTreeNode root = new BinaryTreeNode(rootValue); root.m_pRight = root.m_pLeft = null; if(startPreorder == endPreorder){ if(startInorder == endInorder) return root; else { System.out.println("无效的输入"); return null; } } //在中序中找到根节点 int rootInorder = startInorder; while(rootInorder <= endInorder && Inorder[rootInorder] != rootValue){ ++rootInorder; } if(rootInorder == endInorder && Inorder[rootInorder] != rootValue){ System.out.println("无效的输入"); return null; } int leftLength = rootInorder-startInorder; int leftPreorderEnd = startPreorder+leftLength; if(leftLength>0){ //构建左子树 root.m_pLeft = ConstructCore(Preorder,Inorder,startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1); } if(leftLength<endPreorder-startPreorder){ root.m_pRight = ConstructCore(Preorder,Inorder,leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder); } return root; } //查找树的子结构 boolean HasSubTree(BinaryTreeNode treeA,BinaryTreeNode treeB){ boolean result = false; if(treeA!=null &&treeB!=null){ if(treeA.m_value == treeB.m_value){ result = DoesTree1HaveTree2(treeA,treeB); } if(!result){ result = HasSubTree(treeA.m_pLeft,treeB); } if(!result){ result = HasSubTree(treeA.m_pRight,treeB); } } return result; } //打印树的镜像 public void MirrorRecursively(BinaryTreeNode tree){ if(tree == null ) return; if(tree.m_pLeft ==null|| tree.m_pRight ==null) return; BinaryTreeNode temp = new BinaryTreeNode(0); int tempNode = tree.m_pLeft.m_value; tree.m_pLeft.m_value = tree.m_pRight.m_value; tree.m_pRight.m_value = tempNode; if(tree.m_pLeft!=null){ MirrorRecursively(tree.m_pLeft); } if(tree.m_pRight!=null){ MirrorRecursively(tree.m_pRight); } } boolean DoesTree1HaveTree2(BinaryTreeNode treeA,BinaryTreeNode treeB){ if(treeB ==null){ return true; } if(treeA ==null){ return false; } if(treeA.m_value !=treeB.m_value){ return false; } return DoesTree1HaveTree2(treeA.m_pLeft,treeB.m_pLeft) &&DoesTree1HaveTree2(treeA.m_pRight,treeB.m_pRight); } //面试题24 二叉搜索树的后序遍历序列 public boolean verfiySequenceOfBST(int[] sequence){ if(sequence==null||sequence.length==0) return false; int length=sequence.length; int root=sequence[length-1]; int cut=0; for(int i=0;i<length-1;i++){ if(sequence[i]>root){ cut=i; break; } } if(cut==0){ verfiySequenceOfBST(Arrays.copyOfRange(sequence, 0,length-1)); }else{ for(int j=cut;j<length-1;j++){ if(sequence[j]<root) return false; } } boolean left=true; if(cut>0) left= verfiySequenceOfBST(Arrays.copyOfRange(sequence,0, cut)); boolean right=true; if(cut<length-1) right=verfiySequenceOfBST(Arrays.copyOfRange(sequence,cut,length-1)); return (right&&left); } //求二叉树中和为某一值的路径 void FindPath(BinaryTreeNode pRoot,int expectedSum){ if(pRoot==null) return; Vector<Integer> path = new Vector<Integer>(); int currentSum = 0; FindPath(pRoot,expectedSum,path,currentSum); } void FindPath(BinaryTreeNode pRoot,int expectedSum,Vector<Integer> path,int currentSum){ currentSum+=pRoot.m_value; path.add(pRoot.m_value); //若为叶结点,并且路劲上结点的和等于输入的值 //打印出这条路劲 boolean isLeft = pRoot.m_pLeft == null && pRoot.m_pRight == null; if(currentSum == expectedSum && isLeft){ System.out.println("A Path is found:"); //Integer value = null; int size = path.size(); for (int i=0; i<size; i++) { System.out.print((Integer)path.get(i)+" "); } System.out.println(); } //如果不是叶子节点,则遍历它的子节点 if(pRoot.m_pLeft!=null) FindPath(pRoot.m_pLeft,expectedSum,path,currentSum); if(pRoot.m_pRight!=null){ FindPath(pRoot.m_pRight,expectedSum,path,currentSum); } //在返回父结点之前,在路径上删除当前结点 path.remove(path.size()-1); } public static void main(String[] args) { // TODO Auto-generated method stub ConstructBinaryTree binaryTree = new ConstructBinaryTree(); ConstructBinaryTree binaryTree2 = new ConstructBinaryTree(); //根据前序和中序构建树,注意:序列中不能有重复的数据,如果不能构成,则输出无效输入 int[] Preorder1={1,2,4,7,3,10,6,8};//给定树的前序 int[] Inorder1 = {4,7,2,1,10,3,8,6};//给定树的中序 int[] Preorder2={3,5,6,8}; int[] Inorder2 = {5,3,8,6}; binaryTree.root = binaryTree.ConstructCore(Preorder1,Inorder1,0,7,0,7); binaryTree2.root = binaryTree.ConstructCore(Preorder2,Inorder2,0,3,0,3); System.out.println("层次遍历"); binaryTree.printfBinaryFromTopToBottom(binaryTree.root); System.out.println(); System.out.println("前序遍历"); binaryTree.printfBinaryTree(binaryTree.root); System.out.println(); System.out.println("中序遍历"); binaryTree.printfBinaryTreeByInOrder(binaryTree.root); System.out.println(); System.out.println("树的非递归前序遍历"); binaryTree.printfBinaryTreeNotRecurision(binaryTree.root); System.out.println(); System.out.println("树的非递归中序遍历"); binaryTree.printfBinaryTreeInOrderNotRecurision(binaryTree.root); System.out.println(); System.out.println("树的递归后序遍历"); binaryTree.printfBinaryTreeLastOrder(binaryTree.root); System.out.println(); System.out.println("树的非递归后序遍历"); binaryTree.printfBinaryTreeLastOrderNotRecurision(binaryTree.root); System.out.println(); System.out.println("----------------------------------"); System.out.println("判断二叉树是否有子结构"); binaryTree.printfBinaryTree(binaryTree2.root); boolean result = false; result=binaryTree.HasSubTree(binaryTree.root, binaryTree2.root); System.out.println("result:"+result); System.out.println("二叉树的镜像"); binaryTree2.MirrorRecursively(binaryTree2.root); System.out.println("二叉树的镜像后的前序输出"); binaryTree2.printfBinaryTree(binaryTree2.root); System.out.println(); System.out.println("判断指定序列是否是一个二叉排序树的后序遍历"); int[] array={5,7,6,9,11,10,8}; result = binaryTree.verfiySequenceOfBST(array); System.out.println("result"+result); System.out.println("查找二叉树的路径和与给定值相等的路径"); binaryTree.FindPath(binaryTree.root, 14); }}
阅读全文
0 0
- 二叉树的基本操作,遍历,子结构,镜像,构建
- 二叉树问题(打印二叉树,二叉树子结构、镜像、遍历,二叉树满足的路径)
- 二叉树的构建,遍历等基本操作
- 二叉树的基本操作及遍历
- 二叉树的基本操作和遍历
- 二叉树基本操作 遍历
- 8606 二叉树的构建及遍历操作
- 二叉树的二叉链表存储结构构建以及先序遍历
- 对称的二叉树(二叉树的镜像操作)
- 二叉链表的存储结构和基本操作(各种遍历、求树深度、求树叶个数)
- 二叉查找树的分层遍历输出和镜像
- 查找二叉树的基本操作以及层次遍历
- 【数据结构】二叉树的简单遍历及基本操作
- 线索二叉树的遍历与基本操作(史上最全)
- 7.4 7.5 二叉树的基本操作与遍历
- 重建二叉树,二叉树的镜像,二叉搜索树的后序遍历
- 树的子结构遍历
- 二叉树的基本操作,前序遍历,后续遍历,中序遍历
- hdu 6053-莫比乌斯反演
- 闭包
- [thinkPHP5项目实战_03]子命名空间及命名空间的访问方式
- ArrayList源码分析
- windows 共享文件夹(不需要输账户密码)
- 二叉树的基本操作,遍历,子结构,镜像,构建
- Android anfix热修复 原理剖析
- Halcon小技巧之如何在编辑回车时不执行代码
- iOS 应用逆向工程2.0 书籍的笔记
- pygorithm: 一个用于学习重要算法的Python模块
- leetcode 438.Find All Anagrams in a String
- UE4-Android-环境部署遇到的问题
- liunx 环境下 python模块numpy,scipy,matplotlib 安装
- iOS中多语言本地化流程的优化