目录
可分为线性数据结构和非线性数据结构,如下图所示:
数组(Array)
每次修改数组都得重新给整个数组分配内存,比较麻烦。
链表(Linked List)
每次修改数组都不需要给整个数组重新分配内存,只要在前一个元素中记录后一个元素的地址即可。链表的节点对象有两个属性
class ListNode:
def __init__(self, x):
self.val = x #节点值
self.next = None #后继节点引用
n1 = ListNode(2)
n2 = ListNode(5)
n3 = ListNode(1)
n1.next = n2
n2.next = n3
#即可得到一个链表
栈 (stack)
栈是一种先入后出的抽象数据结构,可以通过数组或者链表实现
stack = [] #通过数组实现栈的功能
stack.append(1) #加入元素
stack.pop() #删除元素
队列(Queue)
队列是一种具有先入先出功能的抽象数据结构,可使用链表实现。
#python通常使用双端队列,导入一个包
from collcetions import deque
queue = deque() #实例化一个双端队列
queue.append(1)
queue.append(2)
queue.leftpop() #1先进来,1先出去
queue.leftpop()
树(Tree)
树是一种非线性数据结构,可根据子节点数量分为[二叉树]和[多叉树],最顶层的节点称为根节点,每个节点包含三个属性。
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
n1 = TreeNode(2)
n2 = TreeNode(3)
n3 = TreeNode(5)
n4 = TreeNode(1)
n5 = TreeNode(8)
n1.left = n2
n1.right = n3
n2.left = n4
n2.right = n5
#即为一个树结构
图
图是一种非线性数据结构,由节点(顶点)和边组成,每条边连接一对顶点,根据边的方向有无,可分为有向图和无向图。
如下图所示,顶点集合:vertices = [1,2,3,4,5]
边集合:edges = [(1,2), (1,3), (1,4), (1,5), (2,4), (3,5), (4,5)]
表示图的方法比较复杂,通常有两种:
-
邻接矩阵
使用数组vertices存储顶点,邻接矩阵edges存储边;edgesi代表i+1,j+1之间是否有边。
vertices = [1,2,3,4,5]
edges = [[0,1,1,1,1],
[1,0,0,1,0],
[1,0,0,0,1],
[1,1,0,0,1],
[1,0,1,1,0]]
-
通过这种方式构建的图一般比较稀疏,如果图之间的连接不稠密,不建议使用,否则太稀疏。
-
邻接表
edges为一个二维容器,第一维表示顶点的索引,第二维表示存储此顶点的边。
edges = [[1,2,3,4],
[0,3],
[0,4],
[0,1,4],
[0,2,3]]
-
邻接表的大小只与节点数量有关,若边数量少,节点多,邻接表会比较浪费内存,因此,邻接表适合存储稀疏图。
堆(Heap)
堆是一种基于完全二叉树的数据结构,可用数组实现,以堆为原理的排序算法称为堆排序,基于堆实现的数据结构为优先队列。堆分为大顶堆和小顶堆。
大顶堆:任意节点的值不大于其父结点的值,小顶堆反之。
完全二叉树:设二叉树深度为k,若二叉树除第k层外其他各层的节点达到了最大个数,且处于第k层的节点都连续集中在最左边,则称之为完全二叉树。
通过使用优先队列的压入和弹出,即可完成堆排序。
from heapq import heappush,heappop
#初始化小顶堆
heap = []
#元素入堆
heappush(heap,1)
heappush(heap,4)
heappush(heap,2)
heappush(heap,6)
heappush(heap,8)
#从小到大出堆
heappop(heap) #->1
heappop(heap) #->2
heappop(heap) #->4
heappop(heap) #->6
heappop(heap) #->8
散列表
类比python中的字典,将输入通过映射函数映射为序号,通过序号查找值。可防止重复