Redis的实现三:c语言实现平衡二叉树,通过平衡二叉树实现排序集

概况:Redis中的排序集数据结构是相当复杂的独特而有用的东西。它不仅提供了顺序排序数据的能力,而且具有按排名查询有序数据的独特特性。

Redis中的排序集

(Sorted Set)是一种特殊的数据结构,它结合了集合(Set)和有序列表(List)的特点。在Redis中,每个成员都有一个分数(score),分数可以是整数或浮点数。根据分数对成员进行排序,分数较低的成员排在前面,分数较高的成员排在后面。

以下是Redis中排序集的一些基本操作:

  1. ZADD:向排序集中添加一个或多个成员,或者更新已存在成员的分数。
  2. ZREM:从排序集中移除一个或多个成员。
  3. ZRANGE:按照分数范围返回排序集中的成员。
  4. ZREVRANGE:按照分数范围逆序返回排序集中的成员。
  5. ZCOUNT:返回排序集中指定分数范围内的成员数量。
  6. ZINCRBY:将指定成员的分数增加指定的值。
  7. ZRANK:返回指定成员在排序集中的排名。
  8. ZREVRANK:返回指定成员在排序集中的排名(逆序)。
  9. ZSCORE:返回指定成员的分数。
  10. ZDIFF、ZINTER、ZUNION:合并多个排序集并返回结果。

实际上真正的Redis项目使用的是skiplist,跳表在一定程度上可以替代平衡二叉树

c语言实现平衡二叉树

第一步:定义结构体

typedef struct Node {int data;struct Node *left;struct Node *right;int height;
} Node;

左节点,右节点,深度,数据

第二步:定义比较算法

int max(int a, int b) {return (a > b) ? a : b;
}

这个很简单的算法,就是单纯的比较两个数,取其中最大的。

第三步:创建节点

Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->left = NULL;newNode->right = NULL;newNode->height = 1;return newNode;
}

第四步:得到高度

int getHeight(Node* node) {if (node == NULL) {return 0;}return node->height;
}

每个节点里面都包含了高度,这个属性。

第五步:计算平衡因子

int getBalance(Node* node) {if (node == NULL) {return 0;}return getHeight(node->left) - getHeight(node->right);
}

如果平衡因子为0,则表示该节点的左右子树高度相等,因此它是平衡的。如果getHeight(node->left) - getHeight(node->right)小于0,则表示左子树比右子树高,需要向左旋转操作来恢复平衡。如果getHeight(node->left) - getHeight(node->right)大于0,则表示右子树比左子树高,需要向右旋转操作来恢复平衡。

第六步:左旋函数

Node* leftRotate(Node* x) {Node* y = x->right;Node* T2 = y->left;y->left = x;x->right = T2;x->height = max(getHeight(x->left), getHeight(x->right)) + 1;y->height = max(getHeight(y->left), getHeight(y->right)) + 1;return y;
}

第七步:右旋函数

Node* rightRotate(Node* y) {Node* x = y->left;Node* T2 = x->right;x->right = y;y->left = T2;y->height = max(getHeight(y->left), getHeight(y->right)) + 1;x->height = max(getHeight(x->left), getHeight(x->right)) + 1;return x;
}

这里就不过多讲解了。和左旋一样,画个图就明白了。

第八步:插入函数

Node* insert(Node* node, int data) {if (node == NULL) {return createNode(data);}if (data < node->data) {node->left = insert(node->left, data);} else if (data > node->data) {node->right = insert(node->right, data);} else {return node;}node->height = 1 + max(getHeight(node->left), getHeight(node->right));int balance = getBalance(node);if (balance > 1 && data < node->left->data) {return rightRotate(node);}if (balance < -1 && data > node->right->data) {return leftRotate(node);}if (balance > 1 && data > node->left->data) {node->left = leftRotate(node->left);return rightRotate(node);}if (balance < -1 && data < node->right->data) {node->right = rightRotate(node->right);return leftRotate(node);}return node;
}

这里面大多都运用到了递归,兄弟们可以先了解递归再来看这个。

第九步:遍历函数

void inorderTraversal(Node* root) {if (root != NULL) {inorderTraversal(root->left);printf("%d ", root->data);inorderTraversal(root->right);}
}

第十步:测试看结果

完整代码

