Skip to content

Commit 1ede11e

Browse files
【二叉树问题】dfs与bfs深度优先与广度优先
1 parent 468d22b commit 1ede11e

File tree

4 files changed

+326
-8
lines changed

4 files changed

+326
-8
lines changed

huawei/src/main/java/BinaryTree.java

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
package main.java;
2+
3+
import java.util.LinkedList;
4+
import java.util.Queue;
5+
import java.util.Stack;
6+
7+
8+
public class BinaryTree {
9+
// 二叉树节点
10+
public static class BinaryTreeNode {
11+
int value;
12+
BinaryTreeNode left;
13+
BinaryTreeNode right;
14+
15+
public BinaryTreeNode(int value) {
16+
this.value = value;
17+
}
18+
}
19+
20+
// 访问树的节点
21+
public static void visit(BinaryTreeNode node) {
22+
System.out.println(node.value);
23+
}
24+
25+
/**
26+
* 递归实现二叉树的先序遍历
27+
*/
28+
public static void preOrder(BinaryTreeNode node) {
29+
if (node != null) {
30+
visit(node);
31+
preOrder(node.left);
32+
preOrder(node.right);
33+
}
34+
}
35+
36+
/**
37+
* 递归实现二叉树的中序遍历
38+
*/
39+
public static void inOrder(BinaryTreeNode node) {
40+
if (node != null) {
41+
inOrder(node.left);
42+
visit(node);
43+
inOrder(node.right);
44+
}
45+
}
46+
47+
/**
48+
* 递归实现二叉树的后序遍历
49+
*/
50+
public static void postOrder(BinaryTreeNode node) {
51+
if (node != null) {
52+
postOrder(node.left);
53+
postOrder(node.right);
54+
visit(node);
55+
}
56+
}
57+
58+
/**
59+
* 非递归实现二叉树的先序遍历
60+
*/
61+
public static void iterativePreorder(BinaryTreeNode node) {
62+
Stack<BinaryTreeNode> stack = new Stack<>();
63+
if (node != null) {
64+
stack.push(node);
65+
while (!stack.empty()) {
66+
node = stack.pop();
67+
// 先访问节点
68+
visit(node);
69+
// 把右子结点压入栈
70+
if (node.right != null) {
71+
stack.push(node.right);
72+
}
73+
// 把左子结点压入栈
74+
if (node.left != null) {
75+
stack.push(node.left);
76+
}
77+
}
78+
}
79+
}
80+
81+
/**
82+
* 非递归实现二叉树的中序遍历
83+
*/
84+
public static void iterativeInOrder(BinaryTreeNode root) {
85+
Stack<BinaryTreeNode> stack = new Stack<>();
86+
BinaryTreeNode node = root;
87+
while (node != null || stack.size() > 0) {
88+
// 把当前节点的全部左侧子结点压入栈
89+
while (node != null) {
90+
stack.push(node);
91+
node = node.left;
92+
}
93+
// 访问节点,处理该节点的右子树
94+
if (stack.size() > 0) {
95+
node = stack.pop();
96+
visit(node);
97+
node = node.right;
98+
}
99+
}
100+
}
101+
102+
/**
103+
* 非递归使用单栈实现二叉树后序遍历
104+
*/
105+
public static void iterativePostOrder(BinaryTreeNode root) {
106+
Stack<BinaryTreeNode> stack = new Stack<>();
107+
BinaryTreeNode node = root;
108+
// 访问根节点时判断其右子树是够被访问过
109+
BinaryTreeNode preNode = null;
110+
while (node != null || stack.size() > 0) {
111+
// 把当前节点的左侧节点所有入栈
112+
while (node != null) {
113+
stack.push(node);
114+
node = node.left;
115+
}
116+
if (stack.size() > 0) {
117+
BinaryTreeNode temp = stack.peek().right;
118+
// 一个根节点被访问的前提是:无右子树或右子树已被访问过
119+
if (temp == null || temp == preNode) {
120+
node = stack.pop();
121+
visit(node);
122+
preNode = node;// 记录刚被访问过的节点
123+
node = null;
124+
} else {
125+
// 处理右子树
126+
node = temp;
127+
}
128+
}
129+
}
130+
}
131+
132+
/**
133+
* 非递归使用双栈实现二叉树后序遍历
134+
*/
135+
public static void iterativePostOrderByTwoStacks(BinaryTreeNode root) {
136+
Stack<BinaryTreeNode> stack = new Stack<>();
137+
Stack<BinaryTreeNode> temp = new Stack<>();
138+
BinaryTreeNode node = root;
139+
while (node != null || stack.size() > 0) {
140+
// 把当前节点和其右侧子结点推入栈
141+
while (node != null) {
142+
stack.push(node);
143+
temp.push(node);
144+
node = node.right;
145+
}
146+
// 处理栈顶节点的左子树
147+
if (stack.size() > 0) {
148+
node = stack.pop();
149+
node = node.left;
150+
}
151+
}
152+
while (temp.size() > 0) {
153+
node = temp.pop();
154+
visit(node);
155+
}
156+
}
157+
158+
/**
159+
* 二叉树广度优先遍历——层序遍历
160+
*/
161+
public static void layerTraversal(BinaryTreeNode root) {
162+
Queue<BinaryTreeNode> queue = new LinkedList<>();
163+
164+
if (root != null) {
165+
queue.add(root);
166+
while (!queue.isEmpty()) {
167+
BinaryTreeNode currentNode = queue.poll();
168+
visit(currentNode);
169+
if (currentNode.left != null) {
170+
queue.add(currentNode.left);
171+
}
172+
173+
if (currentNode.right != null) {
174+
queue.add(currentNode.right);
175+
}
176+
}
177+
}
178+
}
179+
180+
public static void main(String[] args) {
181+
// 构造二叉树
182+
// 1
183+
// / \
184+
// 2 3
185+
// / / \
186+
// 4 5 7
187+
// \ /
188+
// 6 8
189+
BinaryTreeNode root = new BinaryTreeNode(1);
190+
BinaryTreeNode node2 = new BinaryTreeNode(2);
191+
BinaryTreeNode node3 = new BinaryTreeNode(3);
192+
BinaryTreeNode node4 = new BinaryTreeNode(4);
193+
BinaryTreeNode node5 = new BinaryTreeNode(5);
194+
BinaryTreeNode node6 = new BinaryTreeNode(6);
195+
BinaryTreeNode node7 = new BinaryTreeNode(7);
196+
BinaryTreeNode node8 = new BinaryTreeNode(8);
197+
198+
root.left = node2;
199+
root.right = node3;
200+
node2.left = node4;
201+
node3.left = node5;
202+
node3.right = node7;
203+
node5.right = node6;
204+
node7.left = node8;
205+
System.out.println("二叉树先序遍历");
206+
preOrder(root);
207+
System.out.println("二叉树先序遍历非递归");
208+
iterativePreorder(root);
209+
System.out.println("二叉树中序遍历");
210+
inOrder(root);
211+
System.out.println("二叉树中序遍历非递归");
212+
iterativeInOrder(root);
213+
System.out.println("二叉树后序遍历");
214+
postOrder(root);
215+
System.out.println("二叉树单栈非递归后序遍历");
216+
iterativePostOrder(root);
217+
System.out.println("二叉树双栈非递归后序遍历");
218+
iterativePostOrderByTwoStacks(root);
219+
System.out.println("二叉树层树序遍历");
220+
layerTraversal(root);
221+
}
222+
}

