探索树堆Treap和红黑树的优势和劣势

news2024/10/5 18:34:36

探索树堆Treap和红黑树的优势和劣势

  • 一、背景知识
  • 二、树堆(Treap)的介绍
  • 三、红黑树(RB-Tree)的介绍
  • 四、树堆(Treap)与红黑树(RB-Tree)的比较
  • 总结

博主简介


💡一个热爱分享高性能服务器后台开发知识的博主,目标是通过理论与代码实践的结合,让世界上看似难以掌握的技术变得易于理解与掌握。技能涵盖了多个领域,包括C/C++、Linux、Nginx、MySQL、Redis、fastdfs、kafka、Docker、TCP/IP、协程、DPDK等。
👉
🎖️ CSDN实力新星、CSDN博客专家、华为云云享专家、阿里云专家博主
👉


一、背景知识

树堆(Treap)和红黑树(RB-Tree)都是常见的自平衡二叉搜索树(self-balancing binary search tree)数据结构。
在这里插入图片描述

树堆是一种随机化平衡二叉搜索树,结合了二叉堆和二叉搜索树的特性。树堆的每个节点包含一个键值和一个随机优先级值。树堆的特点是通过维护键值的二叉搜索树性质和优先级的堆性质来保持平衡。通过保持这两个性质,树堆可以在插入和删除节点时自动进行平衡操作。树堆的优势在于它相对简单的实现和高效的查找操作。
在这里插入图片描述

红黑树是一种严格平衡的自平衡二叉搜索树。每个节点都具有一个额外的标记,称为颜色,可以是红色或黑色。红黑树通过遵循一组特定的规则来保持平衡,如保持从根节点到叶节点的任何路径上的黑色节点数量相同。通过这些规则,红黑树可以在插入和删除节点时自动进行平衡操作。红黑树的优势在于它提供严格的平衡性能保证,并且具有高效的查找、插入和删除操作。
在这里插入图片描述
区别:

  • 树堆通过随机优先级来维持平衡,而红黑树则通过颜色标记和旋转操作来维持平衡。
  • 树堆在实现和维护方面相对简单,而红黑树提供了严格的平衡保证。

探索树堆(Treap)和红黑树(RB-Tree)的优势和劣势的目的在于深入了解这两种常见的自平衡二叉搜索树数据结构,可以帮助我们优化和改进现有的数据结构,或者在需要特定性能要求的场景中提出新的数据结构设计。

二、树堆(Treap)的介绍

树堆(Treap)是一种组合了二叉堆和二叉搜索树特性的随机化平衡二叉树。它的基本特性和原理:

  1. 键值特性:树堆的每个节点包含一个键值和一个随机的优先级值。键值用于节点的比较和排序,优先级值用于平衡树的结构。

  2. 二叉搜索树性质:树堆维护了二叉搜索树的性质,即对于任意节点,它的左子树中的所有节点的键值小于该节点的键值,右子树中的所有节点的键值大于该节点的键值。

  3. 堆性质:树堆也维护了堆的性质,即对于任意节点,它的优先级值大于其子节点的优先级值。

  4. 随机化平衡:树堆通过随机生成节点的优先级值来实现平衡。节点的优先级值和键值无关,它的随机性保证了树的平衡性质。

  5. 插入操作:当插入一个新节点时,树堆首先按照二叉搜索树性质找到插入的位置,然后根据节点的优先级值,通过旋转操作保持堆性质和搜索树性质。

  6. 删除操作:删除一个节点时,树堆首先根据二叉搜索树性质找到要删除的节点,然后通过旋转操作将其删除,并保持堆性质和搜索树性质。

因此,树堆被广泛应用于各种需要动态操作集合的场景,如数据库索引、动态统计和优先级队列等。

树堆的优点:

  1. 随机化特性和平衡性。树堆通过随机化的方式维护平衡,在大多数情况下可以保持较好的性能,而不需要过多的平衡调整操作。
  2. 相对简单的实现,减少了开发和维护的复杂性。
  3. 提供高效的查找、插入和删除操作。树堆通过旋转操作和优先级调整,在插入和删除节点时能够自动进行平衡操作。相对于其他平衡树结构,树堆的插入和删除操作具有较低的时间复杂度。

简单的树堆(Treap)的C语言代码实现,以便更好地理解其工作原理:

#include <stdio.h>
#include <stdlib.h>

// 定义树堆节点结构体
typedef struct treap_node {
    int key;
    int priority;
    struct treap_node* left;
    struct treap_node* right;
} TreapNode;

