网站项目建设主要内容wordpress投稿功能
网站项目建设主要内容,wordpress投稿功能,一站式服务logo设计,程序员做一个网站多少钱目录 一.概念 二.构建二叉树节点类TreeNode 三.二叉树的遍历 1.前序遍历preOrder
2.中序遍历medOrder
3.后序遍历postOrder 4.非递归遍历
三.深度
1.概念
2.递归求最大深度 3.层序遍历加队列求最大深度
4.测试
5.递归求最小深度
6.层序遍历加队列求最小深度
7.测试
四…目录 一.概念 二.构建二叉树节点类TreeNode 三.二叉树的遍历 1.前序遍历preOrder
2.中序遍历medOrder
3.后序遍历postOrder 4.非递归遍历
三.深度
1.概念
2.递归求最大深度 3.层序遍历加队列求最大深度
4.测试
5.递归求最小深度
6.层序遍历加队列求最小深度
7.测试
四.对称二叉树 五.翻转二叉树
六.后缀表达式构造树
七.根据前序遍历和中序遍历还原树
八.根据后序和中序遍历还原树 一.概念
二叉树是一种树状结构其中每个节点最多有两个子节点被称为左子节点和右子节点。二叉树通常具有以下特点 根节点二叉树的最顶层节点被称为根节点。它没有父节点是整个树的起点。 子节点每个节点最多有两个子节点分别称为左子节点和右子节点。左子节点在树结构中位于父节点的左侧右子节点在右侧。 叶节点没有子节点的节点被称为叶节点也被称为终端节点。叶节点位于树的最底层。 父节点每个节点的上一层节点被称为父节点。每个节点除了根节点都有一个父节点。 兄弟节点拥有相同父节点的节点被称为兄弟节点。 深度节点的深度是指从根节点到该节点的路径上的节点数。 高度节点的高度是指从该节点到树的最底层叶节点的最长路径。 子树节点及其子节点以及与之相关的边所构成的树称为子树。
二叉树在计算机科学中具有广泛的应用例如在搜索树和排序算法中的使用。因为二叉树具有简单的结构和快速的搜索能力所以它被广泛应用于许多领域 二.构建二叉树节点类TreeNode
package 树.二叉树;/*** 普通二叉树*/
public class TreeNode {int value;TreeNode left;TreeNode right;public TreeNode(int value,TreeNode left,TreeNode right){this.value value;this.left left;this.right right;}Overridepublic String toString() {return TreeNode{ value value , left left , right right };}
}三.二叉树的遍历 1.前序遍历preOrder /*** 前序遍历** param treeNode*/static void preOrder(TreeNode treeNode) {if (treeNode null) {return;}System.out.print(treeNode.value \t);preOrder(treeNode.left); //左preOrder(treeNode.right); //右}
2.中序遍历medOrder /*** 中序遍历** param treeNode*/static void medOrder(TreeNode treeNode) {if (treeNode null) {return;}medOrder(treeNode.left); //左System.out.print(treeNode.value \t);medOrder(treeNode.right); //右}
3.后序遍历postOrder /*** 后序遍历** param treeNode*/static void postOrder(TreeNode treeNode) {if (treeNode null) {return;}postOrder(treeNode.left); //左postOrder(treeNode.right); //右System.out.print(treeNode.value \t);}
分别打印一下 public static void main(String[] args) {/*** 1* / \* 2 3* / / \* 6 9 8*/TreeNode root new TreeNode(1,new TreeNode(2, new TreeNode(6, null, null), null),new TreeNode(3, new TreeNode(9, null, null), new TreeNode(8, null, null)));System.out.println(前序遍历);preOrder(root);System.out.println();System.out.println(中序遍历);medOrder(root);System.out.println();System.out.println(后序遍历);postOrder(root);}
运行:
前序遍历
1 2 6 3 9 8
中序遍历
6 2 1 9 3 8
后序遍历
6 2 9 8 3 1
进程已结束,退出代码0 4.非递归遍历 我们可以使用栈stack来实现二叉树的遍历栈可以模拟递归 /*** 通过迭代实现三种遍历*/Testpublic void testAllOrder(){/*** 1* / \* 2 3* / / \* 6 9 8*/TreeNode root new TreeNode(1,new TreeNode(2, new TreeNode(6, null, null), null),new TreeNode(3, new TreeNode(9, null, null), new TreeNode(8, null, null)));//创建栈LinkedListStackTreeNode stack new LinkedListStack(10);//定义指针变量初始指向root节点TreeNode node root;TreeNode pop null;//遍历只要node不为空,并且栈中有元素while (node ! null || !stack.isEmpty()) {//先找左孩子if (node ! null) {//压入栈stack.push(node);System.out.println(前序:node.value);//指向左孩子node node.left;} else {//弹出元素TreeNode peek stack.peek();// 没有右子树if (peek.right null ) {System.out.println(中序遍历:peek.value);//弹出pop stack.pop();System.err.println(后序:pop.value);}//右子树处理完成else if ( peek.right pop) {pop stack.pop();System.err.println(后序:pop.value);}//待处理右子树else {System.out.println(中序遍历:peek.value);//指向栈顶元素的右孩子node peek.right;}}}}
测试一下
前序:1
前序:2
前序:6
后序:6
中序遍历:6
后序:2
中序遍历:2
后序:9
中序遍历:1
后序:8
前序:3
前序:9
中序遍历:9
后序:3
中序遍历:3
后序:1
前序:8
中序遍历:8
三.深度
1.概念 二叉树的深度是指从根节点到最远叶子节点的路径上的节点个数。可以通过递归或迭代的方式来计算二叉树的深度。
递归方法
如果二叉树为空返回深度为 0。否则分别计算左子树和右子树的深度。树的深度为左子树深度和右子树深度中的较大值加 1。
迭代方法层次遍历
如果根节点为空返回深度为 0。创建一个队列并将根节点入队。初始化深度为 0。循环执行以下步骤直到队列为空 获取当前层的节点个数记为 count。将当前层的节点依次出队并将它们的左子节点和右子节点依次入队。将 count 减去当前层节点个数如果 count 大于 0则深度加 1。返回深度的值。
无论使用递归还是迭代的方式都可以得到二叉树的深度。
2.递归求最大深度
/*** 递归调研求最大深度* param node* return*/static int maxDepth(TreeNode node){if(node null){return 0;}if(node.left null node.right null){return 1;}int d1 maxDepth(node.left);int d2 maxDepth(node.right);return Integer.max(d1,d2) 1;} 3.层序遍历加队列求最大深度
/*** 通过层序遍历 加 队列 来实现求最大深度* 思路:* 每次将一层的节点加入到队列中然后循环到下一层取出队列中的元素如果该* 元素右左右子树那么继续加入到队列中去* param root* return*/static int maxDepthByQueue(TreeNode root){if(rootnull){return 0;}//创建队列QueueTreeNode queue new LinkedList();//先把根节点加入到队列中去queue.offer(root);//初始深度为0int depth 0;//当队列不为空时循环while (!queue.isEmpty()){//相当于每一层的个数for (int i 0;i queue.size(); i){//从队头取出元素TreeNode poll queue.poll();//如果有左孩子把左孩子加入到队列中if(poll.left ! null){queue.offer(poll.left);}//如果有右孩子把右孩子加入到队列中if(poll.right ! null){queue.offer(poll.right);}}//每遍历完一层让深度加一depth;}return depth;}
4.测试 /*** 1* / \* 2 3* / \* 4 5* \* 6** 左子树最大深度为3右子树为4,所以最大深度为4*/public static void main(String[] args) {TreeNode root new TreeNode(1,new TreeNode(2,new TreeNode(4,null,null),null),new TreeNode(3,null,new TreeNode(5,null,new TreeNode(6,null,null))));System.out.println(递归法:);System.out.println(maxDepth(root));System.out.println(层序队列法:);System.out.println(maxDepthByQueue(root));} 运行
递归法:
4
层序队列法:
4进程已结束,退出代码0
5.递归求最小深度 /*** 递归求最小深度* param root* return*/static int minDepth(TreeNode root){if(root null){return 0;}int d1 minDepth(root.left);int d2 minDepth(root.right);//为了防止单边树如果一边为null那么应该返回另一边的深度if(d1 0){return d2 1;}if(d2 0){return d1 1;}return Integer.min(d1,d2) 1;}
6.层序遍历加队列求最小深度 /*** 层序遍历找最小深度* 思路* 如果找到第一个叶子节点那么该叶子节点所在的层就是最小层* param root* return*/static int minDepthFloorByQueue(TreeNode root){if(rootnull){return 0;}LinkedListTreeNode queue new LinkedList();int depth 0;queue.offer(root);while (!queue.isEmpty()){int size queue.size();depth;for (int i 0; i size; i) {TreeNode poll queue.poll();if(poll.leftnull poll.rightnull){return depth;}if(poll.left!null){queue.offer(poll.left);}if(poll.right ! null){queue.offer(poll.right);}}}return depth;}
}
7.测试 public static void main(String[] args) {/*** 1* / \* 2 3* / \* 4 5* \* 6** 左子树最大深度为3右子树为4,所以最大深度为4*/TreeNode root new TreeNode(1,new TreeNode(2,new TreeNode(4,null,null),null),new TreeNode(3,null,new TreeNode(5,null,new TreeNode(6,null,null))));System.out.println(递归法:);System.out.println(minDepth(root));System.out.println(层序队列法:);System.out.println(minDepthFloorByQueue(root));}
运行:
递归法:
3
层序队列法:
3进程已结束,退出代码0
四.对称二叉树
/*** 对称二叉树*/
public class D_Eq_Tree {/*** 左的左和右的右相等* 左的右和右的左相等** param args*/public static void main(String[] args) {/*** 1* / \* 2 2* /\ /\* 3 4 4 3*/TreeNode root new TreeNode(1,new TreeNode(2,new TreeNode(3,null,null),new TreeNode(4,null,null)),new TreeNode(2,new TreeNode(4,null,null),new TreeNode(3,null,null)));boolean flag isD_EqTree(root.left, root.right);System.out.println(flag);}static boolean isD_EqTree(TreeNode left,TreeNode right){//如果左子树和右子树都为null则对称if(leftnull rightnull){return true;}//如果左子树或者右子树为Null则不对称if(leftnull || rightnull){return false;}//如果左右两边值不相等则不对称if(left.value ! right.value){return false;}//左右递归return isD_EqTree(left.left,right.right) isD_EqTree(left.right,right.left);}}
测试运行
true进程已结束,退出代码0 五.翻转二叉树
/*** 翻转二叉树*/
public class L226_ReversedTree {public static void main(String[] args) {/*** 1 1* / \ / \* 2 3 3 2* / \ / \ / \ / \* 4 5 6 7 7 6 5 4*/TreeNode root new TreeNode(1,new TreeNode(2,new TreeNode(4,null,null),new TreeNode(5,null,null)),new TreeNode(3,new TreeNode(6,null,null),new TreeNode(7,null,null)));preOrder(root);System.out.println();reversed(root);preOrder(root);}/*** 翻转二叉树* param root*/static void reversed(TreeNode root){if(rootnull){return;}TreeNode node root.left;root.left root.right;root.right node;//递归左子树reversed(root.left);//递归右子树reversed(root.right);}static void preOrder(TreeNode root){if(rootnull){return;}System.out.print(root.value\t);preOrder(root.left);preOrder(root.right);}}
运行:
1 2 4 5 3 6 7
1 3 7 6 2 5 4
进程已结束,退出代码0
六.后缀表达式构造树
/*** 后缀表达式构造树*/
public class Last_Expression {/*** 中缀 (2-1)*3* 后缀 21-3*** 树* ** / \* - 3* / \* 2 1** 后序遍历就能获得 21-3**** param args*/public static void main(String[] args) {String[] str {2,1,-,3,*};LinkedListTreeStrNode stack new LinkedList();for (String c : str) {switch (c){case :case -:case *:case /://先弹出的为右孩子TreeStrNode right stack.pop();//后弹出的为左孩子TreeStrNode left stack.pop();//创建树TreeStrNode parent new TreeStrNode(c);parent.left left;parent.right right;//最后把父节点压入栈stack.push(parent);break;default://如果不是运算符就压入栈stack.push(new TreeStrNode(c));}}//最终栈中的节点为树的根节点TreeStrNode root stack.peek();//对他做一个后序遍历postOrder(root);}/*** 后序遍历** param treeNode*/static void postOrder(TreeStrNode treeNode) {if (treeNode null) {return;}postOrder(treeNode.left); //左postOrder(treeNode.right); //右System.out.print(treeNode.str \t);}} 运行
2 1 - 3 *
进程已结束,退出代码0
七.根据前序遍历和中序遍历还原树
/*** 根据前序遍历和中序遍历 还原树*/
public class Pre_In_ToTree {/*** 1* / \* 2 3* / / \* 6 9 8** preOrder 1, 2, 6, 3, 9, 8* inOrder 6, 2, 1, 9 , 3, 8** 思路* 前序遍历的第一个是根节点 root 1* 然后找到中序遍历中 root所在的位置* -左边的是左子树* -右边的是右子树* 中序* 左: 6,2* 右: 9,3,8* 前序:* 左: 2,6* 右: 3,9,8** 这样根据中序的左和前序的左可以知道 6 是左子树, 2 是父节点* 根据中序的右和前序的右可以知道 9是左子树8是右子树3是父节点** 最后递归调用继续分割左右数组***/public static void main(String[] args) {int[] preOrder {1, 2, 6, 3, 9, 8};int[] inOrder {6, 2, 1, 9 , 3, 8};TreeNode root getTree(preOrder, inOrder);preOrder(root);}static TreeNode getTree(int[] preOrder,int[] inOrder){//结束递归条件if(preOrder.length 0){return null;}//先找到根节点int rootValue preOrder[0];TreeNode root new TreeNode(rootValue, null, null);//在中序中找到根节点的位置for (int i 0; i inOrder.length ; i) {if(inOrder[i] rootValue){//找到之后切割左子树和右子树//inOrder.left 0 ~ i-1//inOrder.right i1 ~ inOrder.length-1;int[] inLeft Arrays.copyOfRange(inOrder, 0, i);int[] inRight Arrays.copyOfRange(inOrder, i 1, inOrder.length);//继续切割preOrder//preOrder.left 1 ~ i1//preOrder.right i2 ~ preOrder.length-1int[] preLeft Arrays.copyOfRange(preOrder, 1, i1);int[] preRight Arrays.copyOfRange(preOrder, i 1, preOrder.length);//递归调用root.left getTree(preLeft,inLeft);root.right getTree(preRight,inRight);break;}}return root;}/*** 前序遍历** param treeNode*/static void preOrder(TreeNode treeNode) {if (treeNode null) {return;}System.out.print(treeNode.value \t);preOrder(treeNode.left); //左preOrder(treeNode.right); //右}}
运行:
1 2 6 3 9 8
进程已结束,退出代码0 八.根据后序和中序遍历还原树
/*** 根据后序和中序遍历还原树*/
public class Post_In_ToTree {/*** 1* / \* 2 3* / / \* 6 9 8** postOrder 6,2,9,8,3,1* inOrder 6, 2, 1, 9 , 3, 8***/public static void main(String[] args) {int[] postOrder {6,2,9,8,3,1};int[] inOrder {6, 2, 1, 9 , 3, 8};TreeNode root buildTree(postOrder, inOrder);preOrder(root);}static TreeNode buildTree(int[] postOrder,int[] inOrder){if(postOrder.length0){return null;}//先找根节点int rootValue postOrder[postOrder.length - 1];TreeNode root new TreeNode(rootValue, null, null);for (int i 0; i inOrder.length; i) {if(inOrder[i] rootValue){//切分int[] inLeft Arrays.copyOfRange(inOrder, 0, i);int[] inRight Arrays.copyOfRange(inOrder, i 1, inOrder.length);int[] postLeft Arrays.copyOfRange(postOrder, 0, i);int[] postRight Arrays.copyOfRange(postOrder, i , postOrder.length - 1);//递归root.left buildTree(postLeft,inLeft);root.right buildTree(postRight,inRight);break;}}return root;}}
运行:
1 2 6 3 9 8
进程已结束,退出代码0
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/90450.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!