剑指offer笔记8:数据结构总结(P37~72)
目录
数组
数组是占据一块连续内存顺序存储的数据,在Python中,通常用列表来表示数组。可在O(1)的时间对数组进行读写操作,并且python中用列表表示的数组也省去了插入/删除操作时需要移动其他元素的烦恼。另外,可以利用数组下标与元素的关系来实现简单的哈希表。
一维数组的表示
用列表表示的一维数组
>>>arr1 = [1, 2, 3, 4, 5]
>>>arr1
[1, 2, 3, 4, 5]
用numpy表示的一维数组
>>>import numpy as np
>>>arr2 = np.asarray(arr1)
>>>arr2
array([1, 2, 3, 4, 5])
可以看出用列表表示的数组和numpy表示的数组的差别
>>>print(arr1)
[1, 2, 3, 4, 5]
>>>print(arr2)
[1 2 3 4 5]
像leetCode这种基本是不让用numpy的,所以下面就不用numpy举例了,关于numpy的用法请参考NumPy教程 | 菜鸟教程
二维数组的表示
用列表表示的二维数组,下面是一个两行三列的数组:
>>>arr3 = [[1, 2, 3], [4, 5, 6]]
>>>arr3
[[1, 2, 3], [4, 5, 6]]
数组的基本操作
这里举例一些关于数组的基本操作,基本上就是python中列表的基本操作,更多请参考Python3 列表 | 菜鸟教程
下面都用一维数组举例了,二维数组操作类似就不写了
数组大小
一维数组
>>>len(arr1)
5
二维数组行数
>>>len(arr3)
2
二维数组列数
>>>len(arr3[0])
3
数组读写
>>>arr1[2]
3
>>>arr1[2] = 0
>>>arr1
[1, 2, 0, 4, 5]
数组中最后一个元素
>>>arr1[-1]
5
数组插入
>>>arr1.insert(2, 9)
>>>arr1
[1, 2, 9, 0, 4, 5]
数组尾部插入
>>>arr1.append(8)
>>>arr1
[1, 2, 9, 0, 4, 5, 8]
数组删除
>>>arr1
[1, 2, 9, 0, 4, 5, 8]
>>>del arr1[2]
>>>arr1
[1, 2, 0, 4, 5, 8]
取数组最后一个元素并删除
>>>arr1
[1, 2, 0, 4, 5, 8]
>>>a = arr1.pop()
>>>a
8
>>>arr1
[1, 2, 0, 4, 5]
字符串
Python中的字符串没有结尾标志,操作也不像c语言那样复杂,这里有一个完整的python3字符串教程Python3 字符串 | 菜鸟教程,我就不多写了。
链表
链表是用指针将很多单个节点链接成的链状结构。在Python中,需要构造一个链表的节点类型。
单链表节点类型
单链表的节点类型只需要两部分,一个是节点值,另一个是指向下一节点的指针。
class ListNode:
# 链表节点定义
def __init__(self, x):
self.val = x
self.next = None
创建一个单链表
这里给出的是将列表初始化为一个单链表的代码,返回单链表的头指针。
class LinkList(object):
# 链表初始化
def __init__(self):
self.head = 0
# 将列表初始化为链表
def initlist(self, items):
self.head = ListNode(items[0])
# 先定义头指针,即其值为items中的第一个元素
p = self.head
# 设置一个移动指针,用以在单链表中顺序添加items中接下来的元素
for item in items[1:]:
# 遍历items中剩下的元素
node = ListNode(item)
# 为该元素创建一个新的listNode类型
p.next = node
# 移动p指针
p = p.next
return self.head
二叉树
二叉树中,每个节点最多有两个子节点。在Python中,需要构造一个二叉树的节点类型。
二叉树节点类型
二叉树的节点类型中包含三部分,节点值和左右子节点的指针。
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
二叉树的基本操作
二叉树的内容有很多,我打算刷完整本书在对二叉树做一个系统的总结。这里就只给出简要概述。
二叉树的遍历
- 先序遍历:根→左→右
- 中序遍历:左→根→右
- 后序遍历:左→右→根
- 宽度优先遍历(广度优先遍历):从上到下从左到右
构建二叉树
这里给出之前的笔记,里面有根据中序遍历和先序遍历构建二叉树和根据中序遍历和后序遍历构建二叉树的代码。
剑指offer笔记4:重建二叉树(Python)
二叉树的变形
平衡二叉树、二叉搜索树、二叉排序树、哈夫曼树、大小顶堆
其他树形结构
B树、B+树
栈和队列
栈
栈的特点是后进先出,像放羽毛球的筒子一样。在Python中,使用列表来模仿栈。压栈操作就是在列表末尾插入,弹栈就是删除列表末尾元素(我也看过有在列表头操作的,但是个人感觉在列表末尾操作更简单)。
栈的基本操作
class Stack:
# 栈的定义
def __init__(self):
self.items = []
# 压栈,相当于在列表末尾插入
def push(self, item):
self.items.append(item)
# 弹栈,与列表的pop()方法相同
def pop(self):
return self.items.pop()
# 判断栈是否为空
def is_empty(self):
return self.size() == 0
# 栈的大小
def size(self):
return len(self.items)
# 返回栈顶元素,即列表中最后一个元素
def peak(self):
return self.items[-1]
队列
队列的特点是先进先出,在Python中,用列表来模拟队列的操作。入队就是在列表后插入,出队就是删除列表头。
队列的基本操作
class Queue:
# 队列的定义
def __init__(self):
self.items = []
# 入队,相当于在列表末尾插入
def en_que(self, item):
self.items.append(item)
# 出队,即删除列表中第一个元素并返回该元素
def un_que(self):
elem = self.items[0]
self.items = self.items[1:]
return elem
# 判断队列是否为空
def is_empty(self):
return self.size() == 0
# 队列的大小
def size(self):
return len(self.items)
# 返回队尾元素,即列表中最后一个元素
def tail(self):
return self.items[-1]
数据结构知识导图
这里是根据本科教科书(下图)总结的