python实现堆的基本操作及堆相关练习

2023-05-16

堆(heap)

又被为优先队列(priority queue)。尽管名为优先队列,但堆并不是队列。回忆一下,在队列中,我们可以进行的限定操作是dequeue和enqueue。

dequeue是按照进入队列的先后顺序来取出元素。而在堆中,我们不是按照元素进入队列的先后顺序取出元素的,而是按照元素的优先级取出元素。

性质

堆的实现通过构造二叉堆(binary heap),实为二叉树的一种;由于其应用的普遍性,当不加限定时,均指该数据结构的这种实现。这种数据结构具有以下性质。

  • 任意节点小于(或大于)它的所有后裔,最小元(或最大元)在堆的根上(堆序性)。
  • 堆总是一棵完全树。即除了最底层,其他层的节点都被元素填满,且最底层尽可能地从左到右填入。

实现

  • 堆的主要操作是插入和删除最小元素(元素值本身为优先级键值,小元素享有高优先级)
  • 在插入或者删除操作之后,我们必须保持该实现应有的性质: 1. 完全二叉树 2. 每个节点值都小于或等于它的子节点

上浮(Promotion)

情境: 子节点的键值变为比父节点的键值大;如下面添加字节点

消除这种违反项: 

  • 交换子节点的键和父节点的键 
  • 重复这个过程直到堆的顺序恢复正常

堆的添加:

下沉(Demotion) 

情境:父节点的键值变得比子节点(一个或者2个) 的键值还小 ,如下面删除了根节点后拿了个小子节点补充上来的情况

消除这种违反项:

  • 把父节点的键值和比它大的子节点的键值做交换
  • 重复这个操作直到堆的顺序恢复正常

删除最大值

参考博客:python数据结构之堆(heap) - kumata - 博客园

python实现常见堆操作

# 堆化实现 heapify(x)
def heapify(heap, n,index):
    # Transform list into a heap, in-place,index开始标志
    #n = len(heap)
    left = index * 2 + 1  # 左孩子下标
    while left < n:
        largest = left+1 if left + 1 < n and heap[left + 1] > heap[left] else left
        largest = largest if heap[largest] > heap[index] else index
        if largest == index:
            break
        heap[index], heap[largest] = heap[largest], heap[index]
        index = largest
        left = index * 2 + 1

def heapinsert(heap, index):
    f=int((index-1)>>1)
    while heap[index]>heap[f]:
        heap[index],heap[f] =heap[f] ,heap[index]
        index=f
def heapSort(arr):
    n = len(arr)
    # Build a maxheap.
    for i in range(n, -1, -1):
        heapify(arr, n, i)
    for i in range(n - 1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]  # 交换
        heapify(arr, i, 0)
if __name__ == '__main__':
    arr = [12, 11, 13, 5, 6, 7]
    heapSort(arr)
    n = len(arr)
    # for i in range(0, n, 1):
    #     heapinsert(arr, i)
    print("排序后")
    for i in range(n):
        print("%d" % arr[i])

python内置方法创建堆有两种方式,heappush()和heapify()

heaqp模块提供了堆队列算法的实现,也称为优先级队列算法。
要创建堆,请使用初始化为[]的列表,或者可以通过函数heapify()将填充列表转换为堆。 提供以下功能: heapq.heappush(堆,项目) 将值项推入堆中,保持堆不变。
heapq.heapify(x) 在线性时间内将列表x转换为堆。 heapq.heappop(堆) 弹出并返回堆中的最小项,保持堆不变。如果堆是空的,则引发IndexError。 

'''
heaqp模块提供了堆队列算法的实现,也称为优先级队列算法。
要创建堆,请使用初始化为[]的列表,或者可以通过函数heapify()将填充列表转换为堆。
提供以下功能:
heapq.heappush(堆,项目)
将值项推入堆中,保持堆不变。
heapq.heapify(x)
在线性时间内将列表x转换为堆。
heapq.heappop(堆)
弹出并返回堆中的最小项,保持堆不变。如果堆是空的,则引发IndexError。
'''
import heapq 

#1 heappush生成堆+ heappop把堆从小到大pop出来 
heap = []
data = [1,3,5,7,9,2,4,6,8,0]
for i in data:
    heapq.heappush(heap,i)
print(heap)

lis = []
while heap:
    lis.append(heapq.heappop(heap))
print(lis)

#2 heapify生成堆+ heappop把堆从小到大pop出来 
data2 = [1,5,3,2,9,5]
heapq.heapify(data2)
print(data2)

