二叉 树

文章目录

    • 递归方式 先序、中序、后序 遍历
    • 非递归方式 先序、中序、后序 遍历
    • 实现二叉树的按层遍历
    • 求二叉树的最大宽度
    • 二叉树的序列化和反序列化
    • 二叉树有 left、right、parent ,给这样二叉树的某个结点,返回该节点的后继节点
    • 折纸条

递归方式 先序、中序、后序 遍历

public class RecursiveTraversalBT {public static class Node {public int value;public Node left;public Node right;public Node(int v) {value = v;}}public static void f(Node head) {if (head == null) {return;}// 1f(head.left);// 2f(head.right);// 3}// 先序打印所有节点public static void pre(Node head) {if (head == null) {return;}System.out.println(head.value);pre(head.left);pre(head.right);}public static void in(Node head) {if (head == null) {return;}in(head.left);System.out.println(head.value);in(head.right);}public static void pos(Node head) {if (head == null) {return;}pos(head.left);pos(head.right);System.out.println(head.value);}}

非递归方式 先序、中序、后序 遍历

使用栈

import java.util.Stack;public class UnRecursiveTraversalBT {public static class Node {public int value;public Node left;public Node right;public Node(int v) {value = v;}}//先序遍历public static void pre(Node head) {System.out.print("pre-order: ");if (head != null) {Stack<Node> stack = new Stack<Node>();stack.add(head);while (!stack.isEmpty()) {head = stack.pop();System.out.print(head.value + " ");if (head.right != null) {stack.push(head.right);}if (head.left != null) {stack.push(head.left);}}}System.out.println();}//中序遍历public static void in(Node cur) {System.out.print("in-order: ");if (cur != null) {Stack<Node> stack = new Stack<Node>();while (!stack.isEmpty() || cur != null) {if (cur != null) {stack.push(cur);cur = cur.left;} else {cur = stack.pop();System.out.print(cur.value + " ");cur = cur.right;}}}System.out.println();}//使用了两个栈实现后序遍历public static void pos1(Node head) {System.out.print("pos-order: ");if (head != null) {Stack<Node> s1 = new Stack<Node>();Stack<Node> s2 = new Stack<Node>();s1.push(head);while (!s1.isEmpty()) {head = s1.pop(); // 头 右 左s2.push(head);if (head.left != null) {s1.push(head.left);}if (head.right != null) {s1.push(head.right);}}// 左 右 头while (!s2.isEmpty()) {System.out.print(s2.pop().value + " ");}}System.out.println();}//使用一个栈实现后序遍历public static void pos2(Node h) {System.out.print("pos-order: ");if (h != null) {Stack<Node> stack = new Stack<Node>();stack.push(h);Node c = null;while (!stack.isEmpty()) {c = stack.peek();if (c.left != null && h != c.left && h != c.right) {stack.push(c.left);} else if (c.right != null && h != c.right) {stack.push(c.right);} else {System.out.print(stack.pop().value + " ");h = c;}}}System.out.println();}}

实现二叉树的按层遍历

1)宽度优先遍历,用队列

import java.util.LinkedList;
import java.util.Queue;public class LevelTraversalBT {public static class Node {public int value;public Node left;public Node right;public Node(int v) {value = v;}}public static void level(Node head) {if (head == null) {return;}Queue<Node> queue = new LinkedList<>();queue.add(head);while (!queue.isEmpty()) {Node cur = queue.poll();System.out.println(cur.value);if (cur.left != null) {queue.add(cur.left);}if (cur.right != null) {queue.add(cur.right);}}}}

2)通过设置flag变量的方式,来发现某一层的结束

参考 (求二叉树的最大宽度) 这个题

求二叉树的最大宽度

1)使用map
2)不使用map

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;public class TreeMaxWidth {public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value = data;}}public static int maxWidthUseMap(Node head) {if (head == null) {return 0;}Queue<Node> queue = new LinkedList<>();queue.add(head);// key 在 哪一层,valueHashMap<Node, Integer> levelMap = new HashMap<>();levelMap.put(head, 1);int curLevel = 1; // 当前你正在统计哪一层的宽度int curLevelNodes = 0; // 当前层curLevel层,宽度目前是多少int max = 0;while (!queue.isEmpty()) {Node cur = queue.poll();int curNodeLevel = levelMap.get(cur);if (cur.left != null) {levelMap.put(cur.left, curNodeLevel + 1);queue.add(cur.left);}if (cur.right != null) {levelMap.put(cur.right, curNodeLevel + 1);queue.add(cur.right);}if (curNodeLevel == curLevel) {curLevelNodes++;} else {max = Math.max(max, curLevelNodes);curLevel++;curLevelNodes = 1;}}max = Math.max(max, curLevelNodes);return max;}public static int maxWidthNoMap(Node head) {if (head == null) {return 0;}Queue<Node> queue = new LinkedList<>();queue.add(head);Node curEnd = head; // 当前层,最右节点是谁Node nextEnd = null; // 下一层,最右节点是谁int max = 0;int curLevelNodes = 0; // 当前层的节点数while (!queue.isEmpty()) {Node cur = queue.poll();if (cur.left != null) {queue.add(cur.left);nextEnd = cur.left;}if (cur.right != null) {queue.add(cur.right);nextEnd = cur.right;}curLevelNodes++;if (cur == curEnd) {max = Math.max(max, curLevelNodes);curLevelNodes = 0;curEnd = nextEnd;}}return max;}
}

