二叉树

pull/28/head
chefyuan 2021-06-28 18:58:22 +08:00
parent e2394cdd6d
commit b2e84c94ba
7 changed files with 475 additions and 112 deletions

View File

@ -87,9 +87,11 @@
- [](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E5%A0%86%E6%8E%92%E5%BA%8F.md)
- [](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E8%AE%A1%E6%95%B0%E6%8E%92%E5%BA%8F.md)
### 🍺
### 🍺
- [+Morris](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E4%BA%8C%E5%8F%89%E6%A0%91/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86(%E6%A0%88).md)
- [+Morris](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E4%BA%8C%E5%8F%89%E6%A0%91/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86(%E6%A0%88).md)
- +Morris
- +Morris
### 🍗
@ -265,4 +267,4 @@
<div align="center"> <img src="https://cdn.jsdelivr.net/gh/tan45du/photobed@master/赞赏码.2mrhxsmxexa0.png" width = "200px" hight = "200px"/> </div>
####
###### ####

View File

@ -0,0 +1,157 @@
Morris Morris
> Github
, `,, , `
![](https://cdn.jsdelivr.net/gh/tan45du/test@master/photo/中序遍历.7gct7ztck8k0.gif)
##
![](https://img-blog.csdnimg.cn/20210608010104232.gif)
-
-
list
```java
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> arr = new ArrayList<>();
TreeNode cur = new TreeNode(-1);
cur = root;
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || cur != null) {
//找到当前应该遍历的那个节点
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
//此时指针指向空,也就是没有左子节点,则开始执行出栈操作
TreeNode temp = stack.pop();
arr.add(temp.val);
//指向右子节点
cur = temp.right;
}
return arr;
}
}
```
### **Morris**
Morris Morris
Morris
** Morris **
```java
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
TreeNode p1 = root; TreeNode p2 = null;
while (p1 != null) {
p2 = p1.left;
if (p2 != null) {
//找到左子树的最右叶子节点
while (p2.right != null && p2.right != p1) {
p2 = p2.right;
}
//添加 right 指针,对应 right 指针为 null 的情况
//标注 1
if (p2.right == null) {
list.add(p1.val);
p2.right = p1;
p1 = p1.left;
continue;
}
//对应 right 指针存在的情况,则去掉 right 指针
p2.right = null;
//标注2
} else {
list.add(p1.val);
}
//移动 p1
p1 = p1.right;
}
return list;
}
}
```
1 p1 p1 list
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.3h60vcjhqo80.png)
p1 `p1 = p1.left`
![](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.44fk4hw4maw0.png)
`p2.right == p1` `p2.right == null` `p1 = p1.right`, p1
Morris `p2.right == p1` p1 `list.add(p1.val);`
Morris
![](https://img-blog.csdnimg.cn/20210622155624486.gif)
![Morris](https://img-blog.csdnimg.cn/20210622155959185.gif)
****
```java
//中序 Morris
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
TreeNode p1 = root;
TreeNode p2 = null;
while (p1 != null) {
p2 = p1.left;
if (p2 != null) {
while (p2.right != null && p2.right != p1) {
p2 = p2.right;
}
if (p2.right == null) {
p2.right = p1;
p1 = p1.left;
continue;
} else {
p2.right = null;
}
}
list.add(p1.val);
p1 = p1.right;
}
return list;
}
}
```

View File

@ -37,7 +37,6 @@ PS本篇文章内容较基础对于没有学过数据结构的同学会有
> n n >= 0 n = 0 ,
>
``

View File

@ -0,0 +1,106 @@
### Morris
Morris
![Morris](https://img-blog.csdnimg.cn/20210622155959185.gif)
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.1u3at0ckvn34.png)
Morris ```` right 2 9 9 right 2
Morris
1. p1.left == null p1 = p1.right( right )
2. p1.left != null p1 ( p2 ) right right
3. - p2 right p1p1, p1 = p1.left
- p2 right p1 right p1 p1 = p1.right
p1 root
p2 = p1.left p2 p1 5 right root root
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.3h60vcjhqo80.png)
p1 p1 = p1.left
p2 = p1.left 4 p1 9 right 2
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.zq91mdjkyzk.png)
p1, p1 = p1.leftp2 = p1.left 8 right p1
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.5vsh71yrzxs0.png)
right p1, right
p1 p1 = p1.leftp2 = p.left p2 == null,
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.zk7nxrjdgr.png)
p1, p1 = p1.left p1 = p1.right 4 p2 = p1.left
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.1pjni9r6tkps.png)
p2.right != null 4 right right p1 = p1.right
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.17t7n8yy340w.png)
p1 ,
On O1
####
```java
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
TreeNode p1 = root; TreeNode p2 = null;
while (p1 != null) {
p2 = p1.left;
if (p2 != null) {
//找到左子树的最右叶子节点
while (p2.right != null && p2.right != p1) {
p2 = p2.right;
}
//添加 right 指针,对应 right 指针为 null 的情况
if (p2.right == null) {
list.add(p1.val);
p2.right = p1;
p1 = p1.left;
continue;
}
//对应 right 指针存在的情况,则去掉 right 指针
p2.right = null;
} else {
list.add(p1.val);
}
//移动 p1
p1 = p1.right;
}
return list;
}
}
```

View File