lis2 = []
while data2:
    lis2.append(heapq.heappop(data2))
print(lis2)

#输出结果
[0, 1, 2, 6, 3, 5, 4, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 5, 9, 5]
[1, 2, 3, 5, 5, 9]

 215. 数组中的第K个最大元素

难度中等950

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:输入: [3,2,1,5,6,4] 和 k = 2 输出: 5

示例 2:输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 输出: 4

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        nums.sort(reverse=True)
        return nums[k-1]

方法二:堆排序

方法三快速选择

#215. 数组中的第K个最大元素
import heapq
def findKthLargest(nums, k: int) :
    # nums.sort(reverse=True)
    # return nums[k-1]
    heap=[]
    for i in nums:
        heapq.heappush(heap, i*-1)
    print(heap)
    while k>1:
        k=k-1
        heapq.heappop(heap)
        print(heap)
    return heap[0]*-1
nums=[3,2,1,1,5,6,4]
k=2
# nums=[3,2,3,1,2,4,5,5,6]
# k=4
print(findKthLargest(nums, k))

692. 前K个高频单词

难度中等222

给一非空的单词列表,返回前 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。

示例 1:


输入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
    注意,按字母顺序 "i" 在 "love" 之前。  
#692. 前K个高频单词
from collections import Counter
def topKFrequent(words, k: int):
        count = Counter(words)
        candidates = list(count.keys())
        candidates.sort(key=lambda w: (-count[w], w))
        print(candidates)
        return candidates[:k]

words=["i", "love", "leetcode", "i", "love", "coding"]
k = 2
print(topKFrequent(words, k))

from collections import Counter
import heapq
def topKFrequent(words, k: int):
        count = Counter(words)
        # candidates = list(count.keys())
        # candidates.sort(key=lambda w: (-count[w], w))
        # print(candidates)
        # return candidates[:k]
        #堆
        heap,ans=[],[]
        heap = [(-freq, word) for word, freq in count.items()]
        heapq.heapify(heap)
        for i in range(k):
            ans.append(heapq.heappop(heap)[1])
        return ans

