avl树 golang实现

golang实现高度平衡二叉树(AVL树) AVL树简介 AVL 树是高度相对平衡(abs(height(node.lchild - height(node.rchild) < 2))的二叉搜索树。它和二叉搜索树主要的区别在AVL是高度平衡的,不会出现二叉搜索树极端情况:线性链表 搜索复杂度为N 。 实现上,AVL树在插入节点和删除节点时要不断调整树,使其处在一个平衡状态。和二叉搜索树相比主要增加树旋转、调整。 实现源码 ... 阅读详情

#Tree


术语:
- 树
- 根
- 节点
- 叶子
- 层次, 根节点
- 深度
- 树的高度, 空树的深度为`-1`, 根的深度为`0`, 一个节点的高度为`0`, 所有的树叶的高度都为`0`。


---


##二叉树
每个节点最多有两个孩子,空树也是一棵二叉树,链表是一种特殊的二叉树。


## 二叉排序树(二叉搜索树,B树)


## 满二叉树


## 完全二叉树


## AVL树
AVL树本质上还是一棵二叉搜索树(因此读者可以看到我后面的代码是继承自二叉搜索树的),它的特点是:


1. 本身首先是一棵二叉搜索树。 
2. 带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。 


例如:
```
     5              5
    / \            / \
   2   6          2   6
  / \   \        / \
 1   4   7      1   4
    /              /
   3              3
```
上图中,左边的是AVL树,而右边的不是。因为左边的树的每个结点的左右子树的高度之差的绝对值都最多为1,而右边的树由于结点6没有子树,导致根结点5的平衡因子为2。


假设有一个结点的平衡因子为2(在AVL树中,最大就是2,因为结点是一个一个地插入到树中的,一旦出现不平衡的状态就会立即进行调整,因此平衡因子最大不可能超过2),那么就需要进行调整。由于任意一个结点最多只有两个儿子,所以当高度不平衡时,只可能是以下四种情况造成的:


- 对该结点的左儿子的左子树进行了一次插入(`LL`)。


- 对该结点的左儿子的右子树进行了一次插入(`LR`)。


- 对该结点的右儿子的左子树进行了一次插入(`RL`)。


- 对该结点的右儿子的右子树进行了一次插入(`RR`)。


情况1和4是关于该点的镜像对称,同样,情况2和3也是一对镜像对称。因此,理论上只有两种情况,当然了,从编程的角度来看还是四种情况。


第一种情况是插入发生在“外边”的情况(即左-左的情况或右-右的情况),该情况可以通过对树的一次单旋转来完成调整。第二种情况是插入发生在“内部”的情况(即左-右的情况或右-左的情况),该情况要通过稍微复杂些的双旋转来处理。




`旋转:`


###单旋转
情况1(`LL`):对该结点的左儿子的左子树进行了一次插入。
![](http://blog.chinaunix.net/attachment/201108/14/25324849_1313308607C3xL.jpg)




左边为调整前得节点,我们可以看出k2的左右子树已不再满足AVL平衡条件,调整后的为右图。


由于K2的左孩子已经变大了,所以应该降低K1的高度,把K1往上提,而K2相应也得往下降。k2下降在k1的右子树(因为k1的左子树增加了,所以不可能再把k2降到k1的左子树上),Y变为K2的左子树(如果Y变成K2的有子树,那么k2的本身没有了左子树,还降为右子树,那么就一减一加,左右失调,平衡因子变成2)。


情况2(`LR`):对该节点的左孩子进行了一次插入
![](../../pic/2676FCA1-CF64-48B2-B4A7-73C41E8C16A7.png)


先从最先失去平衡的节点开始分析,B的left为h,right为h+2,失去平衡,c往上提,B往下提,以致降低整棵树的高度(可以理解为`B,Bl,C,Cl,Cr`这颗树,先把A ignore),C已经平衡,但是A失去平衡,C往上提,A往下降,以致降低整棵树(`C,A,Ar`),Cr连到A的left防止A的right变大而失去平衡,最终C,B,A都已经平衡。


其实他们之间的方法都是一致的,高的节点往上提已经降低其高度,高的往下提,增加高度。这里的***高度可以理解为树的高度***, 他们采用的是一种策略,这是一种平衡左右子树的`趋势`


情况3(`RR`):


![](../../pic/7109344F-642A-4AC0-9F89-9B576FB59578.png)




情况4(`RL`)


![](../../pic/1CB097E6-D404-4CEC-8442-1DE3B3096A52.png)
实现代码:


---
---


## B-树,B+树


---


---




package main

import (
	"fmt"
)

type DataType int
type Node AVLTreeNode
type AVLTree *AVLTreeNode

type AVLTreeNode struct {
	key   DataType
	high  int
	left  *AVLTreeNode
	right *AVLTreeNode
}

func main() {
	data := []DataType{3, 2, 1, 4, 5, 6, 7, 16, 15, 14, 13, 12, 11, 10, 8, 9}
	fmt.Println(data)
	var root AVLTree = nil
	for _, value := range data {
		root = avl_insert(root, value)
		fmt.Println(" root -> key: ", root.key, "high :", root.high, "left", root.left, "right: ", root.right)
	  //  preorder(root)
	}
	preorder(root)
	fmt.Println()
	midorder(root)
	fmt.Println()
}


func highTree(p AVLTree) int {
	if p == nil {
		return -1
	} else {
		return p.high
	}
}

func max(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

/*Please look LL*/
func left_left_rotation(k AVLTree) AVLTree {
	var kl AVLTree
	kl = k.left
	k.left = kl.right
	kl.right = k
	k.high = max(highTree(k.left), highTree(k.right)) + 1
	kl.high = max(highTree(kl.left), k.high) + 1
	return kl
}

/*Please look RR*/
func right_right_rotation(k AVLTree) AVLTree {
	var kr AVLTree
	kr = k.right
	k.right = kr.left
	kr.left = k
	k.high = max(highTree(k.left), highTree(k.right)) + 1
	kr.high = max(k.high, highTree(kr.right)) + 1
	return kr
}

/*so easy*/
func left_righ_rotation(k AVLTree) AVLTree {
	k.left = right_right_rotation(k.left)
	return left_left_rotation(k)
}

func right_left_rotation(k AVLTree) AVLTree {
	k.right = left_left_rotation(k.right)
	return right_right_rotation(k)
}

func avl_insert(avl AVLTree, key DataType) AVLTree {
	if avl == nil {
		avl = new(AVLTreeNode)
		if avl == nil {
			fmt.Println("avl tree create error!")
			return nil
		}else {
			avl.key = key
			avl.high = 0
			avl.left = nil
			avl.right = nil
		}
	} else if key < avl.key {
		avl.left = avl_insert(avl.left, key)
		if highTree(avl.left)-highTree(avl.right) == 2 {
			if key < avl.left.key { //LL
				avl = left_left_rotation(avl)
			} else { // LR
				avl = left_righ_rotation(avl)
			}
		}
	} else if key > avl.key {
		avl.right = avl_insert(avl.right, key)
		if (highTree(avl.right) - highTree(avl.left)) == 2 {
			if key < avl.right.key { // RL
				avl = right_left_rotation(avl)
			} else {
				fmt.Println("right right", key)
				avl = right_right_rotation(avl)
			}
		}
	} else if key == avl.key {
		fmt.Println("the key", key, "has existed!")
	}
	//notice: update high(may be this insert no rotation, so you should update high)
	avl.high = max(highTree(avl.left), highTree(avl.right)) + 1
	return avl
}

func preorder(avl AVLTree) {
	if avl != nil {
		fmt.Print(avl.key, "\t")
		preorder(avl.left)
		preorder(avl.right)
	}
}

func midorder(avl AVLTree) {
	if avl != nil {
		midorder(avl.left)
		fmt.Print(avl.key, "\t")
		midorder(avl.right)
	}
}

/*display avl tree*/
func display(avl AVLTree) {

}



go语言:实现avl 树(附完整源码) 阅读详情

相关推荐

Go-Sparkzstd-用golang编写的zstd解压缩程序

Sparkzstd - 用golang编写的zstd解压缩程序

Spark初识

Spark的背景、定义、特点 背景 MapReduce框架局限性 仅支持Map和Reduce两种操作,提供给用户的只有这两种操作 编程复杂度略高,学习和使用成本略高。 处理效率低效 Map中间结果写磁盘,Reduce写HDFS,多个MR之间通过HDFS交换数据 任务调度和启动开销大 在机器学习、图计算等方面支持有限,性能效率表现比较差。 mapreduce的机器学习框架,称为mahout。 定义 专为大规模数据处理而设计的快速通用的计

qq_57011804的博客 2620

Vue项目实战:海康WebControl插件从安装到预览功能全流程(附RSA加密避坑指南)

本文详细介绍了在Vue项目中集成海康威视WebControl插件的全流程,从环境准备、插件部署到核心功能实现。重点解析了使用JS_RequestInterface获取RSA公钥并进行加密参数初始化的关键步骤与常见避坑指南,帮助开发者高效完成监控视频预览功能的开发与调试。

linux6sysadmin的博客 1227

golang能做大数据开发吗?主流的开发框架有哪些?

一种快速的大规模数据处理框架,支持批处理和流式数据处理,可以使用 Golang 编写 Spark 应用程序。Golang 在大数据领域的应用越来越广泛,可以处理大规模的数据集,同时具有高并发,低延迟和高可用性等优点。:一种分布式的流式数据处理框架,具有低延迟和高吞吐量的特点,支持包括 Golang 在内的多种编程语言。:一种开源的容器编排系统,可以管理和调度大规模的容器化应用程序,同时也支持 Golang 开发。:一种流式数据处理框架,可以处理批处理数据和流式数据,支持多种计算引擎和数据存储系统。

学亮编程手记 2675

车载测试工程师必备:5分钟搞定CANoe台架搭建(附DBC导入技巧)

本文为车载测试工程师提供快速搭建CANoe测试台架的实用指南,涵盖硬件连接、DBC文件导入及常见报错解决方案。通过详细步骤和高效技巧,帮助工程师在5分钟内完成台架搭建,提升车载测试效率,特别适合紧急功能验证场景。

potato的博客 812

51单片机学习(5)-----蜂鸣器的介绍与使用

蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计 算机、 打印机、 复印机、 报警器、 电子玩具、 汽车电子设备、 电话机、 定 时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。1.半导体三极管也称为晶体三极管,可以说它是电子电路中最重要的器件。三极管顾名思义具有三个电极。二极管是由一个PN结构成的,而三极管由两个PN结构成,共用的一个电极成为三极管的基极(用字母b表示)。其他的两个电极成为集电极(用字母c表示)和发射极(用字母e表示)。

2302_80260350的博客 1万+

2024年Go最全Go异常处理——defer、panic、recover,Golang零基础

事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!二、panic和recover(宕机和宕机恢复)

2401_84920027的博客 1316

Pytorch(一) Pytorch 的安装

安装步骤 1.检查是否有合适的GPU, 若有安装Cuda与CuDNN 2.下载pytorch安装文件,进行pytorch的安装 检查电脑是否有合适的GPU 在桌面上右击如果能找到NVIDA控制面板,则说明该电脑有GPU。控制面板如下,并通过查看系统信息获取支持的Cuda版本 点击 帮助->点击 系统信息 弹出下面的对话框,在驱动程序版本那一栏就能看到该计算机使用的驱动版本。 ...

开开心心 25万+

Apache Spark Connect Go 项目常见问题解决方案

Apache Spark Connect Go 项目常见问题解决方案 项目基础介绍 Apache Spark Connect Go 是一个实验性的客户端项目,旨在为 Apache Spark 提供一个用 Golang 编写的连接客户端。该项目目前处于高度实验阶段,不建议在生产环境中使用。Apache Spark 是一个开源的分布式计算系统,广泛用于大数据处理和分析。Spark Connect Go...

gitblog_00832的博客 463

[前沿技术] AMD FSR 1.0源码解析:EASU算法实现细节与优化策略

本文深入解析了AMD FSR 1.0技术的核心——EASU(边缘自适应空间升频)算法。通过剖析其源码,详细阐述了EASU如何利用12-tap采样窗口、基于Lanczos滤波器的多项式近似以及自适应的边缘检测机制,在无需AI模型的情况下实现高质量图像放大。文章重点揭示了其极致的GPU优化策略,包括寄存器利用、采样优化和避免动态分支,为理解高性能图形算法提供了绝佳范例。

docker7nomad的博客 540

1. 动手开发第一个 SAP CDS View

在开始学习前,大家需要根据这篇文章介绍的步骤,在自己本地电脑上,把 ABAP Development Tool 安装好。右键单击这个添加好的 ABAP 开发包,选择新建一个 ABAP Repository Object,类型就选择。,就可以像在 SAPGUI 里使用 SE16 那样,查看这个 CDS View 的内容。笔者下一篇文章,会详细介绍我们创建的第一个 CDS View 的每一行代码的详细含义。从本文开始,正式进入 CDS View 开发的学习。的条件,然后点击 Run 重新执行,得到结果。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1271

2024年最新【算法学习】剑指 Offer 64(2),2024年最新vue总结来了

--### c// 2的14次正好超过10000// 等差数列求和公式n * (n + 1) / 2public:// 2的14次正好超过10000// 等差数列求和公式n * (n + 1) / 2# 2的14次正好超过10000# 等差数列求和公式n * (n + 1) / 2ans = 0a = nb = n + 1// 2的14次正好超过10000// 等差数列求和公式n * (n + 1) / 2ans += a。

2401_84910839的博客 593

从养殖场到科技前沿:YOLOv11+OpenCV精准计数鸡蛋与鸡

YOLOv11结合OpenCV技术,精准识别和计数鸡蛋与鸡,广泛应用于养殖场、市场监控和自动化包装。通过深度学习与计算机视觉,提升农业生产效率,让智能化管理更简单高效。

专注于深入研究多种编程语言,以实战为导向,逐步拓展开发技能,提升工程化编码和思维能力,展现无敌技术实力。 1205

golang实现AVL树算法 【AVL树】【算法】【golang】

golang avl树算法 package main import ( "fmt" ) var nodeCnt int type Node struct { val int left, right *Node h int } func max(i, j int) int { if i > j { return i } return j } func min(i, j int) int { if i < j { return i

LYR 的博客 662

零基础入门Simulink——基于Simulink的MIMO-OFDM系统仿真建模示例

MIMO概述MIMO技术利用多个天线进行信号发送和接收,通过空间复用来提高数据传输速率,或通过空间分集来增强信号的可靠性。OFDM概述OFDM是一种将高速率数据流分成多个低速数据流并行传输的技术,每个子载波都采用调制方式(如BPSK、QPSK),并通过IFFT/FFT变换实现串并转换。MIMO-OFDM优势结合了MIMO的空间分集增益与OFDM对抗多径效应的能力,适用于宽带无线通信系统。提供了更高的数据速率和更好的频谱效率,是现代无线通信标准(如4G LTE、5G NR等)的核心技术之一。

amy_mhd的博客 888

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【数据结构 -- AVL树】c语言和go语言实现

本文讲述了AVL的性质、实现思想及代码实现,更正了代码实现部分,使用 C 语言和 Go 语言实现AVL树

2401_87046050的博客 1532

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

(22)Go实现AVL树-实现和测试

继上一篇 《(21)Go实现AVL树-算法解析》 的后续 https://www.jianshu.com/p/943243f5ee1e AVL树的定义和实现 type node struct { key int value int height int left *node right *node } type avlTree struct { size int Ro...

哥斯拉啊啊啊哦的博客 393

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

golang实现AVL树

AVL树是带有平衡条件的二叉查找树 特点:AVL树中每个节点的左子树和右子树的高度最多差1   旋转:由于插入操作可能会破坏AVL树的平衡特性,故在插入完成之前通过对树进行简单修正来恢复平衡 示例代码如下: package main import ( "fmt" ) type avlTreeNode struct { key int high int

skh2015java的博客 1424

《零基础Go语言算法实战》【题目 5-6】用 Go 语言实现一棵 AVL 树

用Go语言实现一棵AVL树,注意不能使用Go语言内置函数。题目明确要实现AVL树,用Go语言实现AVL树即可。fmt.Println("\n插入了如下树")fmt.Println("\n删除了如下树")【题目5-6】用Go语言实现一棵AVL树。fmt.Println("空树")//向AVL树中插入一个节点。//从AVL树中删除单个节点。《零基础Go语言算法实战》②Go语言实现。

shirdon-廖显东的博客 347

(21)Go实现AVL树-算法解析

了解avltree树之前先了解几个概念 // 1)什么是二分搜索树; 2)什么是平衡树; 3)什么自平衡二分搜索树; 1)二分搜索树以及缺陷 // 如上图,是一颗二分搜索树,从添加查找节点,时间复杂度均为O(h),但在极端情况下, 如按顺序向一个空二分搜索树中添加0,1,2,3,4,二分搜索数会退化为单链,这时候时间 时间复杂度会变成O(n),如下图,为了避免这种情况需要结合平衡树做改进...

哥斯拉啊啊啊哦的博客 265

一种基于AVL树的Map实现(使用golang)

AVL树是以其发明者Adelson-Velskii和Landis命名的一种二叉查找树。均衡因子-1、0、1代表每个节点的均衡状态。为了更简单的实现,我们记录底板的高度并动态计算其平衡系数。向左旋转和向右旋转。对于向右旋转,假设我们有一棵以R为根节点的树,我们将整棵树右转90度,然后将其调整为有效的树。对于向左旋转,假设L是树的根节点,我们将整个树向左旋转90度,最后将其调整为有效的树。

学者的博客 306

Go版数据结构 -【4.3 AVL树】

AVL 树 是 二叉搜索树 的一个自平衡扩展,它通过旋转操作来保持树的平衡。 与普通的二叉搜索树不同,AVL 树在每次插入或删除节点时,都会检查树的平衡因子,并进行必要的调整以确保树的高度尽可能保持平衡。 本节我们将介绍AVL 树的基本概念、平衡因子、旋转操作,以及AVL 树的Go语言实现。

Swxctx 1282

Go语言算法和数据结构(十)AVL树

AVL树是一种自平衡二叉搜索树,通过维护节点平衡因子实现高效数据操作。摘要介绍了AVL树的核心实现:1)节点结构包含高度、值和左右子节点;2)关键操作包括旋转调整(左旋/右旋)、插入删除时的平衡维护;3)提供完整代码示例,展示节点插入、删除和遍历的实现。文章还介绍了两种实现方式:基础实现使用递归处理平衡,进阶实现通过方向标志优化旋转操作。最后演示了AVL树的基本使用,包括创建、插入和删除节点。该实现适用于需要频繁更新的有序数据场景。

不愿言弃-念何的博客 277

最全【算法学习】AVL平衡二叉搜索树原理及各项操作编程实现(C++,2024年最新干了5年Golang开发还没掌握binder机制

/更改原根节点的左子树。//更改原根节点左孩子的右子树。//左左外侧插入导致的不平衡,采用单旋转-右旋转进行修正。//右右外侧插入导致的不平衡,采用单旋转-左旋转进行修正。//对新产生的树进行一次单旋转-右旋转。//对新产生的树进行一次单旋转-左旋转。//对其左子树进行一次单旋转-左旋转。//对其右子树进行一次单旋转-右旋转。//得到树中的元素值最小的那个节点。//插入点位于T的左子结点的右子树。//插入点位于T的右子节点的左子树。//双旋转可以通过两次单旋转实现。//得到树中的元素值最大的节点。

2401_84920027的博客 1081

GOLANG实现的一个avl tree api

用golang实现了一个avl tree的api。 avlTree.go /* ** an avl tree api: //==&gt;&gt; operator tree api: //insert an x to AvlTree, invoker format: t = tree.Insert(t, x) func Insert(tree *AvlNode, x ElementType)...

weixin_30746129的博客 367

2024年Go最全平衡二叉树(AVL)_avl树全称是什么,带你一起探究Golang事件分发机制

增加高度属性二叉搜索树是否平衡,取决于左右子树的高度差插入节点或删除节点时,想要知道二叉树是否保持平衡,需要计算左右子树的高度计算左右子树的高度,一般通过自顶向下或自底向上的方式,递归计算(不对深度和高度加以区分)这样将会存在一定的时间开销和空间开销因此,需要在原有的TreeNode基础上,增加一个高度字段,用于记录当前节点的高度空节点的高度为0,叶子节点的高度为1,平衡二叉树,树节点的定义如下// 获取某个节点的高度。

2401_84925780的博客 610
上一篇: a simple erlang process pool analysis
下一篇: PoolBoy
laohan_
博客等级 码龄15年 112粉丝 224原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值