在这里插入图片描述

二叉树的序列化和反序列化

1)可以用 先序或者中序或者后序,来实现二叉树的序列化

(用了什么方式序列化,就用什么方式反序列化)

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;public class SerializeAndReconstructTree {/** 二叉树可以通过先序、后序或者按层遍历的方式序列化和反序列化,* 以下代码全部实现了。* 但是,二叉树无法通过中序遍历的方式实现序列化和反序列化* 因为不同的两棵树,可能得到同样的中序序列,即便补了空位置也可能一样。* 比如如下两棵树*         __2*        /*       1*       和*       1__*          \*           2* 补足空位置的中序遍历结果都是{ null, 1, null, 2, null}*       * */public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value = data;}}public static Queue<String> preSerial(Node head) {Queue<String> ans = new LinkedList<>();pres(head, ans);return ans;}public static void pres(Node head, Queue<String> ans) {if (head == null) {ans.add(null);} else {ans.add(String.valueOf(head.value));pres(head.left, ans);pres(head.right, ans);}}public static Queue<String> inSerial(Node head) {Queue<String> ans = new LinkedList<>();ins(head, ans);return ans;}public static void ins(Node head, Queue<String> ans) {if (head == null) {ans.add(null);} else {ins(head.left, ans);ans.add(String.valueOf(head.value));ins(head.right, ans);}}public static Queue<String> posSerial(Node head) {Queue<String> ans = new LinkedList<>();poss(head, ans);return ans;}public static void poss(Node head, Queue<String> ans) {if (head == null) {ans.add(null);} else {poss(head.left, ans);poss(head.right, ans);ans.add(String.valueOf(head.value));}}public static Node buildByPreQueue(Queue<String> prelist) {if (prelist == null || prelist.size() == 0) {return null;}return preb(prelist);}public static Node preb(Queue<String> prelist) {String value = prelist.poll();if (value == null) {return null;}Node head = new Node(Integer.valueOf(value));head.left = preb(prelist);head.right = preb(prelist);return head;}public static Node buildByPosQueue(Queue<String> poslist) {if (poslist == null || poslist.size() == 0) {return null;}// 左右中  ->  stack(中右左)Stack<String> stack = new Stack<>();while (!poslist.isEmpty()) {stack.push(poslist.poll());}return posb(stack);}public static Node posb(Stack<String> posstack) {String value = posstack.pop();if (value == null) {return null;}Node head = new Node(Integer.valueOf(value));head.right = posb(posstack);head.left = posb(posstack);return head;}
}

2)按层遍历

