AVL树(balanced binary search tree)

2024-02-11 23:48
文章标签 avl tree search binary balanced

本文主要是介绍AVL树(balanced binary search tree),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

#include<stdio.h>
#include<stdlib.h>typedef int Item;
typedef struct node* Tree;struct node                    /*AVL树结点定义*/
{Item val;int height;struct node* left;struct node* right;
};/*******************************************************
* 辅助函数:
*       1.错误处理
*       2.找最小元素
*       3.找最大元素
*
********************************************************///1.错误处理
static void terminate(const char* message)
{printf("%s\n", message);exit(EXIT_FAILURE);
}//2.找最小元素
Tree find_min(Tree t)
{if (t == NULL)               /*如果树为空,返回NULL*/{return NULL;}else if (t->left == NULL){return t;}else{return find_min(t->left);}
}//3.找最大元素
Tree find_max(Tree t)
{if (t == NULL)              /*如果树为空,返回NULL*/{return NULL;}else if (t->right == NULL){return t;}else{return find_max(t->right);}
}/************************************************************
* AVL树的操作:
*          1.结点高度
*          2.单左旋
*          3.单右旋
*          4.双左旋
*          5.双右旋
*          6.插入
*          7.删除
* 注:
*   1.Tree create(void)
*	2.Tree find(Tree t, Item n)
*	3.Tree find_min(Tree t)
*	4.Tree find_max(Tree t)
*	5.Tree make_empty(Tree t)
*   在AVL树中,这五个函数与二叉查找树的操作完全一样,
*	所以这里不再列出
*
*************************************************************///1.结点高度
int height(Tree t)
{if (t == NULL){return -1;}else{return t->height;}
}//2.单左旋
Tree single_rotate_with_left(Tree t)                         /*1.对root的右儿子的右子树进行一次插入*/
{                                                            /*2.对root的左儿子的右子树进行一次删除*/Tree new_root;new_root = t->right;t->right = new_root->left;new_root->left = t;t->height = max(height(t->left), height(t->right)) + 1;new_root->height = max(t->height, height(new_root->right)) + 1;return new_root;
}//3.单右旋
Tree single_rotate_with_right(Tree t)                       /*1.对root的左儿子的左子树进行一次插入*/
{                                                           /*2.对root的右儿子的左子树进行一次删除*/Tree new_root;new_root = t->left;t->left = new_root->right;new_root->right = t;t->height = max(height(t->left), height(t->right)) + 1;new_root->height = max(height(new_root->left), t->height) + 1;return new_root;
}//4.双左旋
Tree double_rotate_with_left(Tree t)                        /*对root的右儿子的左子树进行一次插入*/
{                                                           t->right = single_rotate_with_right(t->right);return single_rotate_with_left(t);
}//5.双右旋
Tree double_rotate_with_right(Tree t)                       /*对root的左儿子的右子树进行一次插入*/
{t->left = single_rotate_with_left(t->left);return single_rotate_with_right(t);
}//6.插入
Tree insert(Tree t, Item n)
{if (t == NULL){t = malloc(sizeof(struct node));if (t == NULL){terminate("Error: malloc failed in insert.");}t->val = n;t->height = 0;t->left = t->right = NULL;}else if (n < t->val){t->left = insert(t->left, n);if (height(t->left) - height(t->right) == 2){if (n < t->left->val){t = single_rotate_with_right(t);}else{t = double_rotate_with_right(t);}}}else if (n > t->val){t->right = insert(t->right, n);if (height(t->right) - height(t->left) == 2){if (n > t->right->val){t = single_rotate_with_left(t);}else{t = double_rotate_with_left(t);}}}/*如果n=t->val,说明n已经在树里面了,那么什么都不做*/t->height = max(height(t->left), height(t->right)) + 1;         /*不要忘记更新结点高度*/return t;
}//7.删除
Tree delete(Tree t, Item n)
{if (t == NULL)                      /*1.树为空*/{                                   /*2.树不空但n不在树中*/return NULL;}else if (n < t->val){t->left = delete(t->left, n);if (height(t->right) - height(t->left) == 2){if (n < t->val){t = single_rotate_with_left(t);}else{t = double_rotate_with_left(t);}}}else if (n > t->val){t->right = delete(t->right, n);if (height(t->left) - height(t->right) == 2){if (n > t->val){t = single_rotate_with_right(t);}else{t = double_rotate_with_right(t);}}}else{Tree temp;if (t->left != NULL && t->right != NULL){if (height(t->left) >= height(t->right)){temp = find_max(t->left);t->val = temp->val;t->left = delete(t->left, t->val);}else{temp = find_min(t->right);t->val = temp->val;t->right = delete(t->right, t->val);}}else{temp = t;if (t->left != NULL){t = t->left;}else if (t->right != NULL){t = t->right;}else{t = NULL;}free(temp);}}if (t != NULL){t->height = max(height(t->left), height(t->right)) + 1;}return t;
}

