算法学习一,基础查找算法和排序算法

算法学习一,基础查找算法和排序算法

你提供的代码示例展示了两种常见的哈希表实现方法:拉链法(Separate Chaining)和线性探测法(Linear Probing)。每种方法都有其优缺点,适用于不同的场景。

拉链法(Separate Chaining)

拉链法通过将每个散列值对应的位置存储一个链表来解决冲突。这种方法的优点是简单且实现灵活,可以使用任何数据结构来存储冲突的键值对。以下是拉链法的主要特点:

  1. 优点

    • 简单且实现灵活。
    • 不会像线性探测那样导致同类哈希的聚集。
  2. 缺点

    • 需要额外的空间来存储链表。

代码示例(使用拉链法):

namespace StructScript { /// <summary> /// 哈希表的查找算法主要分为两步: /// 第一步是用哈希函数将键转换为数组的一个索引,理想情况下不同的键都能转换为不同的索引值,但是实际上会有多个键哈希到到相同索引值上。 /// 因此,第二步就是处理碰撞冲突的过程。这里有两种处理碰撞冲突的方法:separate chaining(拉链法)和linear probing(线性探测法)。 /// 拉链法: /// 使用链表来解决冲突 /// </summary> public class HashSearch2<T> { private int mCount = 16; // 线性探测表的大小 private List<T>[] mValues; public HashSearch2() { mValues = new List<T>[mCount]; for (int i = 0; i < mCount; i++) { mValues[i] = new List<T>(); } } private int HashCode(T value) { return (value.GetHashCode() & 0xFFFFFFF) % mCount; } public void Add(T value) { // 当碰撞发生时即一个键的散列值被另外一个键占用时,直接检查散列表中的下一个位置即将索引值加1 int index = HashCode(value); if (!mValues[index].Contains(value)) { mValues[index].Add(value); } } public bool Contains(T value) { // 当碰撞发生时即一个键的散列值被另外一个键占用时,直接检查散列表中的下一个位置即将索引值加1 int index = HashCode(value); return mValues[index].Contains(value); } } } 

线性探测法(Linear Probing)

线性探测法通过在冲突发生时,直接检查散列表中的下一个位置来解决冲突。这种方法的优点是简单,但会形成聚集现象,导致后续插入和查找操作的性能下降。

  1. 优点

    • 实现简单。
  2. 缺点

    • 会导致同类哈希的聚集。
    • 插入和查找操作在发生冲突时需要进行多次检查,性能下降。

代码示例(使用线性探测法):

namespace StructScript { /// <summary> /// 哈希表的查找算法主要分为两步: /// 第一步是用哈希函数将键转换为数组的一个索引,理想情况下不同的键都能转换为不同的索引值,但是实际上会有多个键哈希到到相同索引值上。 /// 因此,第二步就是处理碰撞冲突的过程。这里有两种处理碰撞冲突的方法:separate chaining(拉链法)和linear probing(线性探测法)。 /// 线性探测法: /// 使用大小为M的数组来保存N个键值对,我们需要使用数组中的空位解决碰撞冲突 /// 当碰撞发生时即一个键的散列值被另外一个键占用时,直接检查散列表中的下一个位置即将索引值加1 /// 线性探测虽然简单,但是有一些问题,它会导致同类哈希的聚集。在存入的时候存在冲突,在查找的时候冲突依然存在 /// </summary> public class HashSearch2<T> { private int mCount = 16; // 线性探测表的大小 private T[] mValues; public HashSearch2() { mValues = new T[mCount]; } private int HashCode(T value) { return (value.GetHashCode() & 0xFFFFFFF) % mCount; } public void Add(T value) { // 当碰撞发生时即一个键的散列值被另外一个键占用时,直接检查散列表中的下一个位置即将索引值加1 for (int i = 0; i < mCount; i++) { int index = (HashCode(value) + i) % mCount; if (mValues[index] == null || mValues[index].Equals(default(T))) { mValues[index] = value; break; } } } public bool Contains(T value) { // 当碰撞发生时即一个键的散列值被另外一个键占用时,直接检查散列表中的下一个位置即将索引值加1 for (int i = 0; i < mCount; i++) { int index = (HashCode(value) + i) % mCount; if (mValues[index] != null && mValues[index].Equals(value)) { return true; } if (mValues[index] == null) { break; } } return false; } } } 

总结

