【数据结构与算法】二叉搜索树和平衡二叉树

二叉搜索树

左子树的结点都比当前结点小,右子树的结点都比当前结点大。

构造二叉搜索树:

let arr = [3, 4, 7, 5, 2]function Node(value) {this.value = valuethis.left = nullthis.right = null
}/*** 添加结点* @param root 当前结点* @param num 新的结点的值*/
function addNode(root, num) {if (root == null) returnif (root.value == num) returnif (root.value < num) {if (root.right == null) root.right = new Node(num)else addNode(root.right, num)} else {if (root.left == null) root.left = new Node(num)else addNode(root.left, num)}
}function binarySearchTree(arr) {if (arr == null || arr.length == 0) return nulllet root = new Node(arr[0])for (let i = 1; i < arr.length; i++) {addNode(root, arr[i])}return root
}
let root = binarySearchTree(arr)
console.dir(root)

image.png

二叉搜索树的应用:

let arr = [3, 4, 7, 5, 2]function Node(value) {this.value = valuethis.left = nullthis.right = null
}/*** 添加结点* @param root 当前结点* @param num 新的结点的值*/
function addNode(root, num) {if (root == null) returnif (root.value == num) returnif (root.value < num) {if (root.right == null) root.right = new Node(num)else addNode(root.right, num)} else {if (root.left == null) root.left = new Node(num)else addNode(root.left, num)}
}function binarySearchTree(arr) {if (arr == null || arr.length == 0) return nulllet root = new Node(arr[0])for (let i = 1; i < arr.length; i++) {addNode(root, arr[i])}return root
}function searchByTree (root,target) {if (root == null) return falseif (root.value == target) return trueif (root.value > target) return searchByTree(root.left, target)else return searchByTree(root.right, target)
}let root = binarySearchTree(arr)
console.log(searchByTree(root, 4))

平衡二叉树

  • 根节点的左子树和右子树的高度处不能超过1
  • 每棵子树都符合上述规则

image.png

function Node(value) {this.value = valuethis.left = nullthis.right = null
}let a = new Node('a')
let b = new Node('b')
let c = new Node('c')
let d = new Node('d')
let e = new Node('e')
let f = new Node('f')
let g = new Node('g')
let h = new Node('h')
let j = new Node('j')
a.left = b
a.right = c
b.left = d
b.right = e
c.left = f
c.right = g
d.right = h
e.right = jfunction getDeep(root) {if (root == null) return 0let leftDeep = getDeep(root.left)let rightDeep = getDeep(root.right)return Math.max(leftDeep, rightDeep) + 1
}function isBalance(root) {if (root == null) return truelet leftDeep = getDeep(root.left)let rightDeep = getDeep(root.right)if (Math.abs(leftDeep - rightDeep) > 1) {return false} else {return isBalance(root.left) && isBalance(root.right)}
}console.log(getDeep(a))
console.log(isBalance(a))

单旋

某一节点不平衡,如果左边浅,右边深,进行左单旋。

image.png

  • 旋转节点:不平衡的节点为旋转节点(2)
  • 新根:旋转之后称为根节点的节点(5)
  • 变化分支:父级节点发生变化的那个分支
  • 不变分支:父级节点不变的那个分支

左单旋时:

  • 旋转节点:当前不平衡的节点 2
  • 新根:右子树的根节点 5
  • 变化分支:旋转节点的右子树的左子树 3
  • 不变分支:旋转节点的右子树的右子树 6

image.png

右单旋时:

  • 旋转节点:当前不平衡的节点 6
  • 新根:左子树的根节点 3
  • 变化分支:旋转节点的左子树的右子树 5
  • 不变分支:旋转节点的左子树的左子树 2

步骤:

  • 进行左单旋
    1. 找到新根
    1. 找到变化分支
    1. 当前旋转节点的右孩子为变化分支
    1. 新根的左孩子为旋转节点
    1. 返回新的根节点
  • 进行右单旋
    1. 找到新根
    1. 找到变化分支
    1. 当前旋转节点的左孩子为变化分支
    1. 新根的右孩子为旋转节点
    1. 返回新的根节点
