当前位置: 首页 > 后端技术 > Java

二叉树基本算法

时间:2023-04-01 16:18:02 Java

二叉树定义:二叉树(英文:Binarytree)是每个节点至多有两个分支(即没有分支度大于2的节点)的树结构。通常分支被称为“左子树”或“右子树”。二叉树的分支有左右顺序,不能随意颠倒。有关更多说明,请参见堆和堆排序。一、递归遍历1、先序遍历根。a,b,d,e,c,f,g/***二叉树:前序遍历。Root-left-right**经典递归写法**@authorJava与算法学习:周一*/publicstaticvoidpre(Nodehead){if(head==null){return;}System.out.println(head.value);前(头。左);pre(head.right);}2.中序遍历左根右。d,b,e,a,f,c,g/***二叉树:中序遍历。左-根-右**经典递归写法**@authorJava与算法学习:周一*/publicstaticvoidin(Nodehead){if(head==null){return;}在(头。左);系统.out.println(head.value);in(head.right);}3.后序遍历左右根。d,e,b,f,g,c,a/***二叉树:后序遍历。左右根**经典递归写法**@authorJava与算法学习:周一*/publicstaticvoidpos(Nodehead){if(head==null){return;}pos(head.left);pos(head.right);System.out.println(head.value);}经典的递归版本的前序、中序、后序遍历,我们再熟悉不过了。今天我们将讨论一些不同的东西,递归顺序。细心的朋友似乎已经发现,递归的前序、中序、后序遍历其实很相似,只是打印的时机不同而已。这是因为它们实际上是从递归顺序重写的。什么是递归顺序,就是每次自己经过时,打印节点的值,最后打印出来的就是递归顺序。在递归顺序的基础上,只打印第一次经过自身时的值,即前序;只打印第二次经过自身的值,即in-order;只打印第三次经过自身的值,即Postorder。4.递归序列/***递归序列**@authorJava与算法学习:星期一*/publicstaticvoidf(Nodehead){if(head==null){return;}//1System.out.println(head.value);f(头.左);//2System.out.println(head.value);f(头.右);//3System.out.println(head.value);}a结论:知道一棵二叉树的前序遍历和后序遍历,某节点X,X的前序遍历之前的节点集合是A,X的后序遍历之后的节点集合是B,那么A和B的交集一定是节点X的所有祖先。2.非递归遍历1.前序遍历(1)准备一个栈,压入当前节点(即头节点)(2)弹出栈顶元素入栈并打印对应值(3)这个元素有右孩子入栈右孩子,有左孩子入栈左孩子(先右后左)(4)执行步骤2和3直到堆栈为空。/***非递归前序遍历**@authorJava与算法学习:周一*/publicstaticvoidpre(Nodehead){if(head!=null){Stackstack=newStack<>();//推送当前节点stack.push(head);while(!stack.isEmpty()){//弹出栈顶元素Nodecurrent=stack.pop();rr"ent+System.value。");//先按右孩子,再按左孩子左边);}}}}2.中序遍历(1)准备一个栈(2)以当前节点current为头节点压入整个左子树(一个栈,current会移动到左孩子),直到empty(3)弹出栈顶元素,打印其值,取当前弹出元素的右孩子为当前节点,重复步骤2(4)栈为空时结束/***非递归in-顺序遍历**@authorJava与算法学习:周一*/publicstaticvoidin(Nodehead){if(head!=null){Stackstack=newStack<>();节点当前=头部;while(!stack.isEmpty()||current!=null){if(current!=null){//将当前节点的整个左子树压入栈中stack.push(current);当前=当前.左;;System.out.print(pop.value+"");一个栈stackA,stackB;stackA压入当前节点(即头节点)(2)弹出栈顶元素,压入stackB(3)这个元素有一个左孩子将左孩子压入stackA栈,一个右孩子压入stackAthestackAstack进入右孩子(先左后右)(4)执行第2步和第3步,直到stackA为空(5)打印stackB的所有元素,相当于stackA的堆叠顺序是rootrightleft,最后是stackB堆叠顺序是左根和右根。/***非递归后序遍历**@authorJava与算法学习:周一*/publicstaticvoidpos(Nodehead){if(head!=null){StackstackA=newStack<>();堆栈<节点>stackB=new堆栈<>();stackA.push(头);while(!stackA.isEmpty()){//stackA的堆叠顺序是rootrightleftopNodecurrent.p=stack//stackB的堆叠顺序是RootRightLeft}If(Current.richt!=Null){stacka.push(Current.ricHt);}///stackb出栈顺序是左-右while(!stackb.isempty()){System.out.print(stackb.pop().value+"");}}}3.二叉树逐层遍历(1)准备一个队列,头节点入队(2)出队一个节点并打印其值;如果出队节点有左孩子,则将左孩子加入队列,如果有右孩子,则将右孩子加入队列(3)循环执行步骤2,直到队列为空/***二进制逐层遍历树**@authorJava与算法学习:星期一*/publicstaticvoidlevelTraversal(Nodehead){if(head==null){返回;}//准备一个队列Queuequeue=newLinkedList<>();//头节点入队queue.offer(head);while(!queue.isEmpty()){//从队列中弹出一个节点Nodecurrent=queue.poll();//打印System.out.print(current.value+"");//如果有左孩子,则左孩子加入队列),非递归遍历,二叉树的层序遍历本文所有代码:https://github.com/monday-pro/algorithm-study/tree/master/src/basic/binarytree