文章目录
- 前言
- 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.哈希表应用
- 总结