public class SerializeAndReconstructTree {public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value = data;}}public static Queue<String> levelSerial(Node head) {Queue<String> ans = new LinkedList<>();if (head == null) {ans.add(null);} else {ans.add(String.valueOf(head.value));Queue<Node> queue = new LinkedList<Node>();queue.add(head);while (!queue.isEmpty()) {head = queue.poll(); // head 父   子if (head.left != null) {ans.add(String.valueOf(head.left.value));queue.add(head.left);} else {ans.add(null);}if (head.right != null) {ans.add(String.valueOf(head.right.value));queue.add(head.right);} else {ans.add(null);}}}return ans;}public static Node buildByLevelQueue(Queue<String> levelList) {if (levelList == null || levelList.size() == 0) {return null;}Node head = generateNode(levelList.poll());Queue<Node> queue = new LinkedList<Node>();if (head != null) {queue.add(head);}Node node = null;while (!queue.isEmpty()) {node = queue.poll();node.left = generateNode(levelList.poll());node.right = generateNode(levelList.poll());if (node.left != null) {queue.add(node.left);}if (node.right != null) {queue.add(node.right);}}return head;}public static Node generateNode(String val) {if (val == null) {return null;}return new Node(Integer.valueOf(val));}
}

二叉树有 left、right、parent ,给这样二叉树的某个结点,返回该节点的后继节点

public class SuccessorNode {public static class Node {public int value;public Node left;public Node right;public Node parent;public Node(int data) {this.value = data;}}public static Node getSuccessorNode(Node node) {if (node == null) {return node;}if (node.right != null) {return getLeftMost(node.right);} else { // 无右子树Node parent = node.parent;while (parent != null && parent.right == node) { // 当前节点是其父亲节点右孩子node = parent;parent = node.parent;}return parent;}}public static Node getLeftMost(Node node) {if (node == null) {return node;}while (node.left != null) {node = node.left;}return node;}
}

折纸条

在这里插入图片描述

public class PaperFolding {public static void printAllFolds(int N) {process(1, N, true);System.out.println();}// 当前你来了一个节点,脑海中想象的!// 这个节点在第i层,一共有N层,N固定不变的// 这个节点如果是凹的话,down = T// 这个节点如果是凸的话,down = F// 函数的功能:中序打印以你想象的节点为头的整棵树!public static void process(int i, int N, boolean down) {if (i > N) {return;}process(i + 1, N, true);System.out.print(down ? "凹 " : "凸 ");process(i + 1, N, false);}public static void main(String[] args) {int N = 4;printAllFolds(N);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“老师,弃了吧,做个别的……”“笑话,都到这个份上了,怎么能弃掉呢?”...

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。最近项目小组一直在按照原计划做项目&#xff0c;聊天程序&#xff08;高仿版微信&#xff09;已经趋于尾声&#xff0c;做的还可以&#xff0c;剩下的就是美化和慢慢的完善小问题了&#…

IntelliJ IDEA 源值1.5已过时,将在未来所有版本中删除

转载自 IntelliJ IDEA 源值1.5已过时&#xff0c;将在未来所有版本中删除 原因&#xff1a; IDEA默认把项目的源代码版本设置为jdk1.5&#xff0c;目标代码设置为jdk1.5 解决方案&#xff1a; 1修改Maven的Settings.xml文件添加如下内容 <profile><id>jdk-1.8&…

.NET Core 2.0迁移技巧之MemoryCache问题修复

对于传统的.NET Framework项目而言&#xff0c;System.Runtime.Caching命名空间是常用的工具了&#xff0c;其中MemoryCache类则常被用于实现内存缓存。 .NET Core 2.0暂时还不支持System.Runtime.Caching dll&#xff0c;这也就意味着MemoryCache相关代码不再起作用了。 但是…

今天干了两件大事!

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。今天干了两件大事。第一件就是为明天的“IT技能大赛”做了充足准备&#xff0c;带着6个班级的7个小组&#xff0c;在报告厅过了一遍&#xff0c;然后安排了两个后台控制同学&#xff0c;主…

JAVA后端面试100 QA之第一篇

转载自 JAVA后端面试100 Q&A之第一篇 1. synchronized和reentrantlock异同 相同点 都实现了多线程同步和内存可见性语义都是可重入锁 不同点 实现机制不同 synchronized通过java对象头锁标记和Monitor对象实现 reentrantlock通过CAS、ASQ&#xff08;AbstractQueuedSy…

P2158,jzoj1709-仪仗队【欧拉函数,数论】

正题 评测记录&#xff1a;https://www.luogu.org/recordnew/lists?uid52918&pidP2158 大意 有n∗nn∗n个点&#xff0c;求从(1,1)(1,1)可以看到多少个点。 解题思路 我们将(1,1)(1,1)当做(0,0)(0,0)&#xff0c;然后所有点往下和后移一步 我们可以发现点距离点(0,0…

asp.net core MVC 过滤器之ExceptionFilter过滤器(一)

简介 异常过滤器&#xff0c;顾名思义&#xff0c;就是当程序发生异常时所使用的过滤器。用于在系统出现未捕获异常时的处理。 实现一个自定义异常过滤器 自定义一个异常过滤器需要实现IExceptionFilter接口 public class HttpGlobalExceptionFilter : IExceptionFilter { …

今天是个特殊的一天,有意义的一天,值得纪念的一天~

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。今天是个特殊的一天&#xff0c;筹划准备两周时间的IT技能大赛终于在报告厅顺利举行&#xff0c;全校6个班级共有7个小组参加本次技能大赛&#xff0c;大家的项目丰富多彩&#xff0c;不但…

分布式之redis复习精讲

转载自 分布式之redis复习精讲 引言 为什么写这篇文章? 博主的《分布式之消息队列复习精讲》得到了大家的好评&#xff0c;内心诚惶诚恐&#xff0c;想着再出一篇关于复习精讲的文章。但是还是要说明一下&#xff0c;复习精讲的文章偏面试准备&#xff0c;真正在开发过程中…

Nodejs第一讲记录

大家好&#xff0c; 我是雄雄&#xff0c;欢迎关注公众号 &#xff1a;雄雄的小课堂Node.jsNode的简介node是运行在服务端的JS基于谷歌 JavaScript运行时建立的一个平台是一个事件驱动IO服务端JavaScript环境&#xff0c;基于谷歌V8引擎&#xff0c;V8引擎执行JavaScript的速度…

ASP.NET Core 使用Cookie验证身份

ASP.NET Core 1.x提供了通过Cookie 中间件将用户主体序列化为一个加密的Cookie&#xff0c;然后在后续请求中验证Cookie并重新创建主体&#xff0c;并将其分配给HttpContext.User属性。如果您要提供自己的登录界面和用户数据库&#xff0c;可以使用作为独立功能的Cookie中间件。…

Node.JS第二讲笔记

大家好&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂package包包结构包其实就是一个压缩文件&#xff0c;解压之后还原为目录&#xff0c;符合规范的目录&#xff0c;应该包含如下文件&#xff1a;package.json:描述文件bin&#xff1a;可执行的二进制文件lib&#…

asp.net core MVC 过滤器之ActionFilter过滤器(二)

简介 Action过滤器将在controller的Action执行之前和之后执行相应的方法。 实现一个自定义Action过滤器 自定义一个全局异常过滤器需要实现IActionFilter接口 public class ActionFilter : IActionFilter { public void OnActionExecuted(ActionExecutedContext context) …

【最全最详细】publiccms使用教程

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂拉取项目&#xff08;项目部署阶段&#xff09;1.首先需要从gitee中拉取项目&#xff0c;地址为&#xff1a;public cms项目地址 &#xff0c;在idea中点击文件--》新建--》来自版本控制的项…

越努力越幸运,三年了!!!

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”今天非常的开心&#xff0c;因为考了三年的驾照终于考完了。在大厅候考的时候&#xff0c;从10.40等到了1.40,坐在下面能看到LED上有自己的名字&#xff0c;但是前面等待的有200多人………

为什么我们要使用Async、Await关键字

前不久&#xff0c;在工作中由于默认&#xff08;xihuan&#xff09;使用Async、Await关键字受到了很多质问&#xff0c;所以由此引发这篇博文“为什么我们要用Async/Await关键字”&#xff0c;请听下面分解&#xff1a; Async/Await关键字 Visual Studio&#xff08;.net fra…

一次惊险的跳槽面试经历(阿里/美团/头条/网易/有赞...)

转载自 一次惊险的跳槽面试经历&#xff08;阿里/美团/头条/网易/有赞...) 每次说因为生活成本的时候面试官都会很惊奇&#xff0c;难道有我们这里贵&#xff1f;好想直接给出下面这张图&#xff0c;厦门的房价真的好贵好贵好贵。。。 面试过程 有兴趣加入阿里的欢迎发简历…

利用bladex+avue实现一对多的关系

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”今天&#xff0c;记录一篇技术文章吧&#xff0c;也是解决了好久才解决掉的&#xff08;说来也惭愧&#xff09;。涉及技术前端&#xff1a;vue&#xff0c;element ui后端框架&#xff…

.NET中的高性能应用

本文要点 .NET自4.0以来得到了大幅的性能提升&#xff0c;很值得重新考虑一下基于旧版本.NET框架所做的假定。在讨论性能时垃圾回收是个重复出现的主题&#xff0c;它带来了许多CLR和语言的提升&#xff0c;比如引用返回和ValueTask在内存分配上更细粒度度量的性能分析API会成…

利用bladex+avue实现下拉数据源展示

“ 大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;????雄雄的小课堂???? ”昨天给大家整理了下如何使用bladex实现多表查询的方法&#xff0c;今天我们趁热打铁&#xff0c;顺便看看下拉列表的实现。 需求 我们经常会有这样的需求&#xff0c;…