# 阿里第二輪面試：手寫Java二叉樹

### 二叉樹

``````class Node {
int value;//本節點的值
Node left;//左邊的子節點
Node right;//右邊的子節點

Node(int value) {
this.  value = value;
right = null;
left = null;
}
}``````

``````public class BinaryTree {
Node root;
// ...}``````

### 讓我們一起來實現下

##### 插入元素

• 如果新節點的值低於當前節點的值，我們轉到左子節點
• 如果新節點的值大於當前節點的值，我們將轉到右子節點
• 節點當前爲null時，我們已到達葉節點，我們可以在該位置插入新節點

``````private Node addRecursive(Node current, int value) {
if (current == null) {
return new Node(value);
}
if (value < current.value) {
} else if (value > current.value) {
} else {
return current;
}
return current;
}``````

``````public void add(int value) {
}``````

``````private BinaryTree createBinaryTree() {
BinaryTree bt = new BinaryTree();

return bt;
}``````
##### 查找元素

``````private boolean containsNodeRecursive(Node current, int value) {
if (current == null) {
return false;
}
if (value == current.value) {
return true;
}
return value < current.value
? containsNodeRecursive(current.left, value)
: containsNodeRecursive(current.right, value);
}``````

``````public boolean containsNode(int value) {
return containsNodeRecursive(root, value);
}``````

``````@Test
BinaryTree bt = createBinaryTree();

assertTrue(bt.containsNode(6));
assertTrue(bt.containsNode(4));
assertFalse(bt.containsNode(1));
}``````
##### 刪除元素

``````private Node deleteRecursive(Node current, int value) {
if (current == null) {
return null;
}
if (value == current.value) {
// Node to delete found
// ... code to delete the node will go here
}
if (value < current.value) {
current.left = deleteRecursive(current.left, value);
return current;
}
current.right = deleteRecursive(current.right, value);
return current;
}``````

• 節點沒有子節點 -這是最簡單的情況; 我們只需要在其父節點中用 null 替換此節點
• 節點只有一個子節點 -在父節點中，我們用它唯一的子節點替換該節點。
• 節點有兩個子節點 - 這是最複雜的情況，因爲它需要樹重組

``````if (current.left == null && current.right == null) {
return null;
}``````

``````if (current.right == null) {
return current.left;
}
if (current.left == null) {
return current.right;
}``````

``````private int findSmallestValue(Node root) {
return root.left == null ? root.value : findSmallestValue(root.left);
}``````

``````int smallestValue = findSmallestValue(current.right);
current.value = smallestValue;
current.right = deleteRecursive(current.right, smallestValue);
return current;``````

``````public void delete(int value) {
root = deleteRecursive(root, value);
}``````

``````@Test
public void givenABinaryTree  () {
BinaryTree bt = createBinaryTree();

assertTrue(bt.containsNode(9));
bt.delete(9);
assertFalse(bt.containsNode(9));
}``````

### 深度優先搜索

in-order：首先訪問左子樹，然後訪問根節點，最後訪問右子樹：

``````public void traverseInOrder(Node node) {
if (node != null) {
traverseInOrder(node.left);
System.out.print(" " + node.value);
traverseInOrder(node.right);
}
}``````

``3 4 5 6 7 8 9``

pre-order：首先訪問根節點，然後是左子樹，最後是右子樹：

``````public void traversePreOrder(Node node) {
if (node != null) {
System.out.print(" " + node.value);
traversePreOrder(node.left);
traversePreOrder(node.right);
}
}``````

``6 4 3 5 8 7 9``

post-order：訪問左子樹，右子樹，最後訪問根節點：

``````public void traversePostOrder(Node node) {
if (node != null) {
traversePostOrder(node.left);
traversePostOrder(node.right);
System.out.print(" " + node.value);
}
}``````

``3 5 4 7 9 8 6``

### 廣度優先搜索

``````public void traverseLevelOrder() {
if (root == null) {
return;
}
while (!nodes.isEmpty()) {
Node node = nodes.remove();
System.out.print(" " + node.value);
if (node.left != null) {
}
if (node.right!= null) {
}
}
}``````

``6 4 8 3 5 7 9``

### 最後

“不積跬步，無以至千里”，希望未來的你能成爲：有夢爲馬 隨處可棲！加油，少年！