#include <stdio.h>
#include <stdlib.h>typedef struct Node {int data;struct Node *left;struct Node *right;int height;
} Node;int max(int a, int b) {return (a > b) ? a : b;
}Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->left = NULL;newNode->right = NULL;newNode->height = 1;return newNode;
}int getHeight(Node* node) {if (node == NULL) {return 0;}return node->height;
}int getBalance(Node* node) {if (node == NULL) {return 0;}return getHeight(node->left) - getHeight(node->right);
}Node* rightRotate(Node* y) {Node* x = y->left;Node* T2 = x->right;x->right = y;y->left = T2;y->height = max(getHeight(y->left), getHeight(y->right)) + 1;x->height = max(getHeight(x->left), getHeight(x->right)) + 1;return x;
}Node* leftRotate(Node* x) {Node* y = x->right;Node* T2 = y->left;y->left = x;x->right = T2;x->height = max(getHeight(x->left), getHeight(x->right)) + 1;y->height = max(getHeight(y->left), getHeight(y->right)) + 1;return y;
}Node* insert(Node* node, int data) {if (node == NULL) {return createNode(data);}if (data < node->data) {node->left = insert(node->left, data);} else if (data > node->data) {node->right = insert(node->right, data);} else {return node;}node->height = 1 + max(getHeight(node->left), getHeight(node->right));int balance = getBalance(node);if (balance > 1 && data < node->left->data) {return rightRotate(node);}if (balance < -1 && data > node->right->data) {return leftRotate(node);}if (balance > 1 && data > node->left->data) {node->left = leftRotate(node->left);return rightRotate(node);}if (balance < -1 && data < node->right->data) {node->right = rightRotate(node->right);return leftRotate(node);}return node;
}void inorderTraversal(Node* root) {if (root != NULL) {inorderTraversal(root->left);printf("%d ", root->data);inorderTraversal(root->right);}
}int main() {Node* root = NULL;root = insert(root, 70);root = insert(root, 20);root = insert(root, 30);root = insert(root, 40);root = insert(root, 50);root = insert(root, 25);printf("Inorder traversal of the constructed AVL tree is: ");inorderTraversal(root);return 0;
}

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

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

相关文章

C //练习 4-14 定义宏swap(t, x, y)以交换t类型的两个参数。(使用程序块结构会对你有所帮助。)

C程序设计语言 &#xff08;第二版&#xff09; 练习 4-14 练习 4-14 定义宏swap(t, x, y)以交换t类型的两个参数。&#xff08;使用程序块结构会对你有所帮助。&#xff09; 注意&#xff1a;代码在win32控制台运行&#xff0c;在不同的IDE环境下&#xff0c;有部分可能需要…

YOLOv7-tiny,通过pycocotools包得到预测大中小尺寸目标的指标值

文章目录 参考链接步骤认识正确的instances_val2017.json文件格式 代码&#xff08;mogui_tococo.py&#xff0c;用于我自己的数据集&#xff09; 参考链接 需要先在环境中安装pycocotools pip install pycocotools魔鬼面具的代码&#xff1a;objectdetection-tricks/tricks_…

openssl3.2 - 官方demo学习 - server-conf.c

文章目录 openssl3.2 - 官方demo学习 - server-conf.c概述笔记END openssl3.2 - 官方demo学习 - server-conf.c 概述 建立TLS服务器, 参数从配置文件中来.通过SSL_CONF_CTX_set_flags()来决定读那些TLS参数 遍历配置文件, 通过SSL_CONF_cmd()来读取预期的配置项. 如果不是TLS…

第 379 场 LeetCode 周赛题解

A 对角线最长的矩形的面积 模拟 class Solution { public:int areaOfMaxDiagonal(vector<vector<int>> &dimensions) {int res 0, len2 0;for (auto &x: dimensions)if (x[0] * x[0] x[1] * x[1] > len2 || x[0] * x[0] x[1] * x[1] len2 &&am…

SAP 如何快速查询成本的异常

每当月末CO月结的时候&#xff0c;生产企业或多或少会遇到标准成本与实际成本差异偏大的情况&#xff0c;我们如何快速查看产成品的成本异常&#xff0c;一般来说二者偏差5%是正常的&#xff0c;如果偏差20%&#xff0c;就要重点关注。我们通过0062报表来查看 进入“屏幕选择”…

C语言之函数的递归

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> //最简单的递归 int main() { printf("hehe\n"); main(); return 0; } //练习1&#xff1a;接受一个整型值&#xff0c;按顺序打印它的每一位 //例如&#xff1a;输入1234 输出 1 2 3 4 #…

进销存+小程序商城:实现批发零售企业的互联网转型与管理升级

在当今互联网高速发展的时代&#xff0c;越来越多的批发零售企业开始开始考虑转型。在这个行业中&#xff0c;企业要想取得更好的发展&#xff0c;就要积极地拥抱互联网。专属的订货商城小程序是企业转型的第一步。通过将进销存与订货商城一体化&#xff0c;企业可以更好地满足…

argparse库

引言 argparse-------python用于解析命令行参数的标准模块 快速上手 import argparse parser argparse.ArgumentParser() 创建一个命令行解析器对象 parser.add_argument() 向解析器…

C语言—存储管理

在C语言中&#xff0c;存储管理是指分配、使用和释放内存的过程。C提供了几个标准库函数来处理动态内存分配&#xff0c;这对于创建灵活且高效的程序至关重要。理解C语言的存储管理主要涉及以下几个方面&#xff1a; 1. 动态内存分配函数 malloc(size_t size) 分配指定大小的…

APP流量变现——4项关键指标决定了APP混合变现的收入

APP流量变现的方式有很多种&#xff0c;主要的可以分为IAA&#xff08;广告&#xff09;收入、IAP&#xff08;用户应用内付费&#xff09;收入、订阅收入、单次买断收入。这里主要围绕当前流行的混合变现模式&#xff0c;即广告收入&#xff08;IAA&#xff09;应用内付费&…

外汇天眼:塞浦路斯证券交易委员会(CySEC)确认了四家投资公司退出投资者赔偿基金(ICF)会员资格

塞浦路斯证券交易委员会&#xff08;CySEC&#xff09;今天确认了四家投资公司已被取消其在投资者赔偿基金&#xff08;ICF&#xff09;的会员资格。 以下公司不再是ICF的会员&#xff1a; 1.Stone Edge Capital Ltd&#xff08;LEI 213800PZFB9VV8FNWB30&#xff09;&#xf…

yum来安装php727

yum 安装php727,一键安装&#xff0c;都是安装在系统的默认位置&#xff0c;方便快捷 先确定linux平台中centos的版本信息&#xff0c;一下内容针对el7 查看linux版本 &#xff1a; cat /etc/redhat-release 查看内核版本命令&#xff1a; cat /proc/version (0)如果有安装好…

Hive中的四种排序

1.order by 全局排序&#xff0c;只有一个Reducer&#xff08;多个reducer无法保证全局有序&#xff09;&#xff0c;会导致当输入规模较大时&#xff0c;消耗较长的计算时间 hive.mapred.mode strict 模式下 必须指定 limit 否则执行会报错。 2.sort by 不是全局排序&…

3万字数据结构与算法学习笔记+知识点总结

文章目录 数据结构与算法排序排序算法常见排序算法复杂度冒泡排序&#xff08;Bubble Sort&#xff09;选择排序&#xff08;Selection Sort&#xff09;插入排序&#xff08;Insertion Sort&#xff09;希尔排序&#xff08;Shell Sort&#xff09;堆排序&#xff08;Heap Sor…

2024上海国际冶金及材料分析测试仪器设备展览会

2024上海国际冶金及材料分析测试仪器设备展览会 时间&#xff1a;2024年12月18&#xff5e;20日 地点&#xff1a;上海新国际博览中心 ◆ 》》》组织机构&#xff1a; 主办单位&#xff1a;全联冶金商会、中国宝武钢铁集团有限公司、上海市金属学会 支持单位&#xff…

Linux C语言 51-IO复用

Linux C语言 51-IO复用 本节关键字&#xff1a;Linux C语言 IO复用 相关C库函数&#xff1a;select&#xff08;FD_SET,FD_ISSET&#xff09;、epoll IO复用 epoll是Linux特有的。select是POSIX规定&#xff0c;一般操作系统均有实现。 名称支持进程打开最大连接数IO效率消…

浅谈电能管理系统在智能轨道交通中的设计与应用——安科瑞 顾烊宇

摘要&#xff1a;城市轨道交通可以填补市民出行方式的空缺&#xff0c;它的运行需要有持续的电能提供支持。为了给轨道交通营造稳定的运行环境&#xff0c;迫切需要建立相应的电能管理系统&#xff0c;以此实现高质量的电能供给。在本文中&#xff0c;将对应的电能管理系统作为…

MysqL——深入MySQL原理(一)

文章目录 MySQL架构图MySQL执行流程简要执行流程&#xff1a;详细执行流程 存储引擎SQL执行顺序存储结构实战演示 MySQL架构图 图例如下&#xff1a; server层&#xff1a; Connection Pool :连接池&#xff0c;负责管理持有所有的连接&#xff0c;采用BIO的技术&#xff0c;…

前端使用scale属性结合CSS动态样式实现动态的图片缩放效果

废话不多说&#xff0c;直接上代码&#xff1a; 示例一&#xff0c;使用css动态样式结合scale进行src图片的缩放。 //结构层&#xff0c;使用动态属性配合计算属性来实现动态样式<img :src"selectedItem.url" alt"" :style"elementStyle(item)&…

Android实现通过字符串找到图片、Class

1、通过字符串找到相应图片并展示 ApplicationInfo appInfo getActivity().getApplicationInfo();int resID getResources().getIdentifier("图片名字", "mipmap", appInfo.packageName);holder.setImageResource(R.id.title_img, resID);2、通过字符串找…