Rust二叉元树的深度

半城伤御伤魂 提交于 2020-08-10 22:14:42
二元树的深度
题目:输入一棵二元树的根结点,求该树的深度。
从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
分析:这道题本质上还是考查二元树的遍历。
//==================================二元树的深度
// 错误的深度入口程序
// 这个是错的!留下来单纯是希望记得自己犯过的错误
// 有时候生活就是一路犯错掉坑走过来的。你的回头看看那一路走来的痕迹,思考一下,但是一定不要回头走!
fn deep_main(){
    let n: Node = make_tree();
    let deep: i32 = deep(&n, 1);
    println!("deep :: {:?}", deep);
}
// 正确的深度入口程序
fn deep_main1(){
    let n: Node = make_tree();
    let deep: i32 = deep1(&Some(Box::new(n)), 0);
    println!("deep11111 :: {:?}", deep);
}
/*节点结构*/
#[derive(Debug)]
struct Node {
    pid: isize,
    id: isize,
    name: String,
    left: Option<Box<Node>>,
    right: Option<Box<Node>>,
}
/* 多余的一个节点,用来测试的
Some(Box::new(Node{
    pid: 31,
    id: 41,
    name: String::from("/root/left1/left2/right"),
    left: None,
    right: None,
}))
*/
/*构成节点树*/
fn make_tree() -> Node {
    let tree = Node{
        pid: 0,
        id: 1,
        name: String::from("root"),
        left: Some(Box::new(Node{
            pid: 1,
            id: 21,
            name: String::from("left1"),
            left: Some(Box::new(Node{
                pid: 21,
                id: 31,
                name: String::from("left2"),
                left: None,
                right: None,
                })),
            right: None,
        })),
        right: Some(Box::new(Node{
            pid: 1,
            id: 22,
            name: String::from("right1"),
            left: Some(Box::new(Node{
                    pid: 22,
                    id: 33,
                    name: String::from("left_r2"),
                    left: None,
                    right: Some(Box::new(Node{
                        pid: 33,
                        id: 43,
                        name: String::from("/root/right1/left_r2/right"),
                        left: None,
                        right: None,
                    })),
                })),
            right: Some(Box::new(Node{
                    pid: 22,
                    id: 34,
                    name: String::from("right_r2"),
                    left: None,
                    right: None,
                })),
        })),
    };
    return tree;
}
/*检查深度,此方法有 bug,检查了左边就不检查 右边了。*/
fn deep(node: &Node, cdeep: i32) -> i32{
    match node.left {
        None => {
            match node.right {
                None => {
                    return cdeep;
                },
                _ => {
                    let ndeep = cdeep + 1;
                    return deep(&*(node.right.as_ref().unwrap()), ndeep);
                }
            }
        },
        _ => {
            let ndeep = cdeep + 1;
            return deep(&*(node.left.as_ref().unwrap()), ndeep);
        }
    }
}

// 把 Option<Box<Node>> 变成 &Node
// &*(node.right.as_ref().unwrap())
// 那么 node.right.as_ref() == &Option<Box<Node>>
// node 传入 option有 None的结构,可递归的Box堆分配子结构包裹的Node
// 此方法能正确遍历左右子树
fn deep1(node: &Option<Box<Node>>, cdeep: i32) -> i32{
    match node { //对比这个结构,
        None => {//如果是None
            return cdeep;//直接返回当前界面深度值
        },
        _ => {//如果不是None
            //这一句把Option<Box<None>> 结构解开
            // 先node as_ref(),as_ref()的作用是把 Option<i32> 变成Option<&i32>
            // 再用unwrap解开成Box<Node>
            // *解开Box,成Node,Node再&引用
            let c_node = &*(node.as_ref().unwrap());
            // 这段代码构成缩进空格
            let mut empt = String::from("");
            for _i in 0..cdeep {
                empt.push_str(" ");
            }
            //打印,包含前导空格,打印时用 {}占位,不会出现双引号 {:?}占位会出现双引号
            println!("{}节点:: {:?}", &empt, &c_node.name);
            //深度加1
            let ndeep = cdeep + 1;
            // 遍历 左边,// &c_node.left 含义是 c_node的left的引用
            let ld = deep1(&c_node.left, ndeep);
            // 遍历 右边
            let rd = deep1(&c_node.right, ndeep);
            // 选取最大的返回
            if ld > rd{
                return ld;
            } else if rd > ld {
                return rd;
            }
            else{
                return ld;
            }
        }
    }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!