---
# System prepended metadata

title: 'Tree [Python]'
tags: [Python]

---

# Tree [Python]

## 建構子
> Tree大部分都是採用linked list的解法
```python=
class TreeNode():
    def __init__(self,val,left=None,right=None):
        self.val = val
        self.left = left
        self.right = right
```
## 尋訪走法 Traversal
### 1. PreOrder
![](https://i.imgur.com/MOuiWRA.png =200x)
```python=
def pretraverse(root):
    if root!= None:
        print(root.val)
        pretraverse(root.left)
        pretraverse(root.right)
```
### 2. InOrder
![](https://i.imgur.com/755IgE3.png =200x)
```python=
def intraverse(root):
    if root!= None:
        pretraverse(root.left)
        print(root.val)
        pretraverse(root.right)
```
### 3. PostOrder
![](https://i.imgur.com/mAnRhGy.png =200x)
```python=
def posttraverse(root):
    if root!= None:
        pretraverse(root.left)
        pretraverse(root.right)
        print(root.val)
```
### 4. LevelOrder 
![](https://i.imgur.com/uS6VMOz.png =280x)
:bulb:一定要用Queue處理，先把root pop出去，再把左子樹和右子樹放到queue裡
```python=
import queue
def leveltraverse(root):
    q = queue.Queue()
    q.put(root)
    while not q.empty():
        a = q.get()
        print(a.val)
        if root != None:
            q.put(root.left)
            q.put(root.right)
```            
## 樹的種類 Tree
### 1. Binary Tree (BT)
每個root都會有left child和right child
大部分的問題都是用遞迴解決
* 計算node總數(左子樹的node+右子樹的node+1)
```python=
def countNode(root):
    if root == None:
        return 0
    else:
        left_count = countNode(root.left)
        right_count = countNode(root.right)
    return left_count+right_count+1
``` 
* 計算tree高度(1+Max(左子樹的高度,右子樹的高度)
> Max Depth
```python=
def max_depth(root):
    if root == None:
        return 0
    else:
        left_height = max_depth(root.left)
        right_height = max_depth(root.right)
    return 1+max(left_height, right_height)
``` 
> min depth
```python=
def min_depth(root):
    if root == None:
        return 0
    elif not root.left and root.right:
        return 1+min_depth(root.right)
    elif root.left and not root.right:
        return 1+min_depth(root.left)
    elif root.left and root.right:
        return 1+min(min_depth(root.left), min_depth(root.right)
    return 1
``` 

* 計算leaf總數(左子樹的leaf+右子樹的leaf)
```python=
def countLeaf(root):
    if root == None:
        return 0
    else:
        left_count = countLeaf(root.left)
        right_count = countLeaf(root.right)
        if (left_count+right_count) == 0:
            return 1
        else:
            return left_count+right_count
``` 
* 判斷BT是否相等(左子樹是否相同，右邊子樹是否相同)
```python=
def equal(root1, root2):
    flag = false
    if (root1 == None) and (root2 == None):
        return true
    else if (root1!= None) and (root2 != None):
        if root1.val == root2.val:
            if equal(root1.left, root2.left):
                flag = equal(root1.right, root2.right)
        return flag
    else:
        return false
``` 
### 2. Binary Search Tree (BST)
:bulb:root的val有大小順序之分，root.left < root < root.right
```python=
def BSTinsert(root, val):
    if root == None:
        root = TreeNode(val=val)
        return root
        else:
            if (val < root.val):
                root.left = BSTinsert(root.left,val)
            else:
                root.right = BSTinsert(root.right,val)
        return root
``` 
### 3. AVL Tree
任一左右子樹高度不能相差超過1
* 確認是否為平衡樹(每一個node都要回傳樹的高度再相減)
```python=
def isBalanced(root):
    if root == None:
        return 0
    if (root.left == None) and (root.right == Noen):
        return 1
    left_h = isBalanced(root.left)
    right_h = isBalanced(root.right)
    if abs(left_h - right_h) >=2:
        self.balance = False
    return 1+max(left_h, right_h)
def chek(root):
    self.balance = True
    self.isBalanced(root)
    return self.balance
``` 
### 常見應用題
* 計算root to leaf的路徑總和
![](https://i.imgur.com/VuPIAJf.png =400x)
```python=
def PathSum(root, targetSum):
    if root == None:
        return False
    newtarget = targetSum - root.val
    if newtarget == 0 and root.left == None and root.right == None:
        return True
    if self.targetSum(root.left, targetSum):
        return True
    if self.targetSum(root.right, targetSum):
        return True
    return False
``` 

<br>

###### tags: `Python` 