words=["i", "leetcode","love", "leetcode", "i", "love", "coding"]
k = 2
print(topKFrequent(words, k))

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python实现堆的基本操作及堆相关练习 的相关文章

  • docker搭建PyPI服务器

    运行 docker 服务器添加用户使用方法 上传 package使用仓库安装 package 运行 docker 服务器 首先创建服务器文件存放目录 xff08 如 pypi xff09 xff0c 进入目录 使用镜像 codekoala
  • 高维数据可视化之t-SNE算法

    https blog csdn net hustqb article details 78144384 t sne数学原理https zhuanlan zhihu com p 57937096 什么是t SNE xff1f t SNE的主要
  • Dynamic Key-Value Memory Networks for Knowledge Tracing论文阅读

    DKVMN模型效果不是很好 xff0c 但提供了很多新颖的方法思路 xff0c 最近看几篇文章都重点提到了这个模型并对这个模型进行改进 xff0c 回头仔细看一下这篇论文 动机 将KT公式化为监督序列学习问题 BKT和DKT 本文模型 本文
  • 记忆网络外部存储器

    结构化的外部记忆 记忆网络通常由四个模块构成 xff1a 主网络 外部记忆单元 读取模块 以及写入模块 主网络 也叫做控制器 xff0c 任务是解决内容和外界的交互 外部记忆单元负责存储信 息 xff0c 由很多记忆片段组成 xff0c 它
  • 简单爬虫入门

    来源莫烦爬虫 https mofanpy com tutorials data manipulation scraping understand website 爬网页流程 选着要爬的网址 url 使用 python 登录上这个网址 url
  • 正则表达式

    正则表达式这一篇就够了 xff0c 记录学习方便回来查找 文章来源https mofanpy com tutorials python basic basic regular expression https www cnblogs com
  • 数据可视化之 Matplotlib

    可参考 https mofanpy com tutorials data manipulation plt 基本用法 set new sticks new ticks 61 np linspace 1 2 5 print new ticks
  • 爬虫学习之下载图片

    首先找到网页的图片地址如 网址为 xff1a https i0 hdslb com bfs face 03525d094e0e2a142d08181532d729615c18ec92 jpg 找到了这个网址 我们就能开始下载了 为了下载到一
  • Python刷题之两数之和

    刷题之旅开始 day1 给定一个整数数组 nums 和一个整数目标值 target xff0c 请你在该数组中找出 和为目标值 的那 两个 整数 xff0c 并返回它们的数组下标 你可以假设每种输入只会对应一个答案 但是 xff0c 数组中
  • day2两数相加

    给你两个 非空 的链表 xff0c 表示两个非负的整数 它们每位数字都是按照 逆序 的方式存储的 xff0c 并且每个节点只能存储 一位 数字 请你将两个数相加 xff0c 并以相同形式返回一个表示和的链表 你可以假设除了数字 0 之外 x
  • day3三数之和

    给你一个包含 n 个整数的数组 nums xff0c 判断 nums 中是否存在三个元素 a xff0c b xff0c c xff0c 使得 a 43 b 43 c 61 0 xff1f 请你找出所有和为 0 且不重复的三元组 注意 xf
  • Nginx常见日志分析

    日志格式 39 remote addr remote user time local 34 request 34 status body bytes sent 34 http referer 34 34 http user agent 34
  • python爬虫入门之http协议和 Chrome 浏览器抓包工具

    在浏览器中发送一个http请求的过程 1 当用户在浏览器的地址栏中输入一个URL并按回车键之后 xff0c 浏览器会向HTTP服务器发送HTTP请求 HTTP请求主要分为 Get 34 和 Post 34 两种方法 当我们在浏览器输入URL
  • python爬虫之urllib库学习

    urllib库 urllib库是Python中一个最基本的网络请求库 可以模拟浏览器的行为 xff0c 向指定的服务器发送一个请求 xff0c 并可以保存服务器返 回的数据 urllib库是python内置的一个http请求库 xff0c
  • 爬虫练习之了解反爬虫机制

    没学习之前我理解字面意思就是你爬虫网站 xff0c 然后该网站顺着你的ip等会对你的网络电脑等造成损失 爬虫 使用任何技术手段批量获取网站信息的一种方式 xff0c 关键在批量 反爬虫 使用任何技术手段 xff0c 阻止别人批量获取自己网站
  • python爬虫之cookie

    python爬虫之cookie 什么是cookie 在网站中 xff0c http请求是无状态的 也就是说即使第一次和服务器连接后并且登录成功后 xff0c 第二次请求服务器依然不能知道当前请求是哪个用户 cookie的出现就是为了解决这个
  • python爬虫之request库

    发送get请求 1 最简单的发送get请求就是通过requests get来调用 response 61 requests get 34 URL 34 构造一个向服务器请求资源的Request对象 xff0c 返回一个包含服务器资源的Res
  • 爬虫之数据的提取 使用XPath 及lxml 初学者必备

    一 XPATH是什么 xff1f 干什么用的 xff1f xpath xff08 XML Path Language xff09 是一门在XML和HTML文档中查找信息的语言 xff0c 可用来在XML和HTML文档中对元素和属性进行遍历
  • 刷题之sum-closest

    给定一个包括 n 个整数的数组 nums 和 一个目标值 target 找出 nums 中的三个整数 xff0c 使得它们的和与 target 最接近 返回这三个数的和 假定每组输入只存在唯一答案 示例 xff1a 输入 xff1a num
  • 使用requests和xpath爬取电影天堂

    import requests from lxml import etree from openpyxl import Workbook URL 61 39 https dytt8 net html gndy dyzz list 23 1

