`
128kj
  • 浏览: 613561 次
  • 来自: ...
社区版块
存档分类
最新评论

学习“五大经典查找”(2)

阅读更多
大家可否知道,其实查找中有一种O(1)的查找,即所谓的秒杀。

第三:哈希查找:
     对的,他就是哈希查找,说到哈希,大家肯定要提到哈希函数,呵呵,这东西已经在我们脑子里面形成固有思维了。大家一定要知道“哈希“中的对应关系。

     比如说: ”5“是一个要保存的数,然后我丢给哈希函数,哈希函数给我返回一个”2",那么此时的”5“和“2”就建立一种对应关系,这种关系就是所谓的“哈希关系”,在实际应用中也就形成了”2“是key,”5“是value。

    那么有的朋友就会问如何做哈希,首先做哈希必须要遵守两点原则:
          ①:  key尽可能的分散,也就是我丢一个“6”和“5”给你,你都返回一个“2”,那么这样的哈希函数不尽完美。
          ②: 哈希函数尽可能的简单,也就是说丢一个“6”给你,你哈希函数要搞1小时才能给我,这样也是不好的。

其实常用的做哈希的手法有“五种”:

第一种:”直接定址法“。
很容易理解,key=Value+C; 这个“C"是常量。Value+C其实就是一个简单的哈希函数。

第二种:“除法取余法”。
很容易理解, key=value%C;解释同上。

第三种:“数字分析法”。
  这种蛮有意思,比如有一组value1=112233,value2=112633,value3=119033,
针对这样的数我们分析数中间两个数比较波动,其他数不变。那么我们取key的值就可以是
   key1=22,key2=26,key3=90。

第四种:“平方取中法”。此处忽略,见名识意。

第五种:“折叠法”。
   这种蛮有意思,比如value=135790,要求key是2位数的散列值。那么我们将value变为13+57+90=160,   然后去掉高位“1”,此时key=60,哈哈,这就是他们的哈希关系,这样做的目的就是key与每一位value都相关,来做到“散列地址”尽可能分散的目地。

    正所谓常在河边走,哪有不湿鞋。哈希也一样,你哈希函数设计的再好,搞不好哪一次就撞楼了,那么抛给我们的问题就是如果来解决“散列地址“的冲突。

其实解决冲突常用的手法也就2种:

第一种: “开放地址法“。
所谓”开放地址“,其实就是数组中未使用的地址。也就是说,在发生冲突的地方,后到的那个元素(可采用两种方式
:①线性探测,②函数探测)向数组后寻找"开放地址“然后把自己插进入。

第二种:”链接法“。
  这个大家暂时不懂也没关系,我就先介绍一下原理,就是在每个元素上放一个”指针域“,在发生冲突的地方,后到的那个元素将自己的数据域抛给冲突中的元素,此时冲突的地方就形成了一个链表。

  上面啰嗦了那么多,也就是想让大家在”设计哈希“和”解决冲突“这两个方面提一点参考和手段。

那么下面就上代码了,
     设计函数采用:”除法取余法“。
     冲突方面采用:”开放地址线性探测法"。

import java.util.List;
import java.util.Arrays;
import java.util.Scanner;
public class HashProgram  
     {  
         //“除法取余法”   
         static int hashLength = 13;  
   
         //原数据 
          static Integer a[]={ 13, 29, 27, 28, 26, 30, 38 }; 
          static List<Integer> list=Arrays.asList(a);  
 
         //c#中可以这样啊!jdk1.7也不能啊
        // static List<int> list = new List<int>() { 13, 29, 27, 28, 26, 30, 38 };  
     
         //哈希表长度   
         static int[] hash = new int[hashLength];  
   
       public static void main(String[] args)  
         {  
             Scanner sca=new Scanner(System.in);
             //创建hash   
             for (int i = 0; i < list.size(); i++)  
             {  
                 InsertHash(hash, hashLength, list.get(i));  
             }  
   
             System.out.println("Hash表中的数据:");
             for(int i:hash)
               System.out.print(i+",");  
   
             while (true)  
             {  
                 System.out.printf("\n请输入要查找数字:");  
                 int result = sca.nextInt();  
                 int  index = SearchHash(hash, hashLength, result);  
   
                 if (index != -1)  
                   System.out.println("数字" + result + "在索引的位置是:" + index);  
                 else  
                   System.out.println("呜呜," + result + " 在hash中没有找到!");  
   
             }  
         }  
   
   
 // Hash表检索数据   

     static int SearchHash(int[] hash, int hashLength, int key)  
         {  
             //哈希函数   
             int hashAddress = key % hashLength;  
   
             //指定hashAdrress对应值存在但不是关键值,则用开放寻址法解决   
             while (hash[hashAddress] != 0 && hash[hashAddress] != key)  
             {  
                 hashAddress = (++hashAddress) % hashLength;  
             }  
   
             //查找到了开放单元,表示查找失败   
             if (hash[hashAddress] == 0)  
                 return -1;  
             return hashAddress;  
   
         }  
   
          
 //数据插入Hash表   
 
         static void InsertHash(int[] hash, int hashLength, int data)  
         {  
             //哈希函数   
             int hashAddress = data % 13;  
              //如果key存在,则说明已经被别人占用,此时必须解决冲突   
             while (hash[hashAddress] != 0)  
             {  
                 //用开放寻址法找到   
                 hashAddress = (++hashAddress) % hashLength;  
             }  
   
             //将data存入字典中   
             hash[hashAddress] = data;  
         }  
      
 }  


运行:
D:\java>java   HashProgram
Hash表中的数据:
13,27,28,29,26,30,0,0,0,0,0,0,38
请输入要查找数字:38
数字38在索引的位置是:12

请输入要查找数字:33
呜呜,33 在hash中没有找到!

请输入要查找数字:27
数字27在索引的位置是:1

请输入要查找数字:

第四:索引查找
  简称分级查找.例如汉字查找.对象是计算机为索引查找而建立的主表和各级索引表,主表只有一个,索引表的级数和数量不受限制,根据具体的需要确定.索引存储结构是数据组织的一项很重要的存储技术,在数据库领域中有广泛的应用.

  基本思想:首先把一个集合或线性表(主表)按照一定的函数关系或条件划分成若干个逻辑上的子表,为每个子表分别建立一个索引项,由所有这些索引项构成主表的一个索引表,然后,可采用顺序或是链接的方式来存储索引表和每个子表.

索引表包含三个域:
(1)索引值域,用来存储对应子表的索引值,相当于记录的关键字,在索引表中由此索引值来唯一标识一个索引项.

(2)表的开始位置域,用来存储对应子表的第一个元素的存储位置,从此位置出发可以依次访问到子表中的所有元素.

(3)子表的长度域:用来存储对应子表的元素个数.

  索引查找算法:是在索引表和主表上进行的查找.过程是:首先根据给定的索引值K1,在索引表上查找出索引值等于K1的索引项,以确定对应子表在主表的开始位置和长度.然后再根据给定的关键字K2,在对应的子表中查找出关键字等于K2的元素.对索引表或子表的查找时,若表是顺序存储的有序表,则可进行顺序查找,也可以进行二分查找.否则只能进行顺序查找.

import java.util.Arrays;
public class IndexSearch {  
  
    // 主表  
    static int[] students = { 101, 102, 103, 104, 105, 0, 0, 0, 0, 0, 201, 202,  
            203, 204, 0, 0, 0, 0, 0, 0, 301, 302, 303, 0, 0, 0, 0, 0, 0, 0 };  
    // 索引表  
    static IndexItem[] indexItem = { new IndexItem(1, 0, 5),  
            new IndexItem(2, 10, 4), new IndexItem(3, 20, 3), };  
  
    // 查找数据  
    public static int indexSearch(int key) {  
        IndexItem item = null;  
  
        // 建立索引规则  
        int index = key / 100;  
  
        // 首先去索引找  
        for (int i = 0; i < indexItem.length; i++) {  
            if (indexItem[i].index == index) {  
                item = indexItem[i]; 
                break;  
            }  
        }  
  
        // 如果item为null,则说明在索引中查找失败  
        if (item == null)  
            return -1;  
  
        for (int i = item.start; i < item.start + item.length; i++) {  
            if (students[i] == key) {  
                return i;  
            }  
        }  
        return -1;  
    }  
  
    // / 插入数据  
    public static int insert(int key) {  
        IndexItem item = null;  
        // 建立索引规则  
        int index = key / 100;  
        int i = 0;  
        for (i = 0; i < indexItem.length; i++) {  
            // 获取到了索引  
            if (indexItem[i].index == index) {  
                item = indexItem[i];
                break;  
            }  
        }  
        if (item == null)  
            return -1;  
        // 更新主表  
        students[item.start + item.length] = key;  
        // 更新索引表  
        indexItem[i].length++;  
        return 1;  
    }  
  
    public static void main(String[] args) {  
        int value = 205;  
        // 将205插入集合中,过索引  
        int index = insert(value);  
        insert(308);  
  
        // 如果插入成功,获取205元素所在的位置  
        if (index == 1) {  
            System.out.println("\n插入后数据:" + Arrays.toString(students));  
            System.out.println("\n数据元素:205在数组中的位置为 " + indexSearch(205) + "位");  
        }  
  
    }  
  
}  
  
// 索引项实体  
class IndexItem {  
    // 对应主表的值  
    public int index;  
    // 主表记录区间段的开始位置  
    public int start;  
    // 主表记录区间段的长度  
    public int length;  
  
    public IndexItem() {  
    }  
  
    public IndexItem(int index, int start, int length) {  
        this.index = index;  
        this.start = start;  
        this.length = length;  
    }  
}  


运行:
D:\java>java   IndexSearch

插入后数据:[101, 102, 103, 104, 105, 0, 0, 0, 0, 0, 201, 202, 203, 204, 205, 0, 0, 0, 0, 0, 301, 302, 303, 308, 0, 0, 0, 0, 0, 0]

数据元素:205在数组中的位置为 14位

下载源码:
分享到:
评论

相关推荐

    SNS单模无芯光纤仿真与传感器结构特性分析——基于Rsoft beamprop模块

    内容概要:本文主要探讨了SNS单模无芯光纤的仿真分析及其在通信和传感领域的应用潜力。首先介绍了模间干涉仿真的重要性,利用Rsoft beamprop模块模拟不同模式光在光纤中的传播情况,进而分析光纤的传输性能和模式特性。接着讨论了光纤传输特性的仿真,包括损耗、色散和模式耦合等参数的评估。随后,文章分析了光纤的结构特性,如折射率分布、包层和纤芯直径对性能的影响,并探讨了镀膜技术对光纤性能的提升作用。最后,进行了变形仿真分析,研究外部因素导致的光纤变形对其性能的影响。通过这些分析,为优化光纤设计提供了理论依据。 适合人群:从事光纤通信、光学工程及相关领域的研究人员和技术人员。 使用场景及目标:适用于需要深入了解SNS单模无芯光纤特性和优化设计的研究项目,旨在提高光纤性能并拓展其应用场景。 其他说明:本文不仅提供了详细的仿真方法和技术细节,还对未来的发展方向进行了展望,强调了SNS单模无芯光纤在未来通信和传感领域的重要地位。

    发那科USM通讯程序socket-rece

    发那科USM通讯程序socket-set

    嵌入式八股文面试题库资料知识宝典-WIFI.zip

    嵌入式八股文面试题库资料知识宝典-WIFI.zip

    JS+HTML源码与image

    源码与image

    物流行业车辆路径优化:基于遗传算法和其他优化算法的MATLAB实现及应用

    内容概要:本文详细探讨了物流行业中路径规划与车辆路径优化(VRP)的问题,特别是针对冷链物流、带时间窗的车辆路径优化(VRPTW)、考虑充电桩的车辆路径优化(EVRP)以及多配送中心情况下的路径优化。文中不仅介绍了遗传算法、蚁群算法、粒子群算法等多种优化算法的理论背景,还提供了完整的MATLAB代码及注释,帮助读者理解这些算法的具体实现。此外,文章还讨论了如何通过MATLAB处理大量数据和复杂计算,以得出最优的路径方案。 适合人群:从事物流行业的研究人员和技术人员,尤其是对路径优化感兴趣的开发者和工程师。 使用场景及目标:适用于需要优化车辆路径的企业和个人,旨在提高配送效率、降低成本、确保按时交付货物。通过学习本文提供的算法和代码,读者可以在实际工作中应用这些优化方法,提升物流系统的性能。 其他说明:为了更好地理解和应用这些算法,建议读者参考相关文献和教程进行深入学习。同时,实际应用中还需根据具体情况进行参数调整和优化。

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_8.doc.zip

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_8.doc.zip

    基于灰狼优化算法的城市路径规划Matlab实现——解决TSP问题

    内容概要:本文介绍了基于灰狼优化算法(GWO)的城市路径规划优化问题(TSP),并通过Matlab实现了该算法。文章详细解释了GWO算法的工作原理,包括寻找猎物、围捕猎物和攻击猎物三个阶段,并提供了具体的代码示例。通过不断迭代优化路径,最终得到最优的城市路径规划方案。与传统TSP求解方法相比,GWO算法具有更好的全局搜索能力和较快的收敛速度,适用于复杂的城市环境。尽管如此,算法在面对大量城市节点时仍面临运算时间和参数设置的挑战。 适合人群:对路径规划、优化算法感兴趣的科研人员、学生以及从事交通规划的专业人士。 使用场景及目标:①研究和开发高效的路径规划算法;②优化城市交通系统,提升出行效率;③探索人工智能在交通领域的应用。 其他说明:文中提到的代码可以作为学习和研究的基础,但实际应用中需要根据具体情况调整算法参数和优化策略。

    嵌入式八股文面试题库资料知识宝典-Intel3.zip

    嵌入式八股文面试题库资料知识宝典-Intel3.zip

    嵌入式八股文面试题库资料知识宝典-2019京东C++.zip

    嵌入式八股文面试题库资料知识宝典-2019京东C++.zip

    嵌入式八股文面试题库资料知识宝典-北京光桥科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-北京光桥科技有限公司面试题.zip

    物理学领域十字形声子晶体的能带与传输特性研究及应用

    内容概要:本文详细探讨了十字形声子晶体的能带结构和传输特性。首先介绍了声子晶体作为新型周期性结构在物理学和工程学中的重要地位,特别是十字形声子晶体的独特结构特点。接着从散射体的形状、大小、排列周期等方面分析了其对能带结构的影响,并通过理论计算和仿真获得了能带图。随后讨论了十字形声子晶体的传输特性,即它对声波的调控能力,包括传播速度、模式和能量分布的变化。最后通过大量实验和仿真验证了理论分析的正确性,并得出结论指出散射体的材料、形状和排列方式对其性能有重大影响。 适合人群:从事物理学、材料科学、声学等相关领域的研究人员和技术人员。 使用场景及目标:适用于希望深入了解声子晶体尤其是十字形声子晶体能带与传输特性的科研工作者,旨在为相关领域的创新和发展提供理论支持和技术指导。 其他说明:文中还对未来的研究方向进行了展望,强调了声子晶体在未来多个领域的潜在应用价值。

    嵌入式系统开发_USB主机控制器_Arduino兼容开源硬件_基于Mega32U4和MAX3421E芯片的USB设备扩展开发板_支持多种USB外设接入与控制的通用型嵌入式开发平台_.zip

    嵌入式系统开发_USB主机控制器_Arduino兼容开源硬件_基于Mega32U4和MAX3421E芯片的USB设备扩展开发板_支持多种USB外设接入与控制的通用型嵌入式开发平台_

    e2b8a-main.zip

    e2b8a-main.zip

    少儿编程scratch项目源代码文件案例素材-火柴人跑酷(2).zip

    少儿编程scratch项目源代码文件案例素材-火柴人跑酷(2).zip

    【HarmonyOS分布式技术】远程启动子系统详解:跨设备无缝启动与智能协同的应用场景及未来展望

    内容概要:本文详细介绍了HarmonyOS分布式远程启动子系统,该系统作为HarmonyOS的重要组成部分,旨在打破设备间的界限,实现跨设备无缝启动、智能设备选择和数据同步与连续性等功能。通过分布式软总线和分布式数据管理技术,它能够快速、稳定地实现设备间的通信和数据同步,为用户提供便捷的操作体验。文章还探讨了该系统在智能家居、智能办公和教育等领域的应用场景,展示了其在提升效率和用户体验方面的巨大潜力。最后,文章展望了该系统的未来发展,强调其在技术优化和应用场景拓展上的无限可能性。 适合人群:对HarmonyOS及其分布式技术感兴趣的用户、开发者和行业从业者。 使用场景及目标:①理解HarmonyOS分布式远程启动子系统的工作原理和技术细节;②探索该系统在智能家居、智能办公和教育等领域的具体应用场景;③了解该系统为开发者提供的开发优势和实践要点。 其他说明:本文不仅介绍了HarmonyOS分布式远程启动子系统的核心技术和应用场景,还展望了其未来的发展方向。通过阅读本文,用户可以全面了解该系统如何通过技术创新提升设备间的协同能力和用户体验,为智能生活带来新的变革。

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_1.zip

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_1.zip

    少儿编程scratch项目源代码文件案例素材-激光反弹.zip

    少儿编程scratch项目源代码文件案例素材-激光反弹.zip

    COMSOL相控阵检测技术在有机玻璃斜楔中检测工件内部缺陷的应用研究

    内容概要:本文详细介绍了COMSOL相控阵检测技术在有机玻璃斜楔上放置16阵元进行工件内部缺陷检测的方法。首先阐述了相控阵检测技术的基本原理,特别是通过控制各阵元的激发时间和相位来实现声波的聚焦和扫描。接着,重点解析了横孔缺陷的反射接收波,解释了波的折射现象及其背后的物理原因。最后,通过实例展示了COMSOL模拟声波传播过程的成功应用,验证了该技术的有效性和准确性。 适合人群:从事固体力学、无损检测领域的研究人员和技术人员,尤其是对相控阵检测技术和COMSOL仿真感兴趣的读者。 使用场景及目标:适用于需要精确检测工件内部缺陷的研究和工业应用场景,旨在提高检测精度和效率,确保产品质量和安全。 其他说明:文中提到的声速匹配现象有助于理解波在不同介质间的传播特性,这对优化检测参数设置有重要意义。

    少儿编程scratch项目源代码文件案例素材-极速奔跑者.zip

    少儿编程scratch项目源代码文件案例素材-极速奔跑者.zip

    嵌入式八股文面试题库资料知识宝典-微软_interview.zip

    嵌入式八股文面试题库资料知识宝典-微软_interview.zip

Global site tag (gtag.js) - Google Analytics