[144. Binary Tree Preorder Traversal (Medium)](https://leetcode.com/problems/binary-tree-preorder-traversal/description/)
```java
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
if (node == null) continue;
ret.add(node.val);
stack.push(node.right); // 先右后左,保证左子树先遍历
stack.push(node.left);
}
return ret;
}
```
## 非递归实现二叉树的后序遍历
[145. Binary Tree Postorder Traversal (Medium)](https://leetcode.com/problems/binary-tree-postorder-traversal/description/)
前序遍历为 root -> left -> right,后序遍历为 left -> right -> root。可以修改前序遍历成为 root -> right -> left,那么这个顺序就和后序遍历正好相反。
```java
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
if (node == null) continue;
ret.add(node.val);
stack.push(node.left);
stack.push(node.right);
}
Collections.reverse(ret);
return ret;
}
```
## 非递归实现二叉树的中序遍历
[94. Binary Tree Inorder Traversal (Medium)](https://leetcode.com/problems/binary-tree-inorder-traversal/description/)
```java
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
if (root == null) return ret;
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode node = stack.pop();
ret.add(node.val);
cur = node.right;
}
return ret;
}
```
# BST
二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点。
二叉查找树中序遍历有序。
## 修剪二叉查找树
[669. Trim a Binary Search Tree (Easy)](https://leetcode.com/problems/trim-a-binary-search-tree/description/)
```html
Input:
3
/ \
0 4
\
2
/
1
L = 1
R = 3
Output:
3
/
2
/
1
```
题目描述:只保留值在 L \~ R 之间的节点
```java
public TreeNode trimBST(TreeNode root, int L, int R) {
if (root == null) return null;
if (root.val > R) return trimBST(root.left, L, R);
if (root.val <L)returntrimBST(root.right,L,R);
root.left = trimBST(root.left, L, R);
root.right = trimBST(root.right, L, R);
return root;
}
```
## 寻找二叉查找树的第 k 个元素
[230. Kth Smallest Element in a BST (Medium)](https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/)
中序遍历解法:
```java
private int cnt = 0;
private int val;
public int kthSmallest(TreeNode root, int k) {
inOrder(root, k);
return val;
}
private void inOrder(TreeNode node, int k) {
if (node == null) return;
inOrder(node.left, k);
cnt++;
if (cnt == k) {
val = node.val;
return;
}
inOrder(node.right, k);
}
```
递归解法:
```java
public int kthSmallest(TreeNode root, int k) {
int leftCnt = count(root.left);
if (leftCnt == k - 1) return root.val;
if (leftCnt > k - 1) return kthSmallest(root.left, k);
return kthSmallest(root.right, k - leftCnt - 1);
}
private int count(TreeNode node) {
if (node == null) return 0;
return 1 + count(node.left) + count(node.right);
}
```
## 把二叉查找树每个节点的值都加上比它大的节点的值
[Convert BST to Greater Tree (Easy)](https://leetcode.com/problems/convert-bst-to-greater-tree/description/)
```html
Input: The root of a Binary Search Tree like this:
5
/ \
2 13
Output: The root of a Greater Tree like this:
18
/ \
20 13
```
先遍历右子树。
```java
private int sum = 0;
public TreeNode convertBST(TreeNode root) {
traver(root);
return root;
}
private void traver(TreeNode node) {
if (node == null) return;
traver(node.right);
sum += node.val;
node.val = sum;
traver(node.left);
}
```
## 二叉查找树的最近公共祖先
[235. Lowest Common Ancestor of a Binary Search Tree (Easy)](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/)
```html
_______6______
/ \
___2_____8__
/ \ / \
0 4 7 9
/ \
3 5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
```
```java
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root.val <p.val&&root.val<q.val)returnlowestCommonAncestor(root.right,p,q);
return root;
}
```
## 二叉树的最近公共祖先
[236. Lowest Common Ancestor of a Binary Tree (Medium) ](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/)
```html
_______3______
/ \
___5_____1__
/ \ / \
6 2 0 8
/ \
7 4
For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
```
```java
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
return left == null ? right : right == null ? left : root;
}
```
## 从有序数组中构造二叉查找树
[108. Convert Sorted Array to Binary Search Tree (Easy)](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/)
```java
public TreeNode sortedArrayToBST(int[] nums) {
return toBST(nums, 0, nums.length - 1);
}
private TreeNode toBST(int[] nums, int sIdx, int eIdx){
if (sIdx > eIdx) return null;
int mIdx = (sIdx + eIdx) / 2;
TreeNode root = new TreeNode(nums[mIdx]);
root.left = toBST(nums, sIdx, mIdx - 1);
root.right = toBST(nums, mIdx + 1, eIdx);
return root;
}
```
## 根据有序链表构造平衡的二叉查找树
[109. Convert Sorted List to Binary Search Tree (Medium)](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/description/)
```html
Given the sorted linked list: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
0
/ \
-3 9
/ /
-10 5
```
```java
public TreeNode sortedListToBST(ListNode head) {
if (head == null) return null;
if (head.next == null) return new TreeNode(head.val);
ListNode preMid = preMid(head);
ListNode mid = preMid.next;
preMid.next = null; // 断开链表
TreeNode t = new TreeNode(mid.val);
t.left = sortedListToBST(head);
t.right = sortedListToBST(mid.next);
return t;
}
private ListNode preMid(ListNode head) {
ListNode slow = head, fast = head.next;
ListNode pre = head;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
return pre;
}
```
## 在二叉查找树中寻找两个节点,使它们的和为一个给定值
[653. Two Sum IV - Input is a BST (Easy)](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/description/)