这篇关于AVL树(balanced binary search tree)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/701142

相关文章

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

树(Tree)——《啊哈!算法》

树 什么是树?树是一种特殊的图,不包含回路的连通无向树。 正因为树有着“不包含回路”这个特点,所以树就被赋予了很多特性。 一棵树中的任意两个结点有且仅有唯一的一条路径连通。一棵树如果有n个结点,那么它一定恰好有n-1条边。在一棵树中加一条边将会构成一个回路。 一棵树有且只有一个根结点。 没有父结点的结点称为根结点(祖先)。没有子结点的结点称为叶结点。如果一个结点既不是根结点也不是叶

JavaScript正则表达式六大利器:`test`、`exec`、`match`、`matchAll`、`search`与`replace`详解及对比

在JavaScript中,正则表达式(Regular Expression)是一种用于文本搜索、替换、匹配和验证的强大工具。本文将深入解析与正则表达式相关的几个主要执行方法:test、exec、match、matchAll、search和replace,并对它们进行对比,帮助开发者更好地理解这些方法的使用场景和差异。 正则表达式基础 在深入解析方法之前,先简要回顾一下正则表达式的基础知识。正则

插件maven-search:Maven导入依赖时,使用插件maven-search拷贝需要的依赖的GAV

然后粘贴: <dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>    <version>8.0.26</version> </dependency>

226 Invert Binary Tree

//226 Invert Binary Tree//算法思路:主要使用递归算法public class Solution {public TreeNode invertTree(TreeNode root) {//1 出口 空节点if (root==null)return null;//2 递归 调用自己TreeNode left = root.left;TreeNode right = ro

广度优先搜索Breadth-First-Search

目录  1.问题 2.算法 3.代码 4.参考文献  1.问题         广度优先搜索,稍微学过算法的人都知道,网上也一大堆资料,这里就不做过多介绍了。直接看问题,还是从下图招到一条从城市Arad到Bucharest的路径。  该图是连通图,所以必然存在一条路径,只是如何找到最短路径。 2.算法 还是贴一个算法的伪代码吧: 1 procedu

【0323】Postgres内核之 hash table sequentially search(seq_scan_tables、num_seq_scans)

0. seq scan tracking 我们在这里跟踪活跃的 hash_seq_search() 扫描。 需要这种机制是因为如果扫描正在进行时发生桶分裂(bucket split),它可能会访问两次相同的条目,甚至完全错过某些条目(如果它正在访问同一个分裂的桶中的条目)。因此,如果正在向表中插入数据,我们希望抑制桶分裂。 在当前的使用中,这种情况非常罕见,因此只需将分裂推迟到下一次插入即可。

Sorry!Hbase的LSM Tree就是可以为所欲为!

我们先抛出一个问题: LSM树是HBase里使用的非常有创意的一种数据结构。在有代表性的关系型数据库如MySQL、SQL Server、Oracle中,数据存储与索引的基本结构就是我们耳熟能详的B树和B+树。而在一些主流的NoSQL数据库如HBase、Cassandra、LevelDB、RocksDB中,则是使用日志结构合并树(Log-structured Merge Tree,LSM Tr

【spring】does not have member field ‘com.sun.tools.javac.tree.JCTree qualid

spring-in-action-6-samples 的JDK版本 最小是11,我使用 了22: jdk21 jdk22 都与lombok 不兼容,必须使用兼容版本, 否则报错: thingsboard 的大神解释了: java: java.lang.NoSuchFieldError: Class com