ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【Rust】树07-平衡二叉树

2022-07-30 23:31:52  阅读:170  来源: 互联网

标签:node mut right 07 tree 二叉树 root Rust left


环境

  • Time 2022-04-21
  • Rust 1.60.0

前言

说明

基于标准库来学习各种数据结构,并不是从头实现数据结构,未考虑实现性能。
二叉树有个不好的地方,就是在最坏情况下,可能退化成单链表的结构。
比如按从小到大的顺序插入,节点都在右孩子上,平衡二叉树(AVL)可以解决这种情况。

示例

引入模块

pub mod avl_tree;

结构定义

基于二叉搜索树实现。

use std::cmp::Ordering;

use super::{binary_search_tree::BinarySearchTree, Node, NodeRef, Tree};

#[derive(Default)]
pub struct AvlTree<T> {
    tree: BinarySearchTree<T>,
}

节点高度

平衡二叉树根据节点的高度来求平衡因子,所以需要一个获取高度的方法。

fn height(tree: &NodeRef<T>) -> usize {
    match tree {
        Some(node) => {
            let left = Self::height(&node.left);
            let right = Self::height(&node.right);
            1 + std::cmp::max(left, right)
        }
        None => 0,
    }
}

左旋

在调整树的平衡过程中,需要使用到左旋操作。

fn left_rotate(root: &mut NodeRef<T>) {
    if let Some(mut node) = root.take() {
        if let Some(mut new_root) = node.right.take() {
            node.right = new_root.left.take();
            new_root.left = Some(node);
            *root = Some(new_root);
        }
    }
}

右旋

在调整树的平衡过程中,需要使用到右旋操作。

fn right_rotate(root: &mut NodeRef<T>) {
    if let Some(mut node) = root.take() {
        if let Some(mut new_root) = node.left.take() {
            node.left = new_root.right.take();
            new_root.right = Some(node);
            *root = Some(new_root);
        }
    }
}

平衡节点

    fn balance_factor(tree: &NodeRef<T>) -> isize {
        match tree {
            None => 0,
            Some(node) => {
                let left = Self::height(&node.left);
                let right = Self::height(&node.right);
                left as isize - right as isize
            }
        }
    }

    fn balance(tree: &mut NodeRef<T>) {
        let balance_factor = Self::balance_factor(tree);
        if balance_factor == 2 {
            let left = &mut tree.as_mut().unwrap().left;
            if Self::balance_factor(left) == -1 {
                Self::left_rotate(left);
            }
            Self::right_rotate(tree);
        } else if balance_factor == -2 {
            let right = &mut tree.as_mut().unwrap().right;
            if Self::balance_factor(right) == 1 {
                Self::right_rotate(right);
            }
            Self::left_rotate(tree);
        }
    }

总结

基于二叉搜索树,来实现平衡二叉树,首先定义了一些后续必须使用到的方法。

附录

源码

impl<T: Ord> AvlTree<T> {
    fn root_mut(&mut self) -> &mut NodeRef<T> {
        self.tree.root_mut()
    }
    fn left_rotate(root: &mut NodeRef<T>) {
        if let Some(mut node) = root.take() {
            if let Some(mut new_root) = node.right.take() {
                node.right = new_root.left.take();
                new_root.left = Some(node);
                *root = Some(new_root);
            }
        }
    }

    fn right_rotate(root: &mut NodeRef<T>) {
        if let Some(mut node) = root.take() {
            if let Some(mut new_root) = node.left.take() {
                node.left = new_root.right.take();
                new_root.right = Some(node);
                *root = Some(new_root);
            }
        }
    }

    fn height(tree: &NodeRef<T>) -> usize {
        match tree {
            Some(node) => {
                let left = Self::height(&node.left);
                let right = Self::height(&node.right);
                1 + std::cmp::max(left, right)
            }
            None => 0,
        }
    }

    fn balance_factor(tree: &NodeRef<T>) -> isize {
        match tree {
            None => 0,
            Some(node) => {
                let left = Self::height(&node.left);
                let right = Self::height(&node.right);
                left as isize - right as isize
            }
        }
    }

    fn balance(tree: &mut NodeRef<T>) {
        let balance_factor = Self::balance_factor(tree);
        if balance_factor == 2 {
            let left = &mut tree.as_mut().unwrap().left;
            if Self::balance_factor(left) == -1 {
                Self::left_rotate(left);
            }
            Self::right_rotate(tree);
        } else if balance_factor == -2 {
            let right = &mut tree.as_mut().unwrap().right;
            if Self::balance_factor(right) == 1 {
                Self::right_rotate(right);
            }
            Self::left_rotate(tree);
        }
    }
}

标签:node,mut,right,07,tree,二叉树,root,Rust,left
来源: https://www.cnblogs.com/jiangbo4444/p/16536151.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有