【学习笔记】数据结构和常用算法 - Day3

本文概述了数据结构中的核心部分,包括集合(如哈希集和链表集)的特点、主要操作和时间复杂度,树(二叉树、层次结构)的节点分类及遍历,堆(最大/最小堆)的创建与操作,以及图的基本概念和分类。适合理解数据结构在实际问题中的应用。
摘要由CSDN通过智能技术生成

数据结构 - 集合 set

特点

集合的特点:无序,元素不重复

主要作用

1.检查某元素是否存在
2.检查是否有重复元素(方法:比较原数据集和对应集合的长度)

分类

hashset(常见)、linklistset、treeset …

hashset 添加元素的过程:元素→哈希函数→哈希值→放到哈希表相应位置(1.无元素时,直接存;2.有元素且相等时,更新;3.有元素且不等时,产生哈希冲突)

解决哈希冲突的方法:链表法(和之前的笔记一样)

时间复杂度

访问:不能通过索引访问元素
搜索、插入、删除:
(1)无哈希冲突:O(1)
(2)有哈希冲突:O(K),K是冲突元素的个数

常用操作

# 创建集合
s = set()

# 添加元素
# O(1)
s.add(10)

# 搜索元素
# O(1)
2 in s

# 删除元素
# O(1)
s.remove(2)

# 长度
# O(1)
len(s)

数据结构 - 树 tree

特点

树在工作中一般自己单独使用的机会很少

树中的节点存在父子关系

TreeNode 可以作为队列的元素,但不能作为列表的元素
在这里插入图片描述

树的节点分类

节点:所有点
根节点:最顶端的点
叶子节点:没有子节点的节点

概念:高度、深度、层

在这里插入图片描述

二叉树

1.普通二叉树:每个节点最多2个孩子
2.满二叉树:除了叶子节点,每个节点都有左右2个孩子,且所有叶子节点都在同一层上
3.完全二叉树:从树的根节点,从上到下、从左到右依次填满节点形成的二叉树

若一个树是满二叉树,则一定是完全二叉树;若一个树是完全二叉树,它不一定是满二叉树
在这里插入图片描述

二叉树的遍历

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

数据结构 - 堆 heap

特点

堆属于完全二叉树,分为最大堆和最小堆

分类

最大堆:每个节点的值都 >= 它的孩子节点,该堆的最大值是堆顶元素
最小堆:每个节点的值都 <= 它的孩子节点,该堆的最小值是堆顶元素

时间复杂度

堆化(创建堆):O(N),包括2个步骤:(1)遍历原结构,生成完全二叉树,O(N);(2)交换节点位置,直至符合堆的特点,O(N)

访问:不存在,不能通过索引访问元素

搜索:O(1),一般指搜索堆顶元素

添加:O(logN),每添加一个元素,都需要与父节点比较大小,若不符合堆的特点则父子节点交换位置,一直不符合则一直比较至堆顶元素,直至符合堆的特点

删除:O(logN),一般指删除堆顶元素。删除后,将最末尾的元素移至堆顶,若不符合堆的特点,则该元素需要一直与对应子节点的最大/最小值交换位置,直至符合堆的特点

常用操作

import heapq

class Test:
	def test(self):
		# 创建最小堆
		minheap = []
		heapq.heapify(minheap)

		# 若创建最大堆,需要先将所有元素乘-1,然后创建最小堆,最后将最小堆的元素乘-1

		# 添加元素
		heapq.heappush(minheap,10)

		# 查看堆元素
		print(minheap)
		# 查看堆顶元素
		print(minheap[0])

		# 删除堆顶元素
		heapq.heappop(minheap)

		# 长度
		len(minheap)

		# 遍历
		while len(minheap) != 0:
			print(heapq.heappop(minheap))

数据结构 - 图 graph

概念

每个节点称为顶点,与顶点相连的节点是邻居节点,对应的边是度(degree)

分类

无向图,有向图,权重图
在这里插入图片描述
在这里插入图片描述
有向图的一些概念:
入度:多少边指向该顶点
出度:多少边以这个点为起点指向别的顶点

在这里插入图片描述
权重图:可用于计算最短路径

数据结构的常见面试题

1.比较多种数据结构:除了说定义,还需要比较各自的时间复杂度(访问、搜索、插入、删除)、适用场景(读 / 写)

2.哈希碰撞的解决方法

3.数据结构与实物的联想
队列 - 水管(先入先出)
栈 - 杯子(先入后出)

算法 - 双指针 two pointers

分类

普通双指针:两个指针往同一个方向移动(也有可能不是同方向)

# 找出和为12的2个不同元素
# O(N²)
a = [1,4,5,7,9]  # 此处a是升序数组
for i in range(len(a)):
	for j in range(i,len(a)):
		if i+j == 12:
			print(i,j)

对撞双指针:两个指针面对面移动

# O(N)
a = [1,4,5,7,9]  # 此处a是升序数组
i = 0
j = len(a)
while True:
	if i+j == 12:
		print(i,j)
		break
	elif i+j < 12:
		i += 1
	elif i+j > 12:
		j -= 1

快慢双指针:慢指针+快指针
在这里插入图片描述
检测链表是不是环形链表:设置2个指针,一快一满,同时从起点出发,若两者中途相遇,说明是环形链表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值