// 初始化树堆节点
TreapNode* createNode(int key) {
    TreapNode* node = (TreapNode*)malloc(sizeof(TreapNode));
    node->key = key;
    node->priority = rand() % 100;  // 随机生成优先级值
    node->left = NULL;
    node->right = NULL;
    return node;
}

// 左旋
void leftRotate(TreapNode** node) {
    TreapNode* newRoot = (*node)->right;
    (*node)->right = newRoot->left;
    newRoot->left = (*node);
    *node = newRoot;
}

// 右旋
void rightRotate(TreapNode** node) {
    TreapNode* newRoot = (*node)->left;
    (*node)->left = newRoot->right;
    newRoot->right = (*node);
    *node = newRoot;
}

// 树堆插入操作
void insert(TreapNode** root, int key) {
    if ((*root) == NULL) {
        *root = createNode(key);
        return;
    }
    
    if (key < (*root)->key) {
        insert(&((*root)->left), key);
        if ((*root)->left && (*root)->left->priority > (*root)->priority) {
            rightRotate(root);
        }
    } else {
        insert(&((*root)->right), key);
        if ((*root)->right && (*root)->right->priority > (*root)->priority) {
            leftRotate(root);
        }
    }
}

// 前序遍历树堆
void preOrderTraversal(TreapNode* root) {
    if (root == NULL) {
        return;
    }
    
    printf("Key: %d, Priority: %d
", root->key, root->priority);
    preOrderTraversal(root->left);
    preOrderTraversal(root->right);
}

int main() {
    TreapNode* root = NULL;
    
    // 插入节点
    insert(&root, 8);
    insert(&root, 5);
    insert(&root, 12);
    insert(&root, 3);
    insert(&root, 10);
    
    // 前序遍历输出树堆
    preOrderTraversal(root);
    
    return 0;
}

三、红黑树(RB-Tree)的介绍

红黑树本质上是一个二叉树。
在这里插入图片描述

红黑树在二叉树的基础上具备如下的性质:

  1. 每个结点是红的或者黑的。
  2. 根结点是黑的。
  3. 每个叶子结点是黑的。
  4. 如果一个结点是红的,则它的两个儿子都是黑的。
  5. 对每个结点,从该结点到其子孙结点的所有路径上的 包含相同数目的黑结点 。

满足以上性质的二叉树就是红黑树。其中第五条性质就决定了红黑树的平衡,它不像AVL树那样严格要求两边子树的高度差是1,而是要求黑色节点的高度一致即可。

从第四条和第五条的性质中,我们可以总结出一个数学结论:红黑树的根节点到叶子节点的最短路径与红黑树的根节点到叶子节点的最长路径之比是 1 : ( 2 × N − 1 ) 1 :(2\times N-1) 1:2×N1
在这里插入图片描述
红黑树的优点:

  1. 严格的平衡性能保证。红黑树通过遵循一组严格的规则来保持平衡,如保持从根节点到叶节点的任何路径上的黑色节点数量相同。这种平衡性能保证了红黑树的最坏情况时间复杂度为O(logN)。
  2. 高效的查找、插入和删除操作。由于红黑树是二叉搜索树,通过颜色标记和旋转操作来维持平衡,操作具有较低的时间复杂度。
  3. 作为一种高效的自平衡树结构,被用于实现C++ STL的map、set等数据结构,以及数据库索引、编译器实现、网络路由算法等领域。

四、树堆(Treap)与红黑树(RB-Tree)的比较

  • 红黑树和树堆在查找、插入和删除操作上的平均性能是相似的,都是O(log n)。这是因为它们都是自平衡的二叉搜索树,通过调整树的结构来维护平衡性,以确保这些操作的时间复杂度保持在对数级别。
  • 树堆的空间复杂度通常较低,适用于需要高效的优先队列操作的场景。而红黑树的空间复杂度较高,但由于其自平衡性质,它在搜索、插入和删除等操作上具有良好的性能。
  • 树堆的实现复杂度相对较低,特别是在插入和删除操作上。红黑树相对复杂一些,具有更好的平衡性,可以保证树的高度较小,从而在查找操作上表现更好。
  • 如果需要频繁的插入和删除操作,并且对查找操作的性能要求不是特别高,那么树堆可能是一个更好的选择,因为它们在动态插入和删除方面更有效率。如果对查找操作的性能要求较高,希望确保树的平衡性,或者需要一种稳定的数据结构,那么红黑树可能更适合,因为它们在保持平衡和查找操作上具有更好的性能保证。

总结

树堆(Treap)和红黑树(RB-Tree)都是用于实现有序集合或映射的数据结构,但它们各自具有一些不同的优劣势,取决于具体的应用场景和需求。

树堆(Treap)的优势:

  • 简单而高效的实现: 树堆的实现相对较简单,只需要维护两个关键属性:BST的有序性和堆的优先级。这使得它易于实现和理解。

  • 动态操作高效: 树堆在频繁的插入和删除操作方面表现出色,因为它们利用了随机的优先级来维护树的平衡,通常不需要进行复杂的平衡调整。

  • 随机性能好: 在随机输入的情况下,树堆的性能通常很好,因为优先级的随机性可以保持树的平衡。

树堆(Treap)的劣势:

  • 不适用于特定的有序数据: 当数据的顺序是特定的,而不是随机的时候,树堆的性能可能不如其他平衡树结构。

  • 空间开销较大: 每个节点需要存储两个额外的信息:优先级和子树的大小,这可能会增加内存开销。

红黑树(RB-Tree)的优势:

  • 稳定的性能: 红黑树在平均和最坏情况下都能提供稳定的性能保证,确保查找、插入和删除操作的时间复杂度都是O(log n)。

  • 适用于有序数据: 红黑树适用于各种数据分布,包括有序数据,因为它可以保持相对平衡的状态。

  • 没有随机性: 红黑树不依赖于随机性,因此在任何输入情况下都能提供一定程度的平衡性。

红黑树(RB-Tree)的劣势:

  • 相对复杂的实现: 红黑树的实现相对复杂,需要维护颜色信息和执行平衡操作,因此可能比树堆难以理解和实现。

  • 动态操作略慢: 在频繁的插入和删除操作时,红黑树的性能可能略低于树堆,因为它们需要进行平衡操作。

如果需要高效的动态操作,树堆可能更合适。如果需要稳定的性能和对有序数据的支持,红黑树可能更适合。

在这里插入图片描述

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

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

相关文章

王道考研数据结构

文章目录 C 环境准备官方文档环境准备在线运行VSCode 环境报错解决 绪论线性表顺序表链表错题 栈、队列和数组栈队列栈的应用之中缀转后缀特殊矩阵用数组压缩存储错题 串模式匹配之暴力和KMP 树与二叉树二叉树树和森林哈夫曼树和哈夫曼编码并查集错题 图图的基本概念图的存储及…

LeetCode494. 目标和

494. 目标和 文章目录 [494. 目标和](https://leetcode.cn/problems/target-sum/)一、题目二、题解方法一&#xff1a;目标和路径计数算法方法二&#xff1a;01背包方法三&#xff1a;01背包一维数组 一、题目 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个…

IPC进程间通信及示例代码

一. 什么是进程通信 进程通信&#xff08; InterProcess Communication&#xff0c;IPC&#xff09;就是指进程之间的信息交换。实际上&#xff0c;进程的同步与互斥本质上也是一种进程通信&#xff08;这也就是待会我们会在进程通信机制中看见信号量和 PV 操作的原因了&#x…

Ubuntu18.04使用Systemback制作系统镜像并还原

系列文章目录 文章目录 系列文章目录前言一、下载Systemback工具二、制作系统镜像到U盘三、安装制作系统 前言 在Ubuntu系统中开发项目时&#xff0c;有时会希望将项目移植到另外一台计算机&#xff08;如工控机等&#xff09;上进行部署&#xff0c;通常会在新计算机中安装Ub…

Qt +VTK+Cmake 编译和环境配置(第二篇,中级篇, 重新编译)

1.下载VTK和Cmake 这里不介绍了。我的VTK 8.2.0 cmake 3.27.4 就是不服这编译器了。重新来一次 打开Cmake&#xff0c;把VTK源文件路径和目标路径设置一下&#xff08;目标路径自己设置&#xff0c;随意&#xff09; 点击Configure&#xff1a;。 点击下一步 选择好 Qt的gcc…

国际版阿里云/腾讯云:弹性高性能计算E-HPC入门概述

入门概述 本文介绍E-HPC的运用流程&#xff0c;帮助您快速上手运用弹性高性能核算。 下文以创立集群&#xff0c;在集群中安装GROMACS软件并运转水分子算例进行高性能核算为例&#xff0c;介绍弹性高性能核算的运用流程&#xff0c;帮助您快速上手运用弹性高性能核算。运用流程…

selenium 自动化测试——环境搭建

安装python&#xff0c;并且使用pip命令安装 selenium pip3 install selenium 然后尝试第一次使用selenium 完成一个简单的测试自动化脚本 from selenium import webdriver from selenium.webdriver.common.by import By import timedriver webdriver.Chrome() driver.get(…

A 股个股资金流排行 API 数据接口

A 股个股资金流排行 API 数据接口 全量股票资金流排名&#xff0c;多时间区间&#xff0c;全量A股数据。 1. 产品功能 支持所有A股资金流数据查询&#xff1b;每日定时更新数据&#xff1b;支持多时间段查询&#xff1b;超高的查询效率&#xff0c;数据秒级返回&#xff1b;数…

【问大家】电商问答数据的采集与深度分析

1. 引言 电商运营多年&#xff0c;功能越来越完善&#xff0c;我们发现当您购买过该商品之后&#xff0c;在消息-互动这里会看到别的网友提问的有关该商品的问题&#xff0c;这个功能叫问大家。 问大家模块可以说填补了宝贝评价部分的短板&#xff0c;评价部分单向传播属性较…

CSS中你不得不知道的css优先级

在我们定义css样式时&#xff0c;经常出现两个或更多规则应用在同一元素上&#xff0c;这时就会出现优先级的问题。其实css为每一种基础选择器都分配了一个权重。 我们简化理解&#xff1a; CSS权重计算&#xff1a; 最顶层&#xff1a;!important 权重值&#xff1a;…

【Django】让SQLite数据库中表名支持重命名的方法

修改了数据库表名之后&#xff0c;更新数据库时跳错&#xff1a; django.db.utils.NotSupportedError: Renaming the japi_api_info table while in a transaction is not supported on SQLite < 3.26 because it would break referential integrity. Try adding atomic F…

无涯教程-JavaScript - PERCENTILE函数

PERCENTILE函数替代Excel 2010中的PERCENTILE.INC函数。 描述 该函数返回范围中值的第k个百分位数。您可以使用此功能建立接受阈值。 语法 PERCENTILE (array,k)争论 Argument描述Required/OptionalArrayThe array or range of data that defines relative standing.Requi…

230920-部署Gradio到已有FastAPI及服务器中

1. 官方例子 run.py from fastapi import FastAPI import gradio as grCUSTOM_PATH "/gradio"app FastAPI()app.get("/") def read_main():return {"message": "This is your main app"}io gr.Interface(lambda x: "Hello, …

37. 交换字符(第三期模拟笔试)

题目&#xff1a; 给定一个01串&#xff08;仅由字符0和字符1构成的字符串&#xff09;。每次操作可以交换两个相邻的字符。 例如&#xff1a;对于字符串"001110"来说&#xff0c; 可以交换第二个字符0和第三个字符1&#xff0c;交换之后的字符串变成了"0101…

十、MySQL(DQL)条件查询

1、基础语法&#xff1a; select 字段列表 from 表名 where 条件列表; 2、实际操作&#xff1a; &#xff08;1&#xff09;初始化表格 &#xff08;2&#xff09;查询number大于444的员工 -- 查询number大于444的员工 select * from things where number>444; &#xff…

解决 filezilla 连接服务器失败问题

问题描述&#xff1a; 开始一直用的 XFTP 后来&#xff0c;它变成收费软件了&#xff0c;所以使用filezilla 代替 XFTP 之前用的还好好的&#xff0c;今天突然就报错了&#xff1a;按要求输入相关字段&#xff0c;连接 连接失败&#xff01;&#xff01;&#xff01;o(╥﹏╥…

海外有哪些流行的支付方式?

大家好&#xff0c;我是老三&#xff0c;很久没写支付相关的文章了&#xff0c;这期给大家讲一讲&#xff0c;海外都在用哪些支付方式。 简介 我们先来看下两个主流电商产品的美国站的支付方式&#xff1a; 在国内&#xff0c;想必大家都习惯了支付宝和微信支付二分天下&…

联合体(共用体)的简单介绍

目录 概念&#xff1a; 联合的声明&#xff1a; 类比结构体&#xff1a; 联合体的大小&#xff1a; 联合的⼤⼩⾄少是最⼤成员的⼤⼩ 联合体的空间是共用的 联合体内部成员的赋值&#xff1a; 当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候&#xff0c;就要对⻬到最⼤对⻬…

性能测试工具Jmeter你所不知道的东西····

谈到性能测试&#xff0c;大家一定会联想到Jmeter和LoadRunner,这两款工具目前在国内使用的相当广泛&#xff0c;主要原因是Jmeter是开源免费&#xff0c;LoadRunner 11在现网中存在破解版本。商用型性能测试工具对于中小型企业很难承担相关的费用。国内的性能测试工具有&#…

Java项目-苍穹外卖-Day08

文章目录 前言导入地址簿代码导入需求分析代码导入功能测试 用户下单需求分析接口设计数据库设计 代码开发功能测试 前言 本篇博客主要是用户端的功能完善 主要是三个功能 1.导入地址簿 2.点击去结算弹出结算页面 3.微信支付功能 导入地址簿代码导入 这个地址簿就是一个表的…