C++之双向链表与哈希链表用法区别实例(二百六十八)

2024-04-06 05:44

本文主要是介绍C++之双向链表与哈希链表用法区别实例(二百六十八),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:在阅读Linux内核代码时,发现Binder驱动中的双向链表和哈希链表的挺有意思,分享给大家。

2.双向链表与哈希链表介绍

  • 在Android的Binder区域中,双向链表(struct list_head)和哈希链表(struct hlist_node)是两种不同的数据结构,它们在实现中有一些区别和各自的作用。
  • 首先,让我们了解这两种数据结构的基本概念:
  1. 双向链表(struct list_head)

    • 双向链表是一种数据结构,其中每个节点都包含指向前一个节点和后一个节点的指针。这使得在双向链表中,节点可以双向遍历。
    • 在Linux内核中,双向链表是一种常见的数据结构,用于连接内核中的各种对象,例如进程、文件等。
    • 在Binder区域,双向链表常用于维护连接Binder驱动程序的客户端和服务端之间的通信通道。它们可以帮助管理Binder对象的生命周期和通信路线。
  2. 哈希链表(struct hlist_node)

    • 哈希链表是一种特殊的链表结构,它与传统链表不同之处在于,每个节点可能连接到一个链表桶中,而不是简单地按照顺序连接。
    • 在哈希链表中,节点被散列到特定的桶中,以提高检索效率。这使得在大型数据集中查找特定项的时间复杂度得到了显著改善。
    • 在Android的Binder区域,哈希链表通常用于管理Binder节点的分配和释放。通过哈希链表,系统可以更有效地管理Binder对象的分配和回收,以提高性能和资源利用率。

现在来比较双向链表和哈希链表在Binder区域中的作用和区别:

  1. 作用

    • 双向链表用于维护Binder通信通道的连接关系,帮助管理客户端和服务端之间的通信路线。
    • 哈希链表用于管理Binder对象的分配和释放,以提高资源管理的效率和性能。
  2. 区别

    • 双向链表提供了顺序访问节点的能力,而哈希链表则通过散列将节点分布到不同的桶中,提高了查找效率。
    • 双向链表的节点包含指向前一个和后一个节点的指针,而哈希链表的节点可能包含指向桶中下一个节点的指针。
  • 总的来说,在Android的Binder区域中,双向链表和哈希链表都是重要的数据结构,用于管理Binder对象和通信通道,但它们在实现方式和作用上略有不同,以满足不同的需求和优化性能。

Android的Binder驱动数据结构

  • 在Android的Binder驱动数据结构中,struct list_head 表示双向链表,而 struct hlist_head 和 struct hlist_node 表示哈希链表的头部和节点。

  • 1.双向链表 struct list_head

  • 每个 struct list_head 结构包含两个指针,分别指向下一个节点和前一个节点,因此构成了一个双向链表。

  • 用途:双向链表通常用于存储元素的有序集合,并且支持在常量时间内对链表中的元素进行插入、删除和前向/后向遍历。

  • 2.哈希链表 struct hlist_head 和 struct hlist_node

  • struct hlist_head 表示哈希链表的头部,其中包含一个指向链表的第一个节点的指针。

  • struct hlist_node 表示哈希链表中的节点,每个节点包含一个指向下一个节点的指针以及一个指向前一个节点指针的指针。

  • 用途:哈希链表通常用于在哈希表中解决哈希冲突。每个桶对应一个哈希链表,这样相同哈希值的键值对可以通过链表链接在一起。

3.代码实例

<1>.双向链表代码实例

#include <iostream>// 双向链表节点结构
struct list_head {struct list_head *next, *prev;
};int main() {// 创建双向链表struct list_head list;struct list_head node1, node2, node3;// 初始化双向链表头list.next = &node1;list.prev = &node3;// 初始化节点node1.next = &node2;node1.prev = &list;node2.next = &node3;node2.prev = &node1;node3.next = &list;node3.prev = &node2;// 遍历双向链表并打印节点地址struct list_head *pos;std::cout << "双向链表节点地址:";for (pos = list.next; pos != &list; pos = pos->next) {std::cout << pos << " ";}std::cout << std::endl;return 0;
}

<2>.哈希链表代码实例

#include <iostream>// 哈希链表头结构
struct hlist_head {struct hlist_node *first;
};// 哈希链表节点结构
struct hlist_node {struct hlist_node *next, **pprev;
};int main() {// 创建哈希链表struct hlist_head hash_table[10];struct hlist_node node1, node2, node3;// 初始化哈希链表头for (int i = 0; i < 10; ++i) {hash_table[i].first = NULL;}// 初始化节点node1.next = &node2;node1.pprev = &hash_table[0].first;node2.next = &node3;node2.pprev = &node1.next;node3.next = NULL;node3.pprev = &node2.next;// 遍历哈希链表并打印节点地址std::cout << "哈希链表节点地址:";struct hlist_node *hpos;for (hpos = hash_table[0].first; hpos != NULL; hpos = hpos->next) {std::cout << hpos << " ";}std::cout << std::endl;return 0;
}

这篇关于C++之双向链表与哈希链表用法区别实例(二百六十八)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

Java中HashMap的用法详细介绍

《Java中HashMap的用法详细介绍》JavaHashMap是一种高效的数据结构,用于存储键值对,它是基于哈希表实现的,提供快速的插入、删除和查找操作,:本文主要介绍Java中HashMap... 目录一.HashMap1.基本概念2.底层数据结构:3.HashCode和equals方法为什么重写Has

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对