平衡二叉树的应用举例

AVL 是一种自平衡二叉搜索树,其中任何节点的左右子树的高度之差不能超过 1。

AVL树的特点:

1、它遵循二叉搜索树的一般属性。

2、树的每个子树都是平衡的,即左右子树的高度之差最多为1。

3、当插入新节点时,树会自我平衡。因此,插入操作非常耗时。

AVL Tree的应用:

1、大多数内存中集和字典都使用 AVL 树进行存储。

2、数据库应用程序(插入和删除不太常见,但需要频繁的数据查找)也经常使用 AVL 树。

3、除了数据库应用程序之外,它还用于其他需要更好搜索的应用程序。

4、有序关联容器(集合、多集、映射和多映射)的大多数 STL 实现都使用红黑树而不是 AVL树。

#include <stdio.h>
#include <stdlib.h>struct AVLnode
{int key;struct AVLnode *left;struct AVLnode *right;int height;
};
typedef struct AVLnode avlNode;int max(int a, int b) { return (a > b) ? a : b; }avlNode *newNode(int key)
{avlNode *node = (avlNode *)malloc(sizeof(avlNode));if (node == NULL)printf("!! Out of Space !!\n");else{node->key = key;node->left = NULL;node->right = NULL;node->height = 0;}return node;
}int nodeHeight(avlNode *node)
{if (node == NULL)return -1;elsereturn (node->height);
}int heightDiff(avlNode *node)
{if (node == NULL)return 0;elsereturn (nodeHeight(node->left) - nodeHeight(node->right));
}/* 返回左子树中最小值的节点*/
avlNode *minNode(avlNode *node)
{avlNode *temp = node;while (temp->left != NULL) temp = temp->left;return temp;
}void printAVL(avlNode *node, int level)
{int i;if (node != NULL){printAVL(node->right, level + 1);printf("\n\n");for (i = 0; i < level; i++) printf("\t");printf("%d", node->key);printAVL(node->left, level + 1);}
}avlNode *rightRotate(avlNode *z)
{avlNode *y = z->left;avlNode *T3 = y->right;y->right = z;z->left = T3;z->height = (max(nodeHeight(z->left), nodeHeight(z->right)) + 1);y->height = (max(nodeHeight(y->left), nodeHeight(y->right)) + 1);return y;
}avlNode *leftRotate(avlNode *z)
{avlNode *y = z->right;avlNode *T3 = y->left;y->left = z;z->right = T3;z->height = (max(nodeHeight(z->left), nodeHeight(z->right)) + 1);y->height = (max(nodeHeight(y->left), nodeHeight(y->right)) + 1);return y;
}avlNode *LeftRightRotate(avlNode *z)
{z->left = leftRotate(z->left);return (rightRotate(z));
}avlNode *RightLeftRotate(avlNode *z)
{z->right = rightRotate(z->right);return (leftRotate(z));
}avlNode *insert(avlNode *node, int key)
{if (node == NULL)return (newNode(key));/*二叉搜索树插入*/if (key < node->key)node->left =insert(node->left, key); /*递归插入左子树*/else if (key > node->key)node->right =insert(node->right, key); /*递归插入右子树*//*计算节点高度*/node->height = (max(nodeHeight(node->left), nodeHeight(node->right)) + 1);/*检查平衡性*/int balance = heightDiff(node);/*左左*/if (balance > 1 && key < (node->left->key))return rightRotate(node);/*右右*/if (balance < -1 && key > (node->right->key))return leftRotate(node);/*左右*/if (balance > 1 && key > (node->left->key)){node = LeftRightRotate(node);}/*右左*/if (balance < -1 && key < (node->right->key)){node = RightLeftRotate(node);}return node;
}avlNode *delete (avlNode *node, int queryNum)
{if (node == NULL)return node;if (queryNum < node->key)node->left =delete (node->left, queryNum); /*Recursive deletion in L subtree*/else if (queryNum > node->key)node->right =delete (node->right, queryNum); /*Recursive deletion in R subtree*/else{/*单节点或者没有子节点*/if ((node->left == NULL) || (node->right == NULL)){avlNode *temp = node->left ? node->left : node->right;/*没有子节点*/if (temp == NULL){temp = node;node = NULL;}else /*单节点*/*node = *temp;free(temp);}else{/*两个孩子节点*//*获取右子树最小值的节点*/avlNode *temp = minNode(node->right);node->key = temp->key; /*拷贝到根节点*/node->right =delete (node->right,temp->key); /*删除右子树最小值的节点*/}}/*单节点*/if (node == NULL)return node;/*更新高度*/node->height = (max(nodeHeight(node->left), nodeHeight(node->right)) + 1);int balance = heightDiff(node);/*左左*/if ((balance > 1) && (heightDiff(node->left) >= 0))return rightRotate(node);/*左右*/if ((balance > 1) && (heightDiff(node->left) < 0)){node = LeftRightRotate(node);}/*右右*/if ((balance < -1) && (heightDiff(node->right) >= 0))return leftRotate(node);/*右左*/if ((balance < -1) && (heightDiff(node->right) < 0)){node = RightLeftRotate(node);}return node;
}avlNode *findNode(avlNode *node, int queryNum)
{if (node != NULL){if (queryNum < node->key)node = findNode(node->left, queryNum);else if (queryNum > node->key)node = findNode(node->right, queryNum);}return node;
}void printPreOrder(avlNode *node)
{if (node == NULL)return;printf("  %d  ", (node->key));printPreOrder(node->left);printPreOrder(node->right);
}void printInOrder(avlNode *node)
{if (node == NULL)return;printInOrder(node->left);printf("  %d  ", (node->key));printInOrder(node->right);
}void printPostOrder(avlNode *node)
{if (node == NULL)return;printPostOrder(node->left);printPostOrder(node->right);printf("  %d  ", (node->key));
}int main()
{int choice;int flag = 1;int insertNum;int queryNum;avlNode *root = NULL;avlNode *tempNode;while (flag == 1){printf("\n\nEnter the Step to Run : \n");printf("\t1: Insert a node into AVL tree\n");printf("\t2: Delete a node in AVL tree\n");printf("\t3: Search a node into AVL tree\n");printf("\t4: printPreOrder (Ro L R) Tree\n");printf("\t5: printInOrder (L Ro R) Tree\n");printf("\t6: printPostOrder (L R Ro) Tree\n");printf("\t7: printAVL Tree\n");printf("\t0: EXIT\n");scanf("%d", &choice);switch (choice){case 0:{flag = 0;printf("\n\t\tExiting, Thank You !!\n");break;}case 1:{printf("\n\tEnter the Number to insert: ");scanf("%d", &insertNum);tempNode = findNode(root, insertNum);if (tempNode != NULL)printf("\n\t %d Already exists in the tree\n", insertNum);else{printf("\n\tPrinting AVL Tree\n");printAVL(root, 1);printf("\n");root = insert(root, insertNum);printf("\n\tPrinting AVL Tree\n");printAVL(root, 1);printf("\n");}break;}case 2:{printf("\n\tEnter the Number to Delete: ");scanf("%d", &queryNum);tempNode = findNode(root, queryNum);if (tempNode == NULL)printf("\n\t %d Does not exist in the tree\n", queryNum);else{printf("\n\tPrinting AVL Tree\n");printAVL(root, 1);printf("\n");root = delete (root, queryNum);printf("\n\tPrinting AVL Tree\n");printAVL(root, 1);printf("\n");}break;}case 3:{printf("\n\tEnter the Number to Search: ");scanf("%d", &queryNum);tempNode = findNode(root, queryNum);if (tempNode == NULL)printf("\n\t %d : Not Found\n", queryNum);else{printf("\n\t %d : Found at height %d \n", queryNum,tempNode->height);printf("\n\tPrinting AVL Tree\n");printAVL(root, 1);printf("\n");}break;}case 4:{printf("\nPrinting Tree preOrder\n");printPreOrder(root);break;}case 5:{printf("\nPrinting Tree inOrder\n");printInOrder(root);break;}case 6:{printf("\nPrinting Tree PostOrder\n");printPostOrder(root);break;}case 7:{printf("\nPrinting AVL Tree\n");printAVL(root, 1);break;}default:{flag = 0;printf("\n\t\tExiting, Thank You !!\n");break;}}}return 0;
}

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

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

