算法基础学习笔记——⑧堆\哈希表

news2024/11/29 4:36:48

博主:命运之光
专栏:算法基础学习

在这里插入图片描述

目录

✨堆

🍓堆模板:

✨哈希表

🍓一般哈希模板:

🍓字符串哈希模板:


前言:算法学习笔记记录日常分享,需要的看哈O(∩_∩)O,感谢大家的支持!


 ✨堆

如何手写一个堆?

1.插入一个数 heap[++size]=x;up(size);

2.求集合当中的最小值 heap[1]

3.删除最小值//用最后一个元素覆盖掉第一个元素heap[1]=heap[size];size--;down(1);

4.删除任意一个元素 heap[k]=heap[size];size--;down(k);up(k);

5.修改任意一个元素 heap[k]=x;down(k);up(k);

堆的基本结构:完全二叉树//除最后一层节点之外,上面所有结点都是满的,最后一层结点从左到右排列

堆的存储:用一维数组存

堆可以使用一维数组来进行存储。一维数组可以使用连续的内存空间来表示堆的结构。

堆是一种完全二叉树,可以按照从上到下、从左到右的顺序将其节点依次存储在一维数组中。对于一个具有 n 个节点的堆,可以使用一个长度为 n 的一维数组来存储。

假设堆的根节点存储在数组的索引为 0 的位置。对于任意一个节点 i,其左子节点的索引为 2i+1,右子节点的索引为 2i+2。同时,对于一个节点 i 的父节点,其索引为 (i-1)/2。

这种数组表示的好处是可以通过索引计算节点之间的关系,不需要使用指针或引用。

以下是一个示例,展示如何使用一维数组存储堆:

class Heap:
    def __init__(self):
        self.heap = []

    def parent(self, i):
        return (i - 1) // 2

    def left_child(self, i):
        return 2 * i + 1

    def right_child(self, i):
        return 2 * i + 2

    def insert(self, item):
        self.heap.append(item)
        self.heapify_up(len(self.heap) - 1)

    def heapify_up(self, i):
        while i != 0 and self.heap[i] < self.heap[self.parent(i)]:
            self.heap[i], self.heap[self.parent(i)] = self.heap[self.parent(i)], self.heap[i]
            i = self.parent(i)

    def extract_min(self):
        if len(self.heap) == 0:
            return None

        root = self.heap[0]
        self.heap[0] = self.heap[-1]
        self.heap.pop()
        self.heapify_down(0)

        return root

    def heapify_down(self, i):
        while (left := self.left_child(i)) < len(self.heap):
            smallest = left
            right = self.right_child(i)
            if right < len(self.heap) and self.heap[right] < self.heap[left]:
                smallest = right

            if self.heap[i] <= self.heap[smallest]:
                break

            self.heap[i], self.heap[smallest] = self.heap[smallest], self.heap[i]
            i = smallest

上述示例代码展示了一个最小堆的实现。堆的插入操作使用了堆化上移(`heapify_up`),从插入位置开始,将节点与其父节点进行比较并交换,直到满足堆的性质为止。堆的删除操作使用了堆化下移(`heapify_down`),从根节点开始,将节点与其较小的子节点进行比较并交换,直到满足堆的性质为止。

通过使用一维数组存储堆,可以方便地实现堆的各种操作,并且可以节省存储空间,提高访问效率。

堆的基本操作:

堆是一种常用的数据结构,它具有以下基本操作:

  1. 插入(Insertion):将一个新元素插入到堆中。插入操作通常用于将新元素添加到堆的末尾,并通过一系列交换操作将其移动到合适的位置,以保持堆的性质。对于最小堆,插入操作会将新元素插入到堆中并保持最小堆的性质;对于最大堆,则是保持最大堆的性质。

  2. 删除(Deletion):从堆中删除指定元素或者删除堆顶的元素。删除操作通常用于删除堆中的某个元素,并保持堆的性质不变。对于最小堆,删除操作通常删除堆顶的最小元素,并通过将堆的最后一个元素移动到堆顶,并通过一系列交换操作将其移动到合适的位置,以保持最小堆的性质。最大堆的删除操作也是类似的,只是操作的目标变成了删除堆顶的最大元素。

  3. 获取堆顶元素(Get Top):获取堆中的最小或最大元素,即堆顶的元素,而不进行删除操作。对于最小堆,获取堆顶元素即为获取堆中的最小元素;对于最大堆,则是获取堆中的最大元素。获取堆顶元素的时间复杂度为 O(1)。

🍓堆模板:

// h[N]存储堆中的值, h[1]是堆顶,x的左儿子是2x, 右儿子是2x + 1
// ph[k]存储第k个插入的点在堆中的位置
// hp[k]存储堆中下标是k的点是第几个插入的
int h[N], ph[N], hp[N], size;
// 交换两个点,及其映射关系
void heap_swap(int a, int b)
{
     swap(ph[hp[a]],ph[hp[b]]);//
     swap(hp[a], hp[b]);//交换所记录的在堆中插入的值的顺序
     swap(h[a], h[b]);//交换堆中的值
}
void down(int u)
{
     int t = u;
     if (u * 2 <= size && h[u * 2] < h[t]) t = u * 2;
     if (u * 2 + 1 <= size && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
     if (u != t)
     {
         heap_swap(u, t);
         down(t);
     }
}
void up(int u)
{
     while (u / 2 && h[u] < h[u / 2])
     {
         heap_swap(u, u / 2);
         u >>= 1;
     }
}
// O(n)建堆
for (int i = n / 2; i; i -- ) down(i);

✨哈希表

一般哈希

使用情况:将大范围数映射成小范围//哈希是把所有的数放在小空间存起来,然后解决冲突,离散化是把用到的抽取出来

🍓一般哈希模板:

(1) 拉链法

int h[N], e[N], ne[N], idx;
 // 向哈希表中插入一个数
 void insert(int x)
 {
     int k = (x % N + N) % N;
     e[idx] = x;
     ne[idx] = h[k];
     h[k] = idx ++ ;
 }
 // 在哈希表中查询某个数是否存在
 bool find(int x)
 {
     int k = (x % N + N) % N;
     for (int i = h[k]; i != -1; i = ne[i])
         if (e[i] == x)
             return true;
     return false;
 }

(2) 开放寻址法

int h[N];
 // 如果x在哈希表中,返回x的下标;如果x不在哈希表中,返回x应该插入的位置
 int find(int x)
 {
     int t = (x % N + N) % N;
     while (h[t] != null && h[t] != x)
     {
         t ++ ;
         if (t == N) t = 0;
     }
     return t;
 }

字符串哈希

字符串前缀哈希法//快速判断两个字符串是否相等

🍓字符串哈希模板:

🍒🍒核心思想:将字符串看成P进制数,P的经验值是131或13331,取这两个值的冲突概率低

🍒🍒小技巧:取模的数用2^64,这样直接用unsigned long long存储,溢出的结果就是取模的结果

typedef unsigned long long ULL;
ULL h[N], p[N]; // h[k]存储字符串前k个字母的哈希值, p[k]存储 P^k mod 2^64
// 初始化
p[0] = 1;
for (int i = 1; i <= n; i ++ )
{
     h[i] = h[i - 1] * P + str[i];
     p[i] = p[i - 1] * P;
}
// 计算子串 str[l ~ r] 的哈希值
ULL get(int l, int r)
{
     return h[r] - h[l - 1] * p[r - l + 1];
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/576537.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【是C++,不是C艹】 类与对象 | 认识面向对象 | 访问限定符 | 封装 | this指针

&#x1f49e;&#x1f49e;欢迎来到 Claffic 的博客&#x1f49e;&#x1f49e; &#x1f449; 专栏&#xff1a;《是C&#xff0c;不是C艹》&#x1f448; 前言&#xff1a; 在C入门之后&#xff0c;就要进入C的第一个核心&#xff1a;类与对象&#xff0c;这期带大家认识认识…

Multichain跨链无法到账,DApp真去中心化or伪去中心化?

团队出问题&#xff0c;DApp就用不了&#xff0c;multichain被不少人质疑伪去中心化&#xff0c;甚至更有人开始质疑web3&#xff0c;那么这到底是怎么回事呢&#xff1f; 跨链桥问题让DApp的去中心化引发质疑 事情是这样的&#xff0c;5月24下午0xscope发推称与multichain有关…

leetcode 11.盛最多水的容器

题目描述 跳转到leetocde题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff…

RabbitMQ手动ACK与死信队列

为了保证消息从队列可靠的达到消费者&#xff0c;RabbitMQ 提供了消息确认机制&#xff08;Message Acknowledgement&#xff09;。 默认情况下RabbitMQ在消息发出后就立即将这条消息删除,而不管消费端是否接收到,是否处理完,导致消费端消息丢失时RabbitMQ自己又没有这条消息了…

spring-Bean管理-springboot原理-Maven高级

spring-Bean管理-springboot原理-Maven高级 配置优先级Bean管理1.获取bean2.bean作用域3.第三方bean SpringBoot原理Maven高级1.分模块设计与开发2.继承与聚合3.私服1.介绍2.资源上传与下载 配置优先级 优先级(低→高) application.yaml&#xff08;忽略) application.yml appl…

利用Servlet编写第一个“hello world“(续)

利用Servlet编写第一个“hello world“ &#x1f50e;通过插件 Smart Tomcat 简化 打包代码 与 部署 操作下载Smart Tomcat配置Smart Tomcat &#x1f50e;Servlet 中的常见错误404(Not Found)&#x1f36d;请求路径出错&#x1f36d;war 包未被正确加载 405(Method Not Allowe…

【Android-JetpackCompose】13、实战在线课程 App

文章目录 一、BottomNavigation 底部导航1.1 底部导航栏的布局、点击1.2 设置 bottomBar 的颜色1.3 设置顶部 actionBar 的颜色 二、主页 StudyScreen2.1 顶部状态栏2.2 一、BottomNavigation 底部导航 1.1 底部导航栏的布局、点击 首先&#xff0c;构造 NavigationItem 的 d…

安装stable-diffusion

安装流程&#xff1a; 下载stable-diffusion源码 <https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases/tag/v1.2.1>安装python <https://www.python.org/ftp/python/3.10.6/python-3.10.6-amd64.exe>添加host 打开C:\Windows\System32\drivers\etc…

django基于scrapy的音乐歌曲分析及推荐系统

而在线音乐网站作为一个网络载体&#xff0c;在音乐的传播&#xff0c;创作&#xff0c;欣赏等方面对音乐的发展产生了前所未有的影响—。 &#xff08;1&#xff09;电脑网络技术的发展使人们通过音乐网站接触到了多的音乐模式。 &#xff08;2&#xff09;网民数量的激增使更…

两台群晖NAS之间使用FTP或SFTP进行数据高速拷贝问题

两台群晖NAS之间使用FTP或SFTP进行数据高速拷贝问题 为了更好的浏览体验&#xff0c;欢迎光顾勤奋的凯尔森同学个人博客http://www.huerpu.cc:7000 在有些时候&#xff0c;我们新买了一台全新群晖NAS需要把旧群晖NAS里的数据拷贝到新设备里&#xff0c;特别像电影、电视剧、小…

Python实战基础13-装饰器

1、先明白这段代码 第一波 def foo():print(foo)foo # 表示是函数 foo() # 表示执行foo函数第二波 def foo():print(foo)foo lambda x: x 1foo() # 执行lambda表达式&#xff0c;而不再是原来的foo函数&#xff0c;因为foo这个名字被重新指向了另外一个匿名函数函数名仅仅是…

攻不下dfs不参加比赛(九)

标题 为什么练dfs题目为什么练dfs 相信学过数据结构的朋友都知道dfs(深度优先搜索)是里面相当重要的一种搜索算法,可能直接说大家感受不到有条件的大家可以去看看一些算法比赛。这些比赛中每一届或多或少都会牵扯到dfs,可能提到dfs大家都知道但是我们为了避免眼高手低有的东…

Python入门(十三)函数(一)

函数&#xff08;一&#xff09; 1.函数概述2.函数定义2.1向函数传递信息2.2实参和形参 作者&#xff1a;xiou 1.函数概述 函数是带名字的代码块&#xff0c;用于完成具体的工作。要执行函数定义的特定任务&#xff0c;可调用该函数。需要在程序中多次执行同一项任务时&#…

win10微软Edge浏览器通过WeTab新标签页免费无限制使用ChatGPT的方法,操作简单,使用方便

目录 一、使用效果 二、注册使用教程 1.打开Edge浏览器扩展 2.选择Edge浏览器外接程序 3.搜索WeTab 4.进入管理扩展 5.启用扩展 ​编辑 6.进入WeTab新标签页 7.打开Chat AI 8.注册 9.使用 ChatGPT是OpenAI推出的人工智能语言模型&#xff0c;能够通过理解和学习人类…

opencv_c++学习(二十五)

一、Harris角点介绍 1、海瑞斯角点不可能出现在图像平滑的区域&#xff08;上图1&#xff09;&#xff1b; 2、图像边缘的支线出不可能出现海瑞斯角点&#xff08;上图2&#xff09;&#xff1b; 3、海瑞斯角点会出现在顶点处。&#xff08;上图3&#xff09;&#xff1b; 上图…

一文带你了解MySQL之redo日志

前言 本文以及接下来的几篇文章将会频繁的使用到我们前边唠叨的InnoDB记录行格式、页面格式、索引原理、表空间的组成等各种基础知识&#xff0c;如果大家对这些东西理解的不透彻&#xff0c;那么阅读下边的文字可能会特别的些费力&#xff0c;为保证您能正常的理解&#xff0…

Android 12系统源码_WindowInsets (一)WindowInsets相关类和功能介绍

一、什么是WindowInsets? WindowInsets源码解释为Window Content的一系列插值集合,可以理解为可以将其理解为不同的窗口装饰区域类型,比如一个Activity相对于手机屏幕需要空出的地方以腾给StatusBar、Ime、NavigationBar等系统窗口,具体表现为该区域需要的上下左右的宽高。…

Oracle Linux 8.8 发布 - Oracle 提供支持 RHEL 兼容发行版

Oracle Linux 8.8 发布 - Oracle 提供支持 RHEL 兼容发行版 Oracle Linux with Unbreakable Enterprise Kernel (UEK) & Red Hat compatible kernel (RHCK) 请访问原文链接&#xff1a;https://sysin.org/blog/oracle-linux-8/&#xff0c;查看最新版。原创作品&#xff…

opencv实践项目-图像卡通化

目录 1.如何使图像卡通画2.铅笔素描滤波器3. 细节增强滤波器4. 双边过滤器5. 铅笔边缘滤波器 1.如何使图像卡通画 我们通常需要执行两个主要步骤将图像转换为卡通图像&#xff1a;边缘检测和区域平滑。 边缘检测的主要目的显然是为了强调图像的边缘&#xff0c;因为卡通图像通…

银行从业——法律法规

第一章、经济基础知识 第一节、宏观经济分析 【 知识点1】 宏观经济发展目标 宏观经济发展的总体目标一般包括四个&#xff1a; 宏观经济发展的总体目标 衡量指标1、经济增长国内生产总值&#xff08;GDP&#xff09;2、充分就业 失业率3、物价稳定通货膨胀率4、国际…