# 2024q1 Homework4 (quiz3+4)
contributed by < [`Ken-LuWeiRu`](https://github.com/Ken-LuWeiRu) >
## [2024q1 第 4 週測驗題](https://hackmd.io/@sysprog/linux2024-quiz4)
 XTree 是自平衡二元搜尋樹,它結合了 AVL 樹和紅黑樹的特點,旨在提供快速插入和刪除操作同時保持相對優良的平衡性。
- `xt_create` 函數初始化一棵空樹。
- `xt_destroy` 和 `__xt_destroy` 函數負責遞迴銷毀樹及其節點。
- `xt_first` 和 `xt_last` 函數分別找到子樹中最小和最大的節點。
- `xt_rotate_left` 和 `xt_rotate_right` 函數執行基本的樹旋轉操作以幫助維持或恢復平衡。
- `xt_balance` 和 `xt_max_hint` 函數計算樹的平衡因子和更新節點的平衡提示。
- `xt_update` 函數根據節點的平衡情況進行調整以維護整體樹的平衡。
- `__xt_find` 和 `__xt_find2` 函數用於在樹中查找特定鍵值的節點。
- `__xt_insert` 和 `xt_insert` 函數實現節點的插入操作。
- `xt_replace_right` 和 `xt_replace_left` 函數在刪除操作中用來替換節點。
- `__xt_remove` 和 `xt_remove` 函數處理刪除操作,包括選擇適當的替代節點並更新樹以維持平衡。
```graphviz
digraph XTree {
    node [shape=record];
    struct1 [label="XTree | <root> root | cmp | create_node | destroy_node"];
    struct2 [label="xt_node | <left> left | <right> right | hint | <parent> parent"];
    struct3 [label="xt_node | <left> left | <right> right | hint | <parent> parent"];
    struct4 [label="xt_node | <left> left | <right> right | hint | <parent> parent"];
    struct1:root -> struct2 [label="root"];
    struct2:left -> struct3:parent //[label="parent", color="blue"];
    struct2:right -> struct4:parent //[label="parent", color="red"];
    //struct2:parent -> struct2 [label="parent", color="grey"];
}
```
這張圖顯示了 XTree 的基本結構,包括根節點和其他節點之間的關係。每個節點可以有左右子節點和一個父節點。
### 程式碼解釋
#### xt_rotate_left
以下是左旋操作的圖示,紅色虛線表示旋轉後的新連接:
```graphviz
digraph G {
    node [shape=record, style=filled, fillcolor=gray95];
    N [label="n"];
    L [label="l"];
    P [label="p"];
    LR [label="l's right"];
    // Before rotation
    P -> N [label="Parent"];
    N -> L [label="Left child"];
    L -> LR [label="Right child"];
    // After rotation, shown with dashed lines
    edge [color=red, style=dashed];
    P -> L [label="New Parent",color=red];
    L -> N [label="New Right child"];
    N -> LR [label="New Left child"];
}
```
左旋轉前後對比圖(白色是之前,藍色之後):
```graphviz
digraph G {
    node [shape=record, style=filled, fillcolor=gray95];
    // Nodes before rotation
    P [label="p (Parent)"];
    N [label="n (Node to rotate)"];
    L [label="l (Left child of n)"];
    LL [label="ll (Left child of l)"];
    LR [label="lr (Right child of l)"];
    // Nodes after rotation
    P2 [label="p", color="blue"];
    N2 [label="n", color="blue"];
    L2 [label="l", color="blue"];
    LL2 [label="ll", color="blue"];
    LR2 [label="lr", color="blue"];
    // Edges before rotation
    P -> N;
    N -> L;
    L -> LL;
    L -> LR;
    // Edges after rotation
    P2 -> L2 [color="blue", style=dashed];
    L2 -> N2 [color="blue", style=dashed];
    N2 -> LL2 [color="blue", style=dashed];
    L2 -> LR2 [color="blue", style=dashed];
    // Invisible edges for layout
    edge [style=invis];
    P -> P2;
    N -> L2;
    L -> N2;
    LL -> LL2;
    LR -> LR2;
}
```
#### xt_rotate_right
以下是右旋操作的圖示,紅色虛線表示旋轉後的新連接:
```graphviz
digraph G {
    node [shape=record, style=filled, fillcolor=gray95];
    N [label="n"];
    R [label="r"];
    P [label="p"];
    RL [label="r's left"];
    // Before rotation
    P -> N [label="Parent"];
    N -> R [label="Right child before rotation"];
    R -> RL [label="Left child of r"];
    // After rotation, shown with dashed lines
    edge [color=red, style=dashed];
    P -> R [label="New Parent"];
    R -> N [label="New Left child"];
    N -> RL [label="New Right child", color="red"];
}
```
#### xt_update
這是 `xt_update` 函數的操作示意圖:
```graphviz
digraph {
    node [shape=box];
    subgraph cluster_0 {
        label = "xt_update";
        Start [shape=oval, label="Start xt_update"];
        CheckNull [label="Is node NULL?"];
        CalcBalance [label="Calculate balance factor"];
        RotateRight [label="Rotate right"];
        RotateLeft [label="Rotate left"];
        UpdateHint [label="Update hint"];
        End [shape=oval, label="End xt_update"];
    }
    Start -> CheckNull;
    CheckNull -> CalcBalance [label="No"];
    CheckNull -> End [label="Yes"];
    CalcBalance -> RotateRight [label="balance < -1"];
    CalcBalance -> RotateLeft [label="balance > 1"];
    CalcBalance -> UpdateHint [label="balance is ok"];
    RotateRight -> UpdateHint;
    RotateLeft -> UpdateHint;
    UpdateHint -> End;
}
```
#### xt_insert  &  __xt_insert
```graphviz
digraph xt_insert {
    node [shape=record, fontname=Helvetica];
    start [label="開始插入", shape=ellipse];
    find [label="使用 __xt_find\n尋找插入位置"];
    check [label="節點是否已存在?", shape=diamond];
    create [label="創建新節點"];
    insert [label="調用 __xt_insert\n進行實際插入"];
    update [label="調用 xt_update\n平衡樹", shape=box, style=filled, fillcolor=lightgrey];
    end [label="結束插入", shape=ellipse];
    start -> find -> check;
    check -> create [label="否"];
    create -> insert -> update;
    check -> end [label="是"];
    update -> end;
}
```
#### __xt_remove xt_replace_right  xt_replace_left
__xt_remove 使用 xt_replace_right 或 xt_replace_left 來替換節點,在使用 xt_update 來平衡 xtree
以下是 xt_replace_right ,紅色虛線表示旋轉後的新連接:
```graphviz
digraph {
    node [shape=record];
    // Defining nodes
    n [label="{Node n|key: n_key}"];
    r [label="{Replacement Node r|key: r_key}"];
    p [label="{Parent Node p|key: p_key}"];
    rp [label="{Parent of Replacement Node rp|key: rp_key}"];
    nr [label="{Right Child of n|key: nr_key}"];
    rr [label="{Right Child of r|key: rr_key}"];
    // Connecting nodes
    p -> n [label="left or right child"];
    n -> r [label="right child"];
    n -> nr [label="right child", style=dashed];
    rp -> r [label="left or right child"];
    r -> rr [label="right child", style=dashed];
    // After replacement
    p -> r [label="new child", color="red", style=dashed];
    r -> n [label="left child (after rotation)", color="red", style=dashed];
    rp -> rr [label="new child", color="red", style=dashed];
}
```
### 可改進之處
與 AVL 樹和紅黑樹相比,XTree 在插入和刪除操作中尋求更快的執行速度,但可能在保持完美平衡方面稍遜色。改進的方向包括:
1. **平衡策略的優化:** 目前的平衡操作是在插入或刪除後立即執行。考慮引入更智能的策略,例如僅在必要時進行平衡操作,可以減少總體平衡次數,提升效率。
2. **動態調整策略:** 根據樹的大小和操作的特性(如連續插入或刪除),動態調整平衡策略,可能會提高效率。
3. **記憶體管理:** 樹的節點操作經常伴隨記憶體分配和釋放,可以考慮使用記憶體池來管理節點的分配和釋放,以減少記憶體分配的開銷。
#### 循序輸入和亂序輸入的狀況
- **循序輸入:** 在連續插入排序資料時,某些二元搜尋樹(如未平衡的 BST)可能退化成鏈表,導致性能下降。對於 XTree,即使在面對循序輸入時,也應保持一定程度的平衡,避免退化成鏈表。
- **亂序輸入:** 亂序輸入一般有助於保持樹的平衡,但過度的平衡操作可能會導致不必要的性能損耗
XTree 需要在快速插入/刪除與維持樹平衡之間找到適當的平衡點。
#### 代做事項