huawei/src/main/java/Main.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package main.java;
2+
3+
public class Main {
4+
/**
5+
* 给你一个字符串 s 和一个字符 c ,且 c 是 s 中出现过的字符。
6+
* 返回一个整数数组 answer ,其中 answer.length == s.length 且 answer[i] 是 s 中从下标 i 到离它 最近 的字符 c 的 距离 。
7+
* 两个下标 i 和 j 之间的 距离 为 abs(i - j) ,其中 abs 是绝对值函数。
8+
* 示例 1:
9+
* <p>
10+
* 输入:s = "loveleetcode", c = "e"
11+
* 输出:[3,2,1,0,1,0,0,1,2,2,1,0]
12+
* 解释:字符 'e' 出现在下标 3、5、6 和 11 处(下标从 0 开始计数)。
13+
* 距下标 0 最近的 'e' 出现在下标 3 ,所以距离为 abs(0 - 3) = 3 。
14+
* 距下标 1 最近的 'e' 出现在下标 3 ,所以距离为 abs(1 - 3) = 3 。
15+
* 对于下标 4 ,出现在下标 3 和下标 5 处的 'e' 都离它最近,但距离是一样的 abs(4 - 3) == abs(4 - 5) = 1 。
16+
* 距下标 8 最近的 'e' 出现在下标 6 ,所以距离为 abs(8 - 6) = 2 。
17+
* 示例 2:
18+
* <p>
19+
* 输入:s = "aaab", c = "b"
20+
* 输出:[3,2,1,0]
21+
*  
22+
* 提示:
23+
* 1 <= s.length <= 104
24+
* s[i] 和 c 均为小写英文字母
25+
* 题目数据保证 c 在 s 中至少出现一次
26+
*/
27+
public static void main(String[] args) {
28+
/*
29+
* s = "loveleetcode", c = "e"
30+
// * [1,1,1,0,1,0,0,1,1,1,1,0]
31+
* [3,2,1,0,1,0,0,1,2,2,1,0]
32+
*/
33+
String s = "loveleetcode", c = "e";
34+
func(s, c);
35+
// func("aaab","b");
36+
}
37+
38+
private static void func(String s, String c) {
39+
int[] a = new int[s.length()];
40+
int index = 0;
41+
for (int i = 0; i <= s.length() - 1; i++) {
42+
if (s.charAt(i) == c.charAt(0)) {
43+
a[i] = 0;
44+
//往左
45+
for (int i1 = i - 1; i1 >= index; i1--) {
46+
if (s.charAt(i1) != c.charAt(0)) {
47+
if ((i1 - index) <<2 <i-index) {
48+
a[i1] = Math.abs(i - i1);
49+
} else {
50+
a[i1] = Math.abs(i1 - index);
51+
}
52+
} else {
53+
break;
54+
}
55+
}
56+
index = i;
57+
}
58+
}
59+
for (int i : a) {
60+
System.out.print(i + " ");
61+
}
62+
}
63+
}