function Node(value) {this.value = valuethis.left = nullthis.right = null
}let node2 = new Node('2')
let node5 = new Node('5')
let node3 = new Node('3')
let node6 = new Node('6')
node2.right= node5
node5.left = node3
node5.right = node6function getDeep(root) {if (root == null) return 0let leftDeep = getDeep(root.left)let rightDeep = getDeep(root.right)return Math.max(leftDeep, rightDeep) + 1
}function isBalance(root) {if (root == null) return truelet leftDeep = getDeep(root.left)let rightDeep = getDeep(root.right)if (Math.abs(leftDeep - rightDeep) > 1) {return false} else {return isBalance(root.left) && isBalance(root.right)}
}function leftRotate (root){// 找到新根let newRoot= root.right// 找到变化分支let changeBranch  = root.right.left// 当前旋转接点的右节点变为变化分支root.right = changeBranch// 新根的左节点变为旋转分支newRoot.left = root// 返回新的根节点return newRoot
}
function rightRotate (root){let newRoot = root.leftlet changeBranch = root.left.rightroot.left = changeBranchnewRoot.right = rootreturn newRoot
}/*** 平衡二叉树* @param root 根节点* @returns {*|boolean} 平衡后的根节点*/
function change(root) {if (isBalance(root)) return rootif (root.left != null) root.left = change(root.left)if (root.right != null) root.right = change(root.right)let leftDeep = getDeep(root.left)let rightDeep = getDeep(root.right)if (Math.abs(leftDeep - rightDeep < 2)) {return true} else if (leftDeep > rightDeep) {// 左边深 右旋return rightRotate(root)}  else {// 右边深 左旋return  leftRotate(root)}
}console.log(isBalance(node2))
let newRoot = change(node2)
console.log(isBalance(newRoot))

双旋

有些情况只有一次单选是实现不了的,比如下面的情况:

变化分支(6,7)不可以是唯一的最深分支。

image.png

如果变化分支(6,7)是唯一的最深分支,那么需要先进行依次左旋,再进行右旋。也就是需要双旋。

image.png

二叉树的双旋(左右双旋,右左双旋)

当要对某个节点进行左单旋时,如果变化分支是唯一的最深分支,那么我们要对新根进行右单旋,然后再进行左单旋,这样的旋转叫做右左双旋

当要对某个节点进行右单旋时,如果变化分支是惟一的最深分支,那么我们要对新根进行左单旋,然后再进行右单旋,这样的旋转叫做左右双旋

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/295750.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Xen Server 8 Install

Xen Sevrer 前言 XenServer&#xff08;以前称为 Citrix Hypervisor&#xff09;是业界领先的平台&#xff0c;实现了经济高效的桌面、服务器和云虚拟化基础结构。XenServer 支持任意规模或类型的组织整合计算资源&#xff0c;以及将计算资源转换为虚拟工作负载&#xff0c;从…

【Python项目】AI动物识别工具

目录 背景 技术简介 系统简介 界面预览 背景 成像技术在全球科技发展中扮演了关键角色。在科学研究领域&#xff0c;拍摄所得的图像成为了一种不可或缺的研究工具。特别是在生态学与动物学研究中&#xff0c;鉴于地球的广阔地域和多样的气候条件&#xff0c;利用图像技术捕…

SQLite中的隔离(八)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite版本3中的文件锁定和并发(七&#xff09; 下一篇&#xff1a;SQLite 查询优化器概述&#xff08;九&#xff09; 数据库的“isolation”属性确定何时对 一个操作的数据库对其他并发操作可见。 数据库连接之…

Hadoop安装部署-SecondaryNameNode备份版

Hadoop分布式文件系统支持NameNode节点的高可用性&#xff0c;本文主要描述Secondary NameNode数据备份版本的安装部署。 如上所示&#xff0c;NameNode主节点同步数据到NameNode备份节点&#xff0c;当NameNode主节点发生故障变得不可用时&#xff0c; NameNode主节点重新启动…

关联对象介绍

关联对象的作用 在分类里面&#xff0c;不可以直接为分类添加属性 在代理中&#xff0c;不可以直接为代理添加属性 在普通类中&#xff0c;property (assign, nonatomic) int age; 会做三件事&#xff1a; 生成age的成员变量生成age的get、set方法的声明生成age的get、set方…

【论文通读】UFO:A UI-Focused Agent for Windows OS Interaction

UFO&#xff1a;A UI-Focused Agent for Windows OS Interaction 前言AbstractMotivationMethodsExperimentConclusion 前言 Windows客户端第一个JARVIS&#xff0c;利用GPT4 Vision识别截图信息辅助智能体自动化执行操作&#xff0c;作为微软大肆宣传的一篇工作&#xff0c;其…

如何使用 Python 本地客户端操作读写云服务器 Redis 缓存数据库详细教程(更新中)

Redis 基本概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的使用 ANSI C 语言编写的、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库&#xff0c;并提供多种语言的 API。它通常被称为数据结构服务器&#xff0c;因为值&#xff08;value…

【OpenCV】 基础入门(一)初识 Mat 类 | 通过 Mat 类显示图像

&#x1f680; 个人简介&#xff1a;CSDN「博客新星」TOP 10 &#xff0c; C/C 领域新星创作者&#x1f49f; 作 者&#xff1a;锡兰_CC ❣️&#x1f4dd; 专 栏&#xff1a;【OpenCV • c】计算机视觉&#x1f308; 若有帮助&#xff0c;还请关注➕点赞➕收藏&#xff…

部署项目遇到的各种问题总结

文章目录 前言一、后端问题 jar包运行出现错误宝塔面板使用jdk17二、数据库问题 版本问题三、前端问题 连不上后端总结 前言 在做完项目之后&#xff0c;为了让别人访问到自己的网站&#xff0c;就需要部署前端后端以及数据库&#xff0c;但是在部署的过程中出现了各种问题和困…

docker 部署 nali 开源 IP 地理信息归属查询软件

前言 早前用到一个小巧开源的 IP 归属地查询软件&#xff0c;官方提供了 Dockerfile&#xff0c;使用了一段时间觉得还不错&#xff0c;非常简单便捷。 部署 docker 启动 由于该项目会在首次启动自动下载 IP 数据库,所以最好通过挂载目录的方式,将数据库目录挂在到本地,避免…

【C语言】2048小游戏【附源码】

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 一、游戏描述&#xff1a; 2048是一款数字益智类游戏&#xff0c;玩家需要使用键盘控制数字方块的移动&#xff0c;合并相同数字的方块&#xff0c;最终达到数字方块上出现“2048”的目标。 每次移动操作&#xff0c;所…

C++进阶--C++11(1)

C11是C编程语言的一个版本&#xff0c;于2011年发布。C11引入了许多新特性&#xff0c;为C语言提供了更强大和更现代化的编程能力。这篇文章将对C11的一些新增特性进行讲解和实际应用场景。 统一的列表初始化 {}初始化 在C98中&#xff0c;使用{}符号的一般只仅限于对数组和…

基于蚁群算法的三维路径规划(matlab实现)

作品简介 1 理论基础 1.1 三维路径规划问题概述 三维路径规划指在已知三维地图中&#xff0c;规划出一条从出发点到目标点满足某项指标最优&#xff0c;并且避开了所有三维障碍物的三维最优路径。现有的路径规划算法中&#xff0c;大部分算法是在二维规划平面或准二维规划平面…

今日头条signature参数js逆向(爬虫)

今日头条是ajax动态加载 话不多说&#xff0c;直接上代码 windowglobal;window.location{"ancestorOrigins": {},"href": "https://www.toutiao.com/","origin": "https://www.toutiao.com","protocol": "…

连接Redis不支持集群错误,ERR This instance has cluster support disabled,解决方案

1. 问题背景 调整redis的配置后&#xff0c;启动程序时&#xff0c; 会报如下错误&#xff1a; [redis://172.16.0.8xxx]: ERR This instance has cluster support disabledSuppressed: io.lettuce.core.RedisCommandExecutionException: ERR This instance has cluster supp…

【C++】二分查找算法(模板)

重点 只需要记住两点&#xff1a; 1.left right 时&#xff0c;一定就是最终结果&#xff08;包括找不到目标值&#xff09;&#xff0c;无需再次判断&#xff0c;如果判断就会死循环 2.求中点如果是求左端点 mid left (right - left)/2 如果是求右端点 mid left (right -…

MATLAB 自定义均值滤波 (53)

MATLAB 自定义均值滤波 (53) 一、算法介绍二、算法实现1.原理2.代码一、算法介绍 均值滤波,是一种常见的点云平滑算法,改善原始点云的数据质量问题,MATLAB自带的工具似乎不太友好,这里提供自定义实现的点云均值滤波算法,具体效果如下所示: 均值滤波前: 均值滤波后:…

计算机网络 - 基础篇总结

TCP/IP 网络模型有哪几层&#xff1f; 1.应用层 为用户提供应用功能 2.传输层 负责为应用层提供网络支持 使用TCP和UDP 当传输层的数据包大小超过 MSS&#xff08;TCP 最大报文段长度&#xff09; &#xff0c;就要将数据包分块&#xff0c;这样即使中途有一个分块丢失或损坏…

算法学习——LeetCode力扣图论篇2(1020. 飞地的数量、130. 被围绕的区域、827. 最大人工岛)

算法学习——LeetCode力扣图论篇2 1020. 飞地的数量 1020. 飞地的数量 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个大小为 m x n 的二进制矩阵 grid &#xff0c;其中 0 表示一个海洋单元格、1 表示一个陆地单元格。 一次 移动 是指从一个陆地单元格走到另一个相…

【linux】lsof命令使用

1. 功能 lsof list open files, 列出被进程所使用的文件名称。 2. 基础语法 3. 参数含义 参数含义-a过滤出多个选项要同时满足的文件-U仅列出UNIX-like系统的socket文件类型。-u指定用户&#xff0c;比如-u atiaisi&#xff0c;会把用户atiaisi相关的进程使用的文件列出来。…