@ -67,107 +67,3 @@ class Solution {
}
```
### Morris
Morris
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.1u3at0ckvn34.png)
Morris ```` right 2 9 9 right 2
Morris
1. p1.left == null p1 = p1.right( right )
2. p1.left != null p1 ( p2 ) right right
3. - p2 right p1p1, p1 = p1.left
- p2 right p1 right p1 p1 = p1.right
p1 root
p2 = p1.left p2 p1 5 right root root
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.3h60vcjhqo80.png)
p1 p1 = p1.left
p2 = p1.left 4 p1 9 right 2
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.zq91mdjkyzk.png)
p1, p1 = p1.leftp2 = p1.left 8 right p1
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.5vsh71yrzxs0.png)
right p1, right
p1 p1 = p1.leftp2 = p.left p2 == null,
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.zk7nxrjdgr.png)
p1, p1 = p1.left p1 = p1.right 4 p2 = p1.left
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.1pjni9r6tkps.png)
p2.right != null 4 right right p1 = p1.right
![image](https://cdn.jsdelivr.net/gh/tan45du/test@master/image.17t7n8yy340w.png)
p1 ,
On O1
####
```java
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
TreeNode p1 = root; TreeNode p2 = null;
while (p1 != null) {
p2 = p1.left;
if (p2 != null) {
//找到左子树的最右叶子节点
while (p2.right != null && p2.right != p1) {
p2 = p2.right;
}
//添加 right 指针,对应 right 指针为 null 的情况
if (p2.right == null) {
list.add(p1.val);
p2.right = p1;
p1 = p1.left;
continue;
}
//对应 right 指针存在的情况,则去掉 right 指针
p2.right = null;
} else {
list.add(p1.val);
}
//移动 p1
p1 = p1.right;
}
return list;
}
}
```

View File

@ -0,0 +1,207 @@
[]()[]() Morris Morris
##
![](https://cdn.jsdelivr.net/gh/tan45du/test@master/photo/后序遍历.2bx6qccr1q1w.gif)
,` , , , `
``
1.
2.?
![](https://img-blog.csdnimg.cn/20210622160754912.gif)
1.
> 访 cur right 访访 cur
2.
> cur right null cur.right 访 `cur.right != preNode `
>
> `cur = cur.right`
```java
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> list = new ArrayList<>();
TreeNode cur = root;
//这个用来记录前一个访问的节点,也就是橙色箭头
TreeNode preNode = null;
while (cur != null || !stack.isEmpty()) {
//和之前写的中序一致
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
//1.出栈,可以想一下,这一步的原因。
cur = stack.pop();
//2.if 里的判断语句有什么含义?
if (cur.right == null || cur.right == preNode) {
list.add(cur.val);
//更新下 preNode也就是定位住上一个访问节点。
preNode = cur;
cur = null;
} else {
//3.再次压入栈,和上面那条 1 的关系?
stack.push(cur);
cur = cur.right;
}
}
return list;
}
}
```
`cur = stack.pop()` `cur = stack.peek()`便
On, On
Carl
> https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/bang-ni-dui-er-cha-shu-bu-zai-mi-mang-che-di-chi-t/
Morris
## Morris
Morris ,
[]()
![](https://img-blog.csdnimg.cn/20210622155624486.gif)
Morris
![](https://img-blog.csdnimg.cn/20210622142148928.png)
`list.add()`` postMorris() ` list.add() postMorris postMorris Morris
postMorris .
```java
public void postMorris(TreeNode root) {
//反转转链表,详情看下方图片
TreeNode reverseNode = reverseList(root);
//遍历链表
TreeNode cur = reverseNode;
while (cur != null) {
list.add(cur.val);
cur = cur.right;
}
//反转回来
reverseList(reverseNode);
}
//反转链表
public TreeNode reverseList(TreeNode head) {
TreeNode cur = head;
TreeNode pre = null;
while (cur != null) {
TreeNode next = cur.right;
cur.right = pre;
pre = cur;
cur = next;
}
return pre;
}
```
ListNode.next TreeNode.right 线
![](https://img-blog.csdnimg.cn/20210622145335283.png)
绿线
![](https://img-blog.csdnimg.cn/20210622145805876.png)
![](https://img-blog.csdnimg.cn/20210622145846117.png)
```java
class Solution {
List<Integer> list;
public List<Integer> postorderTraversal(TreeNode root) {
list = new ArrayList<>();
if (root == null) {
return list;
}
TreeNode p1 = root;
TreeNode p2 = null;
while (p1 != null) {
p2 = p1.left;
if (p2 != null) {
while (p2.right != null && p2.right != p1) {
p2 = p2.right;
}
if (p2.right == null) {
p2.right = p1;
p1 = p1.left;
continue;
} else {
p2.right = null;
postMorris(p1.left);
}
}
p1 = p1.right;
}
//以根节点为起点的链表
postMorris(root);
return list;
}
public void postMorris(TreeNode root) {
//翻转链表
TreeNode reverseNode = reverseList(root);
//从后往前遍历
TreeNode cur = reverseNode;
while (cur != null) {
list.add(cur.val);
cur = cur.right;
}
//翻转回来
reverseList(reverseNode);
}
public TreeNode reverseList(TreeNode head) {
TreeNode cur = head;
TreeNode pre = null;
while (cur != null) {
TreeNode next = cur.right;
cur.right = pre;
pre = cur;
cur = next;
}
return pre;
}
}
```
On O1
Morris

View File

@ -1,4 +0,0 @@
$$
ED = arg\quad max
$$