1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! 2分木を整形して表示する

const LEFT: &str = "  ┌─";
const MID: &str = "  │ ";
const RIGHT: &str = "  └─";
const NULL: &str = "";
const BLANK: &str = "    ";

/// 2分木を整形して表示する
pub trait ShowBinaryTree<P> {
    /// **\<required\>** 左の子のポインタを取得する
    fn get_left(&mut self, ptr: &P) -> Option<P>;

    /// **\<required\>** 右の子のポインタを取得する
    fn get_right(&mut self, ptr: &P) -> Option<P>;

    /// **\<required\>** 根を取得する
    fn get_root(&mut self) -> P;

    /// **\<required\>** ノードの値を表示する
    fn print_node(&mut self, ptr: &P) -> String;

    /// 再帰的にprintを行う
    fn print_inner(&mut self, ptr: P, fill: &mut Vec<&'static str>, last: &'static str) {
        // 表示の調整
        let mut tmp = None;
        if fill.last().is_some_and(|x| x == &last) {
            tmp = fill.pop();
            fill.push(BLANK);
        } else if fill.last().is_some_and(|x| x != &NULL && x != &BLANK) {
            tmp = fill.pop();
            fill.push(MID);
        }
        fill.push(last);

        // 右の子を表示
        if let Some(left) = Self::get_left(self, &ptr) {
            self.print_inner(left, fill, LEFT);
        }

        // 自分を出力
        eprintln!("│{} {}", fill.join(""), self.print_node(&ptr));

        // 右の子を表示
        if let Some(right) = Self::get_right(self, &ptr) {
            self.print_inner(right, fill, RIGHT);
        }

        // 戻す
        fill.pop();
        if let Some(tmp) = tmp {
            fill.pop();
            fill.push(tmp);
        }
    }

    /// 2分木としてフォーマットする
    fn print_as_binary_tree(&mut self) {
        #[cfg(debug_assertions)]
        {
            eprintln!("┌───────────────────────────────────────────────────────");
            let root = Self::get_root(self);
            Self::print_inner(self, root, &mut vec![], NULL);
            eprintln!("└───────────────────────────────────────────────────────");
        }
    }
}