  • 拉链法:通过链表解决冲突,简单且实现灵活,但需要额外的空间。
  • 线性探测法:通过直接检查下一个位置解决冲突,实现简单但会导致聚集现象。

选择哪种方法取决于具体的应用场景和性能要求。如果对内存使用有较高要求,可以选择拉链法;如果对性能要求较高,可以考虑其他更复杂的哈希表实现方法,如双散列法(Double Hashing)或二次探测法(Quadratic Probing)。

Read more

【金仓数据库】ksql 指南(五) —— 创建与管理索引和视图(KingbaseES 查询优化核心)

【金仓数据库】ksql 指南(五) —— 创建与管理索引和视图(KingbaseES 查询优化核心)

引言 掌握表的基本运作之后,若想优化查询效率并简化数据访问,就要去学习“索引”和“视图”的运用,索引类似于“书籍目录”,可以极大地加快查询速度;视图类似“数据窗口”,能够隐藏复杂的查询逻辑,还能控制数据的可见性。本文就“ksql命令行操作索引与视图”展开论述,把从“作用到创建,再到查看,维持直至删除”的全过程拆解成实际操作步骤,并结合例子和避坑提示,以使初学者能够领悟并付诸实行。 文章目录 * 引言 * 一、前置准备:确认操作基础(衔接前文,确保连贯) * 1.1 1. 连接数据库并切换目标模式 * 1.2 2. 插入测试数据(用于验证索引 / 视图效果) * 二、索引管理:给表 “加目录”,加速查询 * 2.1 1.

By Ne0inhk
从 Express 到企业级架构:NestJS 实战指南与深度解析

从 Express 到企业级架构:NestJS 实战指南与深度解析

在 Node.js 的后端开发生态中,Express 长期以来以其极简主义占据统治地位。然而,随着项目规模的扩大,缺乏约束的“自由”往往会导致代码结构混乱,也就是我们常说的“意大利面条式代码”。 为了解决这个问题,NestJS 应运而生。NestJS 是一个用于构建高效、可扩展且易于维护的企业级后端应用的框架。它基于 TypeScript 构建,深受 Angular 架构的影响,引入了模块化、依赖注入(DI)和装饰器等先进概念。 本文将结合一个包含待办事项(Todos)管理和 PostgreSQL 数据库连接的实战 Demo,带你深入理解 NestJS 的核心架构。 一、 为什么选择 NestJS? 在开始写代码之前,我们需要理解 NestJS 试图解决什么问题。 1. 架构标准化:Express 让你自己决定文件放哪,而

By Ne0inhk
Go语言零基础小白学习知识点【基础版详解】

Go语言零基础小白学习知识点【基础版详解】

✅ 纯白话拆解+代码示例+实战场景,零基础能直接照着敲 ✅ 技术适配:基于Go 1.23(LTS长期支持版,企业主流),聚焦高并发、云原生核心场景 ✅ 条理清晰:从“环境搭建→基础语法→核心特性→实战入门”层层拆解,每个知识点落地到代码 ✅ 核心目标:小白不仅“懂概念”,更能“写得出、跑得起”,掌握Go语言入门核心能力 一、前置准备:先搞定环境和核心认知 1. Go语言是什么? Go(又称Golang)是谷歌2009年推出的编程语言,2026年已是云原生、高并发后端的首选语言——简单说: * 快:运行速度接近C/C++,编译速度秒杀Java; * 简单:语法比Java/Python更简洁,零基础3天能写业务代码; * 强:天生支持高并发,写直播、聊天、

By Ne0inhk
告别重复数据烦恼!MySQL ON DUPLICATE KEY UPDATE 优雅解决存在更新/不存在插入难题

告别重复数据烦恼!MySQL ON DUPLICATE KEY UPDATE 优雅解决存在更新/不存在插入难题

目录 * 前言 * 一、基本概念 * 1、什么是 ON DUPLICATE KEY UPDATE? * 2、工作原理 * 3、基本语法 * 二、使用场景 * 1、计数器更新 * 2、配置项更新 * 3、购物车商品更新 * 三、高级用法 * 1、条件更新 * 2、多表关联 * 3、批量操作优化 * 四、其他处理冲突的方案 * 1、REPLACE INTO * 2、INSERT IGNORE 前言 在日常的数据库操作中,我们经常会遇到这样的场景:“如果数据存在,就更新它;如果不存在,就插入一条新的”。这种模式通常被称为 “Upsert”(Update + Insert)。在

By Ne0inhk