leetcode/lcci/04.12.Paths with Sum/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
<p><strong>示例:</strong><br>
1111
给定如下二叉树,以及目标和&nbsp;<code>sum = 22</code>,</p>
1212

13-
<pre> 5
13+
<pre>
14+
5
1415
/ \
1516
4 8
1617
/ / \
Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,57 @@
1-
class Solution {
2-
int ans = 0;
3-
public int pathSum(TreeNode root, int sum) {
1+
import lombok.Data;
2+
3+
/*
4+
5
5+
/ \
6+
4 8
7+
/ / \
8+
11 13 4
9+
/ \ / \
10+
7 2 5 1
11+
*/
12+
public class Solution {
13+
public static void main(String[] args) {
14+
TreeNode root = new TreeNode(new TreeNode(new TreeNode(new TreeNode(null, null, 7), new TreeNode(null, null, 2), 11), null, 4),
15+
new TreeNode(new TreeNode(null, null, 13), new TreeNode(new TreeNode(null, null, 5), new TreeNode(null, null, 1), 4), 8), 5);
16+
int i = pathSum(root, 22);
17+
System.out.println(i);
18+
}
19+
20+
static int ans = 0;
21+
22+
public static int pathSum(TreeNode root, int sum) {
423
traverse(root, sum);
524
return ans;
625
}
726

8-
void traverse(TreeNode root, int sum) {
27+
static void traverse(TreeNode root, int sum) {
928
if (root == null) return;
1029
ans += dfs(root, sum, 0);
11-
traverse(root.left, sum);
30+
traverse(root.left, sum);
1231
traverse(root.right, sum);
1332
}
1433

1534
// check if sum of path is sum.
16-
int dfs(TreeNode root, int sum, int cur) {
35+
static int dfs(TreeNode root, int sum, int cur) {
1736
if (root == null) return 0;
1837
cur += root.val;
1938
int res = 0;
2039
if (cur == sum) res++;
21-
res += dfs(root.left, sum, cur);
40+
res += dfs(root.left, sum, cur);
2241
res += dfs(root.right, sum, cur);
2342
return res;
2443
}
44+
}
45+
46+
@Data
47+
class TreeNode {
48+
TreeNode left;
49+
TreeNode right;
50+
int val;
51+
52+
public TreeNode(TreeNode left, TreeNode right, int val) {
53+
this.left = left;
54+
this.right = right;
55+
this.val = val;
56+
}
2557
}

0 commit comments

Comments
 (0)