【零基础】学python数据结构与算法笔记10

news2025/1/18 11:54:53

文章目录

  • 前言
  • 57.链表介绍
  • 58.链表的创建和遍历
  • 59.链表的插入和删除
  • 60.双链表
  • 61.链表总结
  • 62.哈希表
  • 62.哈希表实现
  • 64.哈希表应用
  • 总结


前言

学习python数据结构与算法,学习常用的算法,
b站学习链接

57.链表介绍

链表是由一系列节点组成的元素集合。每个节点包含两部分,数据域item和指向下一个节点的指针next。通过节点之间的相互连接,最终串联成一个链表。
在这里插入图片描述
手动创建的链表,将next指向下一个。
在这里插入图片描述

58.链表的创建和遍历

创建链表有两种方式:
一种头插法,一种尾插法

头插法,比如现在链表2,1,新来了一个节点3,插入3分两步,先把3和2连起来 3.next=head
然后head = 3
在这里插入图片描述
尾插法,有头有尾,新来一个3,插入分两步,先把2和3连起来,tail.next=3
然后tail = 3
在这里插入图片描述

往头插相当于倒序所以是3,2,1,尾插的正序
在这里插入图片描述

59.链表的插入和删除

链表节点的插入
现在链表1,2,3怎么把4插进当前节点1的后面去。
如果先把1连到4,那1.next指向4了,指向2 的next就找不着了,
所以先将4的next指向2,再将1指向4
所以
p.next = curNode.next
curNode.next = p
在这里插入图片描述
链表的删除
把4从1的后面删除
如果先把4删除,指向2的next就没了,2就找不着了
所以先把1连到2
再把4删除
p = curNode.next
curNode.next = curNode.next.next #相当于p.next
del p
在这里插入图片描述
链表的插入删除都是O(1),而列表的复杂度是O(n)

60.双链表

双链表的每个节点都有两个指针:一个指向后一个节点,另一个指向前一个节点。
在这里插入图片描述
在这里插入图片描述

双链表的插入 这里(1,3插入2)
一样不能1和2先连,这样3就会断掉,要2和3先连,然后1和2连,
p.next = curNode.next
curNode.next.prior = p
p.prior = curNode
curNode.next = p

在这里插入图片描述
双链表的删除 这里删除2
一样先1和3连起来,再把2删除
p = curNode.next
curNode.next = p.next
p.next.prior = curNode
del p
在这里插入图片描述

61.链表总结

