最近我在做一个项目,其中要用到一个数据结构——Hash Table(哈希表),以前只有理论知识,现在实却发现很不简单,所以写下来和大家共分享。
我们知道,哈希表是一个固定大小的数组,数组的每个元素是一个链表(单向或双向)的头指针。如果Key一样,则在一起,如果Key不一样,则不在一起。哈希表的查询是飞快的。因为它不需要从头搜索,它利用Key的“哈希算法”直接定位,查找非常快,各种数据库中的数据结构基本都是它。但带来的问题是,哈希表的尺寸、哈希算法。
哈希表的数组是定长的,如果太大,则浪费,如果太小,体现不出效率。合适的数组大小是哈希表的性能的关键。哈希表的尺寸最好是一个质数,最小的质数尺寸是17。
当然,根据不同的数据量,会有不同的哈希表的大小。对于数据量很时多时少的应用,最好的设计是使用动态可变尺寸的哈希表,那么如果你发现哈希表尺寸太小了,比如其中的元素是哈希表尺寸的2倍时,我们就需要扩大哈希表尺寸,一般是扩大一倍。下面的数库是哈希表变化尺寸时尺寸大小的一个列表。
static int prime_array[] = {
17, /* 0 */
37, /* 1 */
79, /* 2 */
163, /* 3 */
331, /* 4 */
673, /* 5 */
1361, /* 6 */
2729, /* 7 */
5471, /* 8 */
10949, /* 9 */
21911, /* 10 */
43853, /* 11 */
87719, /* 12 */
175447, /* 13 */
350899, /* 14 */
701819, /* 15 */
1403641, /* 16 */
2807303, /* 17 */
5614657, /* 18 */
11229331, /* 19 */
22458671, /* 20 */
44917381, /* 21 */
89834777, /* 22 */
179669557, /* 23 */
359339171, /* 24 */
718678369, /* 25 */
1437356741, /* 26 */
2147483647 /* 27 (largest signed int prime) */
};
#define PRIME_ARRAY_SIZE (28)
要使用哈希表,就一定要用一个哈希算法,来确定KEY值,这似乎是个很难的事,下面是一个哈希算法:
typedef struct _hTab{
hLinks*link; /* 一个链表 */
intnum; /* 成员个数 */
intsize; /* 表的尺寸 */
} hTab;
static unsigned int
getHashIndex(hTab *tabPtr, const char *key)
{
unsigned int ha = 0;
while (*key)
ha = (ha * 128 + *key++) % tabPtr->size;
return ha;
}
(其中key是一个字符串,hTab就是一个哈希表结构, tabPtr->size是哈希表数组的大小)
这个算法被实施证明是比较不错的,能够达到分散数据的效果,如果你有更好的算法,欢迎和我交流。(litmouse@km169.net)
————
(版权所有,如需转载,请注明出处及作者)
分享到:
相关推荐
最后,学生的心得体会可能会涵盖在项目中遇到的挑战、解决问题的方法、以及对数据结构和哈希表理解的加深。通过这个课程设计,学生不仅掌握了哈希表的理论知识,还获得了实践经验,提高了编程和问题解决能力。
至于“截图”和“心得体会”部分,可能会展示哈希表的可视化示例、代码片段的截图,以及作者在设计和实现过程中遇到的问题及解决方案的个人见解。 总的来说,这份文档详细介绍了如何根据需求分析来设计和构建一个...
- 学生会有个人的感想和学习心得,例如对哈希表理解的加深、实际编程经验的积累等。 哈希表的效率在于其查找、插入和删除操作的时间复杂度可以接近O(1),但在存在哈希冲突的情况下,性能会下降。在这个电话号码...
数据结构课程实验中,哈希表的设计与实现是一项重要的任务,旨在帮助学生深入理解哈希表的概念和工作原理。哈希表是一种数据结构,通过哈希函数将数据映射到一个固定大小的数组中,以实现快速的查找、插入和删除操作...
解题思路与解法二相同,先创建一个哈希表,然后遍历数组,利用哈希表查找目标值减去当前元素值的键是否存在,并确保找到的索引不是当前索引。这种方法在代码实现上更完整,同时保持了O(n)的时间复杂度和O(n)的空间...
在这个例子中,可以添加一个哈希表,遍历文本中的每个单词,如果单词已经在哈希表中,则增加其计数,否则添加到哈希表中。 4. **事件处理**:C#中的Windows Forms应用程序是事件驱动的,`button1_Click`和`Form1_...
二分搜索在有序数组中寻找目标值时效率极高,而哈希表的查找速度可以达到近乎常数级别,这对于大数据处理尤其重要。 图论是解决许多实际问题的工具,包括最短路径算法(如Dijkstra算法和Floyd-Warshall算法)和最小...
分区是将大表分成更小、更易管理的部分,可以提高查询性能和维护效率,常见的分区方式有范围分区、列表分区、哈希分区和复合分区。 在学习Oracle的过程中,实践操作是至关重要的。例如,你可以通过SQL*Plus或PL/SQL...
【Java算法刷题笔记(LeetCode、牛客)】这篇笔记主要涵盖了三个核心知识点:双指针技巧、哈希表的应用以及深度优先搜索算法(DFS)。 1. **双指针技术**: 双指针是算法中常用的一种技巧,通常用于处理链表和数组的...
二分查找适用于有序数据,而哈希表查找能实现近乎瞬时的查找速度,但需要额外的空间。 5. **图论与网络流**:图算法如Dijkstra最短路径算法、Floyd-Warshall算法和Prim最小生成树算法,以及最大流问题的Ford-...
这门课程涵盖了数据结构中的基本概念,如数组、链表、栈、队列,以及更高级的结构如树、图、哈希表等,并深入讲解了如何用C++来实现这些结构。同时,也涉及了算法分析和设计,包括排序和搜索算法。 首先,数组是最...
- 哈希表查找(`HashTablesearch`):使用哈希表存储单词,通过输入单词快速定位,时间复杂度理想情况下为O(1)。 - 分块查找(`Blocksearch`):将单词数组分成多个块,每个块有固定数量的单词,通过比较块中最大...
面试算法通常包括但不限于排序算法(如快速排序、归并排序)、查找算法(二分查找、哈希表查找)、图论问题(最短路径算法、拓扑排序)、动态规划等。这些算法不仅在面试中常见,也是解决实际问题的重要工具。 在...
6. **哈希表**:哈希表通过哈希函数将数据映射到一个固定大小的数组中,实现快速的查找、插入和删除操作。哈希冲突是哈希表需要解决的关键问题。 7. **树**:树是一种非线性数据结构,每个节点可能有零个或多个子...
8. 存储结构:在数据结构领域,主要的存储方式有顺序存储(数组)、链式存储(链表)、索引存储(B树、B+树等)和散列存储(哈希表)。 这些知识点构成了Java学习的基础,理解并掌握它们对于通过Java相关的考试或...
查找是数据处理的核心操作,面试中会涉及顺序查找、二分查找、哈希表查找等。对于哈希表,需理解哈希冲突的解决方法(开放寻址法、链地址法)。同时,掌握A*算法、Dijkstra算法、Floyd算法等图论中的最短路径求解...
4. **Hashtable**:Hashtable 是一种基于哈希表的集合,提供了快速的键值对查找。键是唯一的,且必须实现`GetHashCode`方法来确定元素的存储位置。它适用于大量的查找操作。 5. **SortedList**:SortedList 类似于 ...