相关文章

前端项目负责人(虚拟岗)

定位&#xff1a; 项目从需求到上线阶段的绝对主力&#xff0c;确保项目的正常迭代与风险把控&#xff1b;代码质量和性能的保证者&#xff1b; 素质要求&#xff1a; 拥有良好的沟通和协调能力&#xff0c;能够清晰地传达目标、任务和进展情况&#xff0c;并及时解决沟通障…

R语言绘图 --- 饼状图(Biorplot 开发日志 --- 2)

「写在前面」 在科研数据分析中我们会重复地绘制一些图形&#xff0c;如果代码管理不当经常就会忘记之前绘图的代码。于是我计划开发一个 R 包&#xff08;Biorplot&#xff09;&#xff0c;用来管理自己 R 语言绘图的代码。本系列文章用于记录 Biorplot 包开发日志。 相关链接…

JDBC入门基础

目录 JDBC的基本概念 快速入门&#xff08;基本步骤&#xff09; 创建数据库 注册驱动&#xff08;可以省略不写&#xff09; 获取连接对象 获取执行SQL语句的对象 编写SQL语句&#xff0c;并执行&#xff0c;以及接收返回的结果 处理结果&#xff0c;遍历结果集和 释放资源&…

数据流通与智能家居的未来

在科技飞速发展的今天&#xff0c;智能家居逐渐融入我们的日常生活&#xff0c;改变了传统的居住方式。智能生态网络&#xff08;IEN&#xff09;作为智能家居的核心&#xff0c;集成了家庭内的各种智能设备和传感器&#xff0c;实现了对家庭环境的智能化管理。而数据要素流通则…

ESP32入门:1、VSCode+PlatformIO环境搭建(离线快速安装)

文章目录 背景安装vscode安装配置中文 安装Platform IO安装PIO 新建ESP32工程参考 背景 对于刚接触单片机的同学&#xff0c;使用vscodeplatformIO来学习ESP32是最方便快捷的&#xff0c;比IDF框架简单&#xff0c;且比arduino文件管理性能更好。但是platformIO安装较为麻烦&a…

C动态编程语言:深入剖析其特性与潜力

C动态编程语言&#xff1a;深入剖析其特性与潜力 在编程语言的浩瀚海洋中&#xff0c;C语言以其独特的魅力吸引着无数开发者。然而&#xff0c;当我们提及C作为动态编程语言时&#xff0c;可能会引发一些困惑和争议。毕竟&#xff0c;C语言通常被视为一种静态类型、过程式的编…

如何查看Kafka数据文件中的 .log .index .timeindex 文件内容

如何查看 在 kafka 目录下执行指令&#xff1a; kafka/bin/kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.log --print-data-log# 将00000000000000000000.log替换为要查看的.log .index .timeindex文件即可结果如下&#xff1a; kafka/b…

电子阅览室能给孩子做什么

电子阅览室为孩子提供了很多活动和资源&#xff0c;可以为他们提供以下服务&#xff1a; 1. 提供电子书籍和儿童读物&#xff1a;电子阅览室通常提供大量的电子书籍和儿童读物&#xff0c;供孩子选择阅读。 2. 提供儿童学习资源&#xff1a;专久智能电子阅览室可以提供各种学习…

CraftCMS ConditionsController.php 代码执行漏洞(CVE-2023-41892)

0x01 产品简介 Craft CMS是一个开源的内容管理系统,它专注于用户友好的内容创建过程,逻辑清晰明了,是一个高度自由,高度自定义设计的平台吗,可以用来创建个人或企业网站也可以搭建企业级电子商务系统。 0x02 漏洞概述 Craft CMS在4.4.15版本之前存在远程代码执行漏洞,…

代码随想录算法训练营day24|回溯理论基础、77.组合

回溯理论基础 带你学透回溯算法&#xff08;理论篇&#xff09;| 回溯法精讲&#xff01;_哔哩哔哩_bilibili 回溯算法是一种试探性的算法&#xff0c;用于解决组合优化问题。这类问题通常涉及在给定的候选集中找出满足特定条件的所有解。回溯算法通过深度优先遍历的方式&#…

【数据结构与算法|栈篇】中缀表达式转变为后缀表达式

1. 前言 假设我们已经知道中缀表达式和后缀表达式的概念. 我们可以用符号栈来实现中缀表达式向后缀表达式的转变. 2. 符号栈实现中缀表达式转变为后缀表达式 (1). 思路 我们设计了可变字符串与符号栈. 如果传入的字符串的字符是数字字符&#xff0c;则直接将该字符append到…

[论文笔记]MemGPT: Towards LLMs as Operating Systems

引言 今天介绍一篇论文MemGPT: Towards LLMs as Operating Systems。翻过过来就是把LLM看成操作系统。 大语言模型已经在人工智能领域引起了革命性的变革&#xff0c;但受到有限上下文窗口的限制&#xff0c;在扩展对话和文档分析等任务中的效用受到了阻碍。为了能够利用超出…

4月啤酒品类线上销售数据分析

近期&#xff0c;中国啤酒行业正处于一个重要的转型期。首先&#xff0c;消费者对高品质啤酒的需求不断增加&#xff0c;这推动了行业向高端化、场景化和社交化的方向发展。精酿啤酒作为这一趋势的代表&#xff0c;其发展势头强劲&#xff0c;不仅满足了消费者对品质化、个性化…

Ubuntu下搭建与配置PPPoE server

1.安装pppoe sudo apt-get install pppoe #查看帮助与版本号&#xff08;本文基于Version 3.12&#xff09; pppoe-server -h2.修改配置文件 主要包括/etc/ppp/options 、/etc/ppp/pppoe-server-options 、/etc/ppp/chap-secrets三个文件 /etc/ppp/options &#xff1a; #设…

蓝桥杯2024国赛--备赛刷题题单

1.游戏&#xff08;单调队列&#xff09; 注意如果结果是分数&#xff0c;直接设置变量为double&#xff0c;最好不要使用把int类型乘1.0变成分数来计算。 #include <iostream> #include <queue> using namespace std; const int N1e510; //滑动窗口大小为k,最大值…

2024上海中小学生古诗文大会方案已发布,家长孩子最关心10个问题

昨天&#xff08;2024年5月30日&#xff09;下午15点&#xff0c;上海中小学生古诗文大会组委会通过两个公众号发布了《2024上海中小学生古诗文大会系列活动方案出炉》的推文&#xff08;下称《方案》&#xff09;。如我之前的分析和预测&#xff0c;5月份会发布今年的中小学生…

Java - Java对象,充血模型的坑,还是不规范惹的祸~

充血模型的特点包括&#xff1a; 富含业务逻辑&#xff1a;在充血模型中&#xff0c;领域对象&#xff08;如Java中的类&#xff09;不仅仅是数据的容器&#xff0c;它们还包含了丰富的业务逻辑。这意味着业务规则、验证逻辑、计算等直接嵌入到领域对象内部。例如&#xff0c;一…

邮件服务器部署

目录 介绍 资源列表 基础环境 关闭防火墙 关闭内核安全机制 修改主机名 一、部署DNS服务器 mail节点操作 修改DNS地址 二、部署postfix和dovecot 安装软件包 修改postfix配置文件 重启postfix服务和开机自启 修改dovecot配置文件 重启dovecot服务和开机自启 创…

2024-5-28 刷题题单

1. 两数之和 经典算法 以空间换取时间。 链表 – 哑结点 dummy node 使用了虚拟头结点的技巧,也是为了防止出现空指针的情况。 例如:链表 head = [1,2,3,4,5],需要删除倒数第 5 个结点,也就是第一个节点。按照算法逻辑,应该首先找到倒数第 6 个节点。但由于头节点不存…

微服务:一篇博客带你学会Gateway(路由、过滤、跨域问题配置)

文章目录 Gateway搭建路由断言工厂路由过滤器全局过滤器过滤器执行顺序网关的core跨域配置跨域问题配置 Gateway 网关功能&#xff1a; 身份认证、权限校验服务路由、负载均衡请求限流 搭建 gateway也算一个服务 所以创建gateway子模块 引入依赖 <dependency><gro…