顺序表(列表/数组与 链表
按元素值查找:都是O(n)
按下标查找:O(1) _O(n) #链表要一个一个查,数组直接按地址找到
在某元素后插入:O(n)_O(1)
删除某元素:O(n)_O(1)

链表在插入和删除的操作上明显快于顺序表
链表的内存可以更灵活的分配,它的内存是散的,可以一直连下一个,不像数组只能开多大的空间,满了只能再开一个数组。
可以用链表重新实现栈和队列
链表这种链式存储的数据结构对树和图的结构有很大的启发性。

62.哈希表

或者叫散列表,python的字典和集合都是
哈希表一个通过哈希函数来计算数据存储位置的数据结构,通常支持如下操作:
insert(key,value):插入键值对(key,value)
get(key):如果存在键为key的键值对,则返回value,否则返回空值
delete(key):删除键为key的键值对

直接寻址表介绍
开辟十个空间,用到4个空间,当找2 时,可以直接根据2的关键字,找到里面的数据。当关键字的全域U比较小时,直接寻址比较有效
在这里插入图片描述
直接寻址缺点:
当域U很大时,需要消耗大量内存,很不实际
如果域U很大而世家出现的key很少,则大量空间背浪费
无法处理关键字不是数字的情况

哈希函数
直接寻址表:key为k的元素放到k位置上
改进直接寻址表:哈希(Hashing)
构建大小为m的寻址表T
key为k的元素放到h(k)位置上
h(k)是一个函数,将其域U映射到表T[0,1,…m-1]

哈希表(Hash Table,又称散列表),是一种线性表的存储结构。哈希表由一个直接寻址表和一个哈希函数组成。哈希函数h(k)将元素关键字k作为自变量,返回元素存储下标。

像这样h(k) = k%7的除法哈希
在这里插入图片描述
但如果21也要存进去,0的位置已经有值怎么办:
这就形成了哈希冲突
由于哈希表的大小是有限的,而要存储的值的总数量是无限的,因此对于任何哈希函数,都会出现两个不同元素映射到同一个位置上的情况,这种情况叫做哈希冲突。
比如h(k) = k%7,h(0) = h(7) = h(14)=…
解决方法:
第一种:开放寻址法
线性探查:i位置被占用,则将位置存在i+1,
如果要找或者删除这个数,则必须也用线性查找的方法找,如果21已经存进去了,找21,则要找i+1的位置。
二次探查同理
在这里插入图片描述
第二种:拉链法
都存在0这个位置,将它存成链表,一个一个链起来。这个比较好用,存的时候先找关键字,找到拉上一个,而线性探查如果插0,7,14都是7的倍数,就要一直找位置给它存,而且如果100个空间查100个元素,插满了就要重新建一个更大的。
链表的空间就可以无线打,插入删除操作也是O(1)。
在这里插入图片描述
常见哈希函数
在这里插入图片描述

62.哈希表实现

用哈希表实现集合
首先了解下知识点:
实现迭代器__iter__ 和 next
__iter __ 和 __next__使对象可以迭代
Python学习:__repr__和__str__区别
__repr__使对象可以打印
python中的map函数
map(str,self)实现类型转换
类里可以嵌套类就像函数可以嵌套函数

#先封装一个链表
class Linklist:
    class Node:
        def __init__(self,item=None):
            self.item = item
            self.next = None
    class LinkListIterator:  #迭代器类
        def __init__(self,node): #首先把传入的head传到node
            self.node = node
        def __next__(self):
            if self.node: #如果有节点
                cur_node = self.node #把节点赋给当前节点
                self.node = cur_node.next #并把节点转到下一个节点
                return cur_node.item #返回当前节点的值
            else:
                raise StopIteration #否则停止迭代
        def __iter__(self): 
            return self #返回自己
    def __init__(self,iterable =None):#初始化,允许传一个列表进来(可迭代对象)
        self.head = None  #刚开始头尾节点都是空
        self.tail = None
        if iterable: #如果是列表进来就extend,模仿python列表的extend
            self.extend(iterable)
    def append(self,obj):  #尾插 #append对象
        s = Linklist.Node(obj) #先创建一个节点
        if not self.head: #如果没有head
            self.head = s  #那么创建的节点就是头节点
            self.tail = s
        else:
            self.tail.next = s #如果有 就尾插
            self.tail = s
    def extend(self,iterable):#extend 列表 插入好几回
        for obj in iterable:
            self.append(obj)
    def find(self,obj): #加了迭代器之后,本身链表支持for循环
        for n in self: #就可以查找对象了
            if n == obj:
                return True
        else:
            return False
    def __iter__(self):  #迭代器,使链表支持for循环
        return self.LinkListIterator(self.head)#返回一个迭代器类
    def __repr__(self):
        return "<<"+",".join(map(str,self))+">>"

看一下效果
在这里插入图片描述
构建哈希表,最终相同取余的值在同一个链表内。
在这里插入图片描述
再次插入1,重复插入,不能找到3。
在这里插入图片描述
实际上内置的集合可以用很多函数,这里只是简单实现。

64.哈希表应用

字典和集合使用哈希表来存储是,字符串也可以看成整数,先看成一串01再从二进制变成十进制就是整数。
在这里插入图片描述
MD5算法,用来加密,现在被清华的一个教授破解了。
哈希函数只能用来加密不能用来解密,因为要保证其安全性,而且加密时间必须要快
在这里插入图片描述
也可以用来比较文件是否一样,如果两个文件的哈希值一样,那么很大概率他们是一样的,还有很小很小一部分可能不一样,因为只要存在哈希,就会存在哈希冲突,世界上文件很多,虽然128位已经很大了,但世界上的文件一定比它还要多,但一样的概率很小很小。
在这里插入图片描述
还有一个是百度云的秒传功能,用户上传一个文件,首先和它的云数据库里的文件比较,如果哈希值一样,就说明这个文件有人传过,就可以不用一个字节一个字节传,直接把他的文件拷到你的文件下就行,速度很快,用户也很开心。
在这里插入图片描述
SHA2算法,现在MD5和SHA1被破解了,所以要是加密的话用SHA2算法来加密,SHA512就说明有512位。
在这里插入图片描述
还有一个是挖比特币,实际上就是解决一个问题,这个问题是给定一个值,计算与哈希值相差小于一定范围的一个值,因为这个哈希不能被反解,所以需要暴力枚举还实现。
在这里插入图片描述
MD5或者SHA要用的话,python里有内置的模块hashlib。

总结

学习了链表和Hash的实现和应用。

文章目录

  • 前言
  • 57.链表介绍
  • 58.链表的创建和遍历
  • 59.链表的插入和删除
  • 60.双链表
  • 61.链表总结
  • 62.哈希表
  • 62.哈希表实现
  • 64.哈希表应用
  • 总结


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

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

相关文章

React配置文件(五) 配置less

代码如下: module.exports { webpack: override( addLessLoader({ lessOptions: { javascriptEnabled: true, modifyVars: { primary-color: #1DA57A }, }, }), adjustStyleLoaders(({ use: [, , postcss] }) > { const postcssOptions postcss.options postcss.options …

SEO初学者如何快速做好 SEO 优化?seo数据查询

昨天给大家介绍了seo的意义和重要性&#xff0c;今天让我们一起看看10个基本的SEO初学者技巧&#xff0c;如何优化网站以增加流量。 1. 研究关键词并使用尾词 关键词在SEO中起着重要的作用。关键字表明了你文章的主要主题&#xff0c;它使人们有可能在网上搜索感兴趣的主题时找…

RK3588平台开发系列讲解(日志篇)RK3588 syslog的使用

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、查看是否启用syslog.conf二、配置启用syslog.conf1、配置busybox2、添加配置文件3、编译buildroot烧录三、验证1、编写测试代码2、查看日志文件3、运行测试程序沉淀、分享、成长,让自己和他人都能有所收获!😄 …

SpringCloudAlibaba入门(2023版)

先知 架构图一览 创建Serve端 新建项目 配置文件 application.yaml server:port: 8080# Eureka配置 eureka:instance:## Eureka实例的名称hostname: localhostAclient:# false表示自己端就是注册中心&#xff0c;职责就是维护服务实例&#xff0c;并不需要去检查服务fetch-r…

Kafka-eagle 安装教程

参考资料&#xff1a; 参考视频 Kafka-eagle官网 解释&#xff1a;Kafka-eagle 后来更名为 EFAK &#xff0c;所以打开官网会显示EFAK 环境准备&#xff1a; 要有本服务器可访问的MySQL服务&#xff0c;远程的请检查是否已经开启了MySQL远程访问&#xff0c;如果没有则需…

1.12 PWM实验

蜂鸣器--------TIM4 CH1/PB6 风扇-----------TIM1 CH1/PE9 马达-----------TIM16 CH1/PF6 一.PWM框图 RCC&#xff1a;使能GPIOB GPIOB&#xff1a;设置复用功能 TIM4:产生方波 二.分析RCC 确定总线&#xff0c;使能GPIOB和TIM4&#xff0c;GPIOE和TIM1,GPIO和TIM16 三.分…

【C++11】右值引用和移动语义

目录 一、左值 vs 右值 二、左值引用vs 右值引用 三、右值引用使用场景和意义 1. 左值引用的使用场景 2. 左值引用的短板 3. 右值引用和移动语义解决上述问题 四、右值引用引用左值的使用场景 五、完美转发 1. 模板中的&& 万能引用 2. std::forward 完美转发…

windows排查问题常用命令

查看JAVA进程占用PID: wmic process where caption"java.exe" get processid,caption,commandline /value查看进程端口信息&#xff1a;netstat -ano 或者 netstat -ano|findstr "8080" 或查看成功建立连接的&#xff1a;netstat -ano | findstr “ESTABLI…

C语言中的字符指针

目录1.字符指针指向一个字符2.字符指针指向一个字符串3.例题1.字符指针指向一个字符 int main() {char ch w;char *pc &ch;return 0; }将一个char类型的变量的地址放到一个char*类型的指针里去&#xff0c;这里的char*ps就是字符指针 在这里的字符指针与之前的整形指针等…

巧用gitbash的scp命令实现跨网段的文件直传

背景 嵌入式开发的工作流一般是这样的&#xff0c;程序员通过Windows电脑登陆Linux服务器&#xff0c;在服务器上编译出二进制文件后&#xff0c;先将文件scp到本地&#xff0c;然后再scp到Linux开发板&#xff0c;如下图所示 这样做需要执行两次scp命令&#xff0c;能否只执…

Golang cgo:如何在Go代码中调用C语言代码?

如何在Go代码中调用C语言代码&#xff1f; Go语言是通过自带的一个叫CGO的工具来支持C语言函数调用&#xff0c;同时我们可以用Go语言导出C动态库接口给其它语言使用。 方式一、直接在 Go 代码中写入 C 代码 检查是否开启cgo工具 首先&#xff0c;要查看是否已经开启cgo工具…

树状数组+例题

一、树状数组的定义 树状数组 或 二元索引树&#xff08;Binary Indexed Tree&#xff09;&#xff0c;现多用于高效计算数列的前缀和&#xff0c; 区间和。它可以以 log(n)log(n)log(n) 的时间得到任意前缀和&#xff0c;也支持在log(n)log(n)log(n)时间内支持动态单点值的修改…

Spring简介与使用

什么是spring spring是一个开源的框架&#xff0c;里面有一系列功能&#xff0c;可以使我们的开发变得更为轻松 简单来说&#xff0c;spring是包含众多工具方法的IoC容器 所谓容器&#xff0c;就是盛放东西的事务&#xff0c;例如我们的ArrayList就是数据存储的容器&#xff…

数据库——排序与分页

目录 排序数据 单列排序 多列排列 分页 分页原理 优点 MySQL 8.0新特性 排序数据 使用 ORDER BY 子句排序ASC&#xff08;ascend&#xff09;: 升序DESC&#xff08;descend&#xff09;:降序ORDER BY 子句在SELECT语句的结尾。 单列排序 SELECT employee_id,last_name…

【Linux】项目自动化构建工具-make与Makefile的简单使用(模拟实现进度条)

目  录1 make与Makefile使用2 模拟实现进度条前言&#xff1a; 会不会编写Makefile&#xff0c;从侧面说明了一个人是否具备完成大型工程的能力。一个工程中的源文件不计其数&#xff0c;按类型、功能、模块分别放在若干个目录中&#xff0c;Makefile定义了一系列的规则来指定…

使用 EMQX Cloud 桥接数据到 GCP Pub/Sub

前不久&#xff0c;Google 宣布其旗下的 GCP IoT Core 即将在 2023 年 8 月 16 日停止提供服务。这意味着大量使用 GCP IoT Core 的用户可能需要将他们的 IoT 应用迁移到其他物联网云服务。除了云服务的迁移&#xff0c;很多用户也在直接利用谷歌云生态&#xff0c;使用 GCP 上…

Docker部署 Harbor

系列文章目录 Docker部署 registry Docker搭建 svn Docker部署 Harbor Docker 部署SQL Server 2017 Docker 安装 MS SqlServer Docker部署 Oracle12c Docker部署Jenkins Docker部署 Harbor系列文章目录前言一、Harbor安装有3种方式二、安装步骤1. 从github官方地址下载安装包2…

C/C++尖括号和双引号包含头文件的区别

前言头文件有两种包含方式&#xff0c;一种是使用尖括号<>&#xff0c;另外一种是通过双引号""包含&#xff0c;例如&#xff1a;#include <iostream> #include "add.h"那么今天就专门来聊一聊这两种方式的区别。1.头文件的含义不同使用尖括号…

多表连接查询

语法&#xff1a; select ... from a join b on a和b的连接条件 join c on a和c的连接条件 join d on a和d的连接条件 一条SQL语句中内连接与外连接可以混合使用 案例&#xff1a;查询每个员工的部门名称以及薪资等级&#xff0c;要求显示员工名、部门名、薪资和薪资等级 SQL&…

核心乐理---和弦基础

和弦命名 什么是和弦 三个或三个以上的三度堆叠成为和弦 三和弦 三和弦指的是有三个音的和弦 七和弦是指七度的和弦&#xff0c;共4个音 其余的和弦与七和弦命名规则相同&#xff0c;跨越几度就是几和弦 九和弦是指跨越九度的和弦&#xff0c;共5个音十一和弦是指跨越十一…