平衡二叉树的应用举例

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.rhkb.cn/news/337149.html

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

相关文章

【计算机毕设】基于SpringBoot的房产销售系统设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 随着房地产市场的发展和互联网技术的进步&#xff0c;传统的房产销售模式逐渐向线上转移。设计并实现一个基于Spring Boot的房产销售系统&#xff0…

代理IP怎么检测?如何判断IP好坏?

当我们的数字足迹无处不在&#xff0c;隐私保护显得愈发重要。而代理IP就像是我们的隐身斗篷&#xff0c;让我们在各项网络业务中更加顺畅。 我们常常看到别人购买了代理IP服务后&#xff0c;用在线检测网站检查IP&#xff0c;相当于一个”售前检验““售后质检”的作用。但是…

[ROS 系列学习教程] 建模与仿真 - Xacro 语法

ROS 系列学习教程(总目录) 本文目录 一、属性与属性块二、数学表达式三、宏3.1 宏的基本使用3.2 属性块做为宏的入参3.3 任意数量元素做为宏的入参3.4 指定多个块元素的处理顺序3.5 宏嵌套3.6 默认参数3.7 局部属性 四、Rospack 命令五、包含其他 xacro 文件六、条件语句七、YA…

html+CSS部分基础运用9

项目1 参会注册表 1.设计参会注册表页面&#xff0c;效果如图9-1所示。 图9-1 参会注册表页面 项目2 设计《大学生暑期社会实践调查问卷》 1.设计“大学生暑期社会实践调查问卷”页面&#xff0c;如图9-2所示。 图9-2 大学生暑期社会调查表页面 2&#xff0e;调查表前导语的…

【C++】C++11新特性:列表初始化、声明、新容器、右值引用、万能引用和完美转发

目录 一、列表初始化 1.1 { } 初始化 1.2 std::initializer_list 二、声明 2.1 auto 2.2 decltype 2.3 nullptr 三、新容器 四、右值引用和移动语义 4.1 左值和左值引用 4.2 右值和右值引用 4.3 左值引用与右值引用比较 4.4 右值引用使用场景和意义&#xff1a;移…

Spring Boot 项目中使用 JSP

文章目录 Spring Boot 项目中使用 JSP项目结构引入依赖包编写页面和后台运行方式一&#xff1a;Maven 命令运行方式二&#xff1a;在 IDEA 中运行方式三&#xff1a;打 war 包部署运行 Spring Boot 项目中使用 JSP 在 Spring Boot 项目中不是不可以使用 JSP 。想在 Spring Boo…

fmql之CAN调试

刚刚把zynq的CAN调成功。那么现在就要把程序移植到fmql了。 老规矩&#xff0c;Procise导入vivado的.bd和.xci文件。 Procise下create block也可以&#xff0c;但是不能自动约束引脚&#xff0c;只能手动写代码。 PeripheralTest CanExample中用到了CAN0和CAN1&#xff1a;…

msvcp140.dll是什么东西?如何修复电脑提示msvcp140.dll丢失的多种方法

文件名为 msvcp140.dll&#xff0c;这是一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;属于Microsoft Visual C 2015 Redistributable的一部分。全称为 "Microsoft C Runtime Library" 或 "Microsoft C Runtime Library"&#xff0c;表明该文…

如何使用 Connector API 将数据提取到 Elasticsearch Serverless 中

作者&#xff1a;来自 Elastic Jedr Blaszyk Elasticsearch 支持一系列摄取方法。 其中之一是 Elastic Connectors&#xff0c;它将 SQL 数据库或 SharePoint Online 等外部数据源与 Elasticsearch 索引同步。 连接器对于在现有数据之上构建强大的搜索体验特别有用。 例如&…

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

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

uniapp 添加字体ttf

效果图如下 一、逻辑概述 在uniapp中使用字体&#xff0c;一共分成两种情况&#xff0c;一种是普通vue页面&#xff0c;一种是nvue页面引入字体。。 1.vue页面引入字体需要如下步骤 1. 先选择下载一种字体&#xff1a;字体格式一般为 ttf后缀名 黄凯桦律师手写体免费下载和在线…

代码随想录算法训练营第三十二 | ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

122.买卖股票的最佳时机II 讲解链接&#xff1a;https://programmercarl.com/1005.K%E6%AC%A1%E5%8F%96%E5%8F%8D%E5%90%8E%E6%9C%80%E5%A4%A7%E5%8C%96%E7%9A%84%E6%95%B0%E7%BB%84%E5%92%8C.html 简单思路&#xff1a;逐个计算连续两天的股票差值&#xff0c;sum初始为零&…

期末速成 ——计算机组成原理(2)数值的表示与运算

目录 一、定点数的表示 &#xff08;一&#xff09;无符号数和有符号数的表示 &#xff08;二&#xff09;机器数的定点表示 &#xff08;三&#xff09;原码、补码、反码、移码 (1)原码表示法 二、浮点数的表示 三、溢出判断 (一)采用一位符号位 (二)采用双符号位 四…

Qt Creator(Qt 6.6)拷贝一行

Edit - Preference - Environment&#xff1a; 可看到&#xff0c;拷贝一行的快捷键是&#xff1a; ctrl Ins

Django——Admin站点(Python)

#前言&#xff1a; 该博客为小编Django基础知识操作博客的最后一篇&#xff0c;主要讲解了关于Admin站点的一些基本操作&#xff0c;小编会继续尽力更新一些优质文章&#xff0c;同时欢迎大家点赞和收藏&#xff0c;也欢迎大家关注等待后续文章。 一、简介&#xff1a; Djan…

Firefox国际版

Firefox国际版官方网址&#xff1a; Download the Firefox Browser in English (US) and more than 90 other languagesEveryone deserves access to the internet — your language should never be a barrier. That’s why — with the help of dedicated volunteers around…

基础—SQL—DQL(数据查询语言)案例练习

一、需求 0、emp 表的初始数据 1、查询年龄为20,21,22,23岁的员工信息。 SELECT * FROM emp WHERE gender女AND age IN(20,21,22,23); 2、查询性别为男&#xff0c;并且年龄在20-40岁(含)以内的姓名为三个字的员工。 SELECT * FROM emp WHERE gender男 AND age BETWEEN 20 AND …

记 Codes 开源免费研发管理平台 —— 日报与工时融合集中式填报的创新实现

继上一回合生成式全局看板的创新实现后&#xff0c;本篇我们来讲一讲日报与工时融合集中式填报的创新实现。 市面上所有的研发管理软件&#xff0c;大多都有工时相关功能&#xff0c;但是却没有日报功能&#xff0c;好像也没什么问题&#xff0c;但是在使用过程中体验非常不…

LeetCode-131 分割回文串

LeetCode-131 分割回文串 题目描述解题思路C 代码 题目描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串。返回 s 所有可能的分割方案。 示例 1&#xff1a; 输入&#xff1a;s “aab” 输出&#xff1a;[[“a”,“a”,“b”],…

Docker安装Redis(云服务器)

准备&#xff1a; 在云服务器中开启6370端口号 docker run -d --name redis -p 6379:6379 redis 这条命令使用docker运行一个名为"redis"的容器&#xff0c;映射容器的6379端口到主机的6379端口&#xff0c;并且使用redis镜像来运行容器。REDIS是一个开源的内存数据…