随机推荐

  • day4数组之 删除排序数组中的重复项

    26删除排序数组中的重复项 给定一个排序数组 xff0c 你需要在 原地 删除重复出现的元素 xff0c 使得每个元素只出现一次 xff0c 返回移除后数组的新长度 不要使用额外的数组空间 xff0c 你必须在 原地 修改输入数组 并在使用
  • 爬虫之BeautifulSoup4库详解

    BeautifulSoup4库 和 lxml 一样 xff0c Beautiful Soup 也是一个HTML XML的解析器 xff0c 主要的功能也是如何解析和提取 HTML XML 数据 lxml 只会局部遍历 xff0c 而Beau
  • 在 VirtualBox 中安装 Debian 虚拟机

    在 VirtualBox 中安装 Debian 虚拟机 手把手一步一步带你在VirtualBox中安装Debian虚拟机 xff1b 打开VirtualBox软件点击新建 xff1a 配置信息 xff08 示例 xff09 xff1a 名称
  • 爬虫中国天气网数据并可视化

    中国天气网爬虫数据可视化 爬虫功能网页分析 以华北地区为例分析网页源代码 1 以谷歌浏览器为例分析2 提取特征标签3 分析源代码利用requests库获取目标网页源代码利用BeautifulSoup库提取天气信息港澳台地区代码分析分析数据数
  • day5刷题之 删除排序数组中的重复项 II

    80 删除排序数组中的重复项 II 难度中等361 给定一个增序排列数组 nums xff0c 你需要在 原地 删除重复出现的元素 xff0c 使得每个元素最多出现两次 xff0c 返回移除后数组的新长度 不要使用额外的数组空间 xff0c
  • day7刷题之二分搜索2

    33 搜索旋转排序数组 难度中等1187收藏分享切换为英文接收动态反馈 升序排列的整数数组 nums 在预先未知的某个点上进行了旋转 xff08 例如 xff0c 0 1 2 4 5 6 7 经旋转后可能变为 4 5 6 7 0 1 2 x
  • day6刷题之二分搜索1

    二分查找代码 class Solution public int searchInsert int nums int target int left 61 0 right 61 nums length 1 注意循环条件 while left
  • 正则表达式补充篇

    1 re match和re search match 和search 的区别 xff1a match xff08 xff09 函数只检测RE是不是在string的开始位置匹配 xff0c search 会扫描整个string查找匹配matc
  • 爬虫实战之爬取古诗文网站 (详细)

    爬取古诗文网站 重点是练习正则表达式的使用 链接变化 url base 61 39 https www gushiwen cn default aspx 39 for i in range 1 2 print 39 正在爬取第 页 xff1
  • 利用Python爬取糗事百科段子信息

    有个博客很详细https blog csdn net weixin 42488570 article details 80794087 要求 xff1a 用户ID xff0c 用户等级 xff0c 用户性别 xff0c 发表段子文字信息 x
  • 爬虫之数据存储(json,csv,mysql)等

    JSON支持数据格式 xff1a 对象 xff08 字典 xff09 使用花括号 数组 xff08 列表 xff09 使用方括号 整形 浮点型 布尔类型还有null类型 字符串类型 xff08 字符串必须要用双引号 xff0c 不能用单引号
  • MongoDB的安装及配置服务及使用

    安装配置 https blog csdn net heshushun article details 77776706 1 先在安装目录data文件下创建一个新文件夹log xff08 用来存放日志文件 xff09 2 在Mongodb安装
  • python多线程学习

    Python3 线程中常用的两个模块为 xff1a thread xff08 已经废弃 xff09 threading 推荐使用 线程模块 Python3 通过两个标准库 thread 和 threading 提供对线程的支持 thread
  • 爬虫实战之多线程下载表情包

    一般下载 import requests from lxml import etree import os import re from urllib request import urlretrieve headers 61 39 Use
  • 卷积padding,kernel_initializer

    TensorFlow和 keras layers convolutional Conv1D和tf layers Conv1D函数 keras layers convolutional Conv1D filters kernel size s
  • python刷题之链表常见操作

    链表常用操作 也可以把列表当做队列用 xff0c 只是在队列里第一加入的元素 xff0c 第一个取出来 xff1b 但是拿列表用作这样的目的效率不高 在列表的最后添加或者弹出元素速度快 xff0c 然而在列表里插入或者从头部弹出速度却不快
  • 刷题之链表

    链表相关 19 删除链表的倒数第 N 个结点 难度中等1261收藏分享切换为英文接收动态反馈 给你一个链表 xff0c 删除链表的倒数第 n 个结点 xff0c 并且返回链表的头结点 进阶 xff1a 你能尝试使用一趟扫描实现吗 xff1f
  • 高级爬虫: 使用 Selenium 浏览器

    安装Selenium和chromedriver xff1a 因为 Selenium 需要操控你的浏览器 所以安装起来比传统的 Python 模块要多几步 先在 terminal 或者 cmd 用 pip 安装 selenium python
  • python刷题之栈和队列

    20 有效的括号 难度简单2228 给定一个只包括 39 39 xff0c 39 39 xff0c 39 39 xff0c 39 39 xff0c 39 39 xff0c 39 39 的字符串 s xff0c 判断字符串是否有效 有效字符串
  • python实现堆的基本操作及堆相关练习

    堆 heap 又被为优先队列 priority queue 尽管名为优先队列 xff0c 但堆并不是队列 回忆一下 xff0c 在队列中 xff0c 我们可以进行的限定操作是dequeue和enqueue dequeue是按照进入队列的先后