`
Kslsi
  • 浏览: 23475 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

数据结构之好玩好难的hash table

阅读更多

       貌似每次写博客之前就得先说说自己又多久多久没有写过博客了,这次的博客距上次的已经过了快一年了,确实自制力不够,懒癌加拖延症患者伤不起。

        咳咳,接下来进入正题:数据结构已经很让人头疼了,不过更让人头疼的还有hash。那么什么是hash?

 

全称:hash table

简写:HT

中文名:散列表

结构:hash table中的一个位置叫做一个槽(怎么就感觉像是个坑),注意了:一个槽里只能放一个数据,槽的数量姑且用M表示,则一个hash table中就有用0—M-1编号的M个槽(不同hash table的结构不同,其中有一种就是在这个名为“槽”的坑里再挖若干个坑,要不然装不下我们要装的东西)。

怎么用:这里又涉及到名为“散列函数”的东西(不用知道它具体是什么样的,因为它具有变色龙的性质,知道它是一个函数就好),我们利用这个散列函数(实际上就是通过一系列的计算),将我们要保存的数据放到那一个一个坑里去。那么问题来了,要是坑里已经放了一个数据了,新数据通过计算之后又是应该放在那个坑里的,放不下怎么办,这样上面说的坑里再挖坑就排上用场了眨眼(当然不止这一种方法哦),这里,坑里再挖的坑由于需要有一定的灵活性,我们通常用链表来实现。

 

       通过以上简介,我们大概知道了hash table的大概情况了,接下来,上手了,代码来也~

 

 /**  
     * 存  
     * @param k  
     * @param v  
     */  
    public boolean put(K k, V v) {   
        // 1.计算K的hash值   
        // 直接调用JDK给出的hashCode()方法来计算hash值   
        int hash = k.hashCode();   
        //将所有信息封装为一个Entry   
        Entry< K,V> temp=new Entry(k,v,hash);   
            if(setEntry(temp, container)){   
                // 大小加一   
                size++;   
                return true;   
            }   
            return false;   
    }   

 

  /**  
     * 取  
     * @param k  
     * @return  
     */  
    public V get(K k) {   
        Entry< K, V> entry = null;   
        // 1.计算K的hash值   
        int hash = k.hashCode();   
        // 2.根据hash值找到下标   
        int index = indexFor(hash, container.length);   
        // 3.根据index找到链表   
        entry = container[index];   
        // 4.若链表为空,返回null   
        if (null == entry) {   
            return null;   
        }   
        // 5.若不为空,遍历链表,比较k是否相等,如果k相等,则返回该value   
        while (null != entry) {   
            if (k == entry.getKey()||entry.getKey().equals(k)) {   
                return entry.getValue();   
            }   
            entry = entry.getNext();   
        }   
        // 如果遍历完了不相等,则返回空   
        return null;   
  
    }   

 

 /**  
     *将指定的结点temp添加到指定的hash表table当中  
     * 添加时判断该结点是否已经存在  
     * 如果已经存在,返回false  
     * 添加成功返回true  
     * @param temp  
     * @param table  
     * @return  
     */  
    private boolean setEntry(Entry< K,V> temp,Entry[] table){   
        // 根据hash值找到下标   
        int index = indexFor(temp.getHash(), table.length);   
        //根据下标找到对应元素   
        Entry< K, V> entry = table[index];   
        // 3.若存在   
        if (null != entry) {   
            // 3.1遍历整个链表,判断是否相等   
            while (null != entry) {   
                //判断相等的条件时应该注意,除了比较地址相同外,引用传递的相等用equals()方法比较   
                //相等则不存,返回false   
             if ((temp.getKey() == entry.getKey()||temp.getKey().equals(entry.getKey())) && 
 temp.getHash() == entry.getHash()&&(temp.getValue()==entry.getValue()||temp.getValue().equals(entry.getValue()))) {   
                    return false;   
                }  
				
                 else if(temp.getKey() == entry.getKey() && temp.getValue() != entry.getValue()) { 
                     entry.setValue(temp.getValue()); 
                    return true; 
                } 
				 
                //不相等则比较下一个元素   
                else if (temp.getKey() != entry.getKey()) {   
                        //到达队尾,中断循环   
                        if(null==entry.getNext()){   
                            break;   
                        }   
                        // 没有到达队尾,继续遍历下一个元素   
                        entry = entry.getNext();   
                }   
            }   
            // 3.2当遍历到了队尾,如果都没有相同的元素,则将该元素挂在队尾   
            addEntry2Last(entry,temp);   
               return true;
        }   
        // 4.若不存在,直接设置初始化元素   
        setFirstEntry(temp,index,table);   
        return true;   
    }   

 

/**  
     * 扩容 
     * @param newSize  新的容器大小  
     */  
    private void reSize(int newSize) {   
        // 1.声明新数组   
        Entry< K, V>[] newTable = new Entry[newSize];   
        max = (int) (newSize * LOAD_FACTOR);   
        // 2.复制已有元素,即遍历所有元素,每个元素再存一遍   
        for (int j = 0; j < container.length; j++) {   
            Entry< K, V> entry = container[j];   
            //因为每个数组元素其实为链表,所以…………   
            while (null != entry) {   
                setEntry(entry, newTable);   
                entry = entry.getNext();   
            }   
        }   
        // 3.改变指向   
        container = newTable;   
           
    }   

 PS.扩容存在的意义:当一个槽里挖得坑太多了,总会有不能再挖的一天,这个时候我们就只能把槽的数量增加,当槽的数量增加之后,我们应该复制之前的所有元素,将其再遍历存一次。

 

最后的最后,各种数据结构增删查改的时间比较,省略。在下只附上hash表究竟有多快~

 

 

  • 大小: 16.4 KB
分享到:
评论

相关推荐

    哈希表(Hash Table)是一种高效的数据结构

    哈希表(Hash Table)是一种高效的数据结构

    数据结构 hash表 hash table 原理,以及实现介绍

    hash 表是我们经常使用的一种存储数据的结构,它查找性能不会因为数据的增长而下降。

    前端大厂最新面试题-hash-table.docx

    * Hash Table 是一种数据结构,通过哈希函数将关键字映射到索引,以便快速访问和查找元素。 * Hash Table 由数组和哈希函数组成,哈希函数将关键字转换为数组的索引。 二、哈希函数 * 哈希函数是将关键字转换为...

    上海交大数据结构课件 上海交大数据结构课件

    此外,哈希表(Hash Table)是另一种重要的数据结构,它通过散列函数实现快速的查找、插入和删除操作,达到近乎恒定的时间复杂度。而堆(Heap)是一种特殊的树形数据结构,通常用于实现优先队列,例如在排序算法(如...

    HASHbiao.rar_hash_哈西table_数据结构实验_文件查找

    哈希表(Hash Table),又称为散列表,是一种高效的数据结构,它通过特定的哈希函数将关键字映射到一个固定大小的数组中,从而实现快速查找、插入和删除操作。在标题“HASHbiao.rar_hash_哈西table_数据结构实验_...

    广工计算机数据结构课程设计之电梯模拟

    在"广工计算机数据结构课程设计之电梯模拟"这个项目中,学生们被要求运用所学的数据结构知识来实现一个电梯模拟系统。这个设计不仅检验了学生的编程技能,更重要的是锻炼了他们对数据结构的理解和应用能力。 电梯...

    清华大学教程 --数据结构

    此外,哈希表(Hash Table)是一种提供快速查找的数据结构,通过散列函数将键映射到数组的特定位置,实现常数时间的查找。堆(Heap)是一种特殊的树形数据结构,通常用于实现优先队列,如最大堆和最小堆。 排序算法...

    数据结构课后答案.pdf

    7. **哈希表(Hash Table)**:哈希表是一种通过哈希函数来实现快速查找的数据结构,它允许将键映射到特定的位置以存储数据,从而实现平均时间复杂度为O(1)的查找性能。冲突解决策略包括链地址法、开放寻址法等。 ...

    fpga-hash-table-master.zip_Table_fpga hash table_hash_hash fpga_

    "FPGA-based hash table"是指利用FPGA的特性实现的哈希表数据结构。哈希表是一种高效的数据存储和检索结构,它通过将关键字映射到数组的特定位置来快速查找、插入和删除数据。 哈希表的核心是哈希函数,它将输入的...

    Hash_Table.rar_C语言 哈希表_Table_数据结构代码

    哈希表,数据结构,完整代码,值得学习。C++语言

    u_hash_table.rar_Table For Two

    在IT领域,哈希表(Hash Table)是一种高效的数据结构,用于存储和检索键值对。标题中的"u_hash_table.rar_Table For Two"暗示我们关注的是一个特定的哈希表实现,可能是为处理两个相关对象设计的。描述中的"compare...

    数据结构_北大

    7. **高级数据结构**:如散列表(Hash Table)、B树和B+树、Trie树等,这些在数据库和文件系统中有着广泛的应用。 8. **实践应用**:结合实际问题,讲解如何选择合适的数据结构以及优化数据结构设计,提升程序性能...

    数据结构各种习题 很好很强大

    数据结构是计算机科学中的核心课程,它探讨了如何在计算机中高效地组织和管理数据,以便进行快速查询、存储和处理。本压缩包文件包含了多种数据结构相关的习题,可以帮助学习者深入理解和掌握数据结构的基本概念及其...

    数据结构(c语言版)课后题答案-(学生版 )

    7. **特殊数据结构**:如散列表(Hash Table)、堆(Heap)、队列的变形(如循环队列、优先队列)等,这些在实际编程中广泛应用。 在解答这些习题时,除了理解基本概念,还要考虑C语言的特性,如指针操作、内存管理...

    数据结构(Data Structure)是指在计算机科学中,用于组织、存储和管理数据的方式 数据结构可以帮助我们更好地组织和访问

    散列表(Hash Table):一种将键映射到值的数据结构。 堆(Heap):一种特殊的树形数据结构,用于实现优先队列。 ** Trie**(Trie):一种树形数据结构,用于实现字符串匹配和搜索。 数据结构的操作: 插入(Insert...

    李春葆数据结构教程上机实验全部源代码

    数据结构是计算机科学中的核心课程,它探讨了如何有效地存储和检索数据,是软件工程、算法分析和计算机系统设计的基础。李春葆教授的《数据结构教程》是该领域的经典教材,深受学生和专业人士的喜爱。这个压缩包包含...

    Java数据结构和算法中文第二版

    1. **数组(Array)**:数组是最基础的数据结构之一,通过连续的内存空间来存储相同类型的数据元素。 2. **链表(Linked List)**:链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针...

    数据结构课程设计之地铁线路查询

    数据结构课程设计是计算机科学教育中的重要组成部分,它涉及到如何高效地存储和处理数据,以解决实际问题。在这个“地铁线路查询”的项目中,我们主要会接触到以下关键知识点: 1. **图数据结构**:地铁线路可以被...

    数据结构408.xmind.zip

    此外,哈希表(Hash Table)是一种通过哈希函数将键映射到数组中的数据结构,提供了快速的查找、插入和删除操作。哈希冲突是哈希表面临的主要挑战,常见的解决方法有开放寻址法和链地址法。 排序是数据结构中不可或...

Global site tag (gtag.js) - Google Analytics