栈
- 可以比喻为上开口的树立储物柜
- python中借助于列表实现
- 先进后出
- 一种特殊的线性表,仅能在线性表的一段(栈顶)操作
- 常应用于实现递归方面的场景,例如非波那契数列
# python栈实现(必须会代码)
'''
初始化为空栈;
包含 判断为空,入栈,出栈(返回值,不返回值), 栈长功能;
注意添加,取出的操作都是在栈顶进行(列表末尾,运用append, pop函数);
'''
class satck(self):
# 初始化为空
def __init__(self):
self.items = []
# 判断是否为空,输出 True,False
def isEmpty(self):
return self.items == []
# 指定元素入栈
def push(self, item):
self.items.append(item)
# 出栈
def pop(self):
self.items.pop()
# 出栈(有返回值)
def peek(self):
return self.items.pop()
# 返回栈长
def size(self):
return len(self.items)
队列
- 类似于排队,先进先出
- 也是一种线性表
- python中借助于列表实现
- 入队:列表一端实现;出队:python另一端实现
- 使用场景:多线程阻塞队列管理中非常适用
# python队列实现(必须会代码)
'''
初始化为空列表;
包含 清空,出队(pop),入队(insert),队列长 等功能;
注意出入在不同端实现;
'''
class Queue(self):
# 初始化为空
def __init__(self):
self.items = []
# 判断是否为空
def isEmpty(self):
return self.items == []
# 指定元素入队
def enqueue(self, item):
self.items.insert(0, item)
# 出队
def dequeue(self):
self.items.pop()
# 返回队长
def size(self):
return len(self.items)
# python 双端队列实现(必须会代码)
"""
跟普通队列的区别在于可以两端都可以 出队,入队
"""
class Deque(self):
# 初始化为空
def __init__(self):
self.items = []
# 判断为空
def isEmpty(self):
return self.items == []
# 指定元素队头入队
def addFront(self, item):
self.items.insert(0, item)
# 队头出队
def rmEnd(self):
self.items.pop(0)
# 指定元素队尾入队
def addEnd(self, item):
self.items.append(item)
# 队尾出队
self.items.pop()
# 返回队长
def size(self):
return len(self.items)
二叉树
- 每个结点最多有两颗子树,结点的度最大为2
- 左子树和右子树是有顺序的,次序不能颠倒
- 即使某个结点只有一个子树,也要区分左右子树
# python二叉树实现(必须要会)
class BinaryTree:
# 初始化二叉树
def __init__(self, root):
self.key = root
self.left_child = None
self.right_child = None
# 从左插入指定新结点
def insert_left(self, new_node):
# 没有“左孩子”,你做我的左孩子
if self.left_child == None:
self.left_child = BinaryTree(new_node)
# 有“左孩子”,我把我的左孩子给你,你再做我的左孩子
else:
t = BinayTree(new_code)
t.left_child = self.left_child
self.left_child = t
# 从右插入指定新结点(原理同左)
# 没有“右孩子”,你做我的右孩子
def insert_right(self, new_node):
if self.right_child = None:
self.right_child = BinaryTree(new_node)
else:
t = BinaryTree(new_node)
t.right_child = self.right_child
self.right_child = t
# 取左孩子
def get_left_child(self):
return self.left_child
def get_right_child(self):
return self.right_child
# 设置根结点
def set_root_val(self, val):
self.key = val
# 返回根结点
def get_root_val(self):
return self.key
堆
- 堆是一颗完全二叉树
- 堆中的某个节点总不大于或者不小于其父节点的值。
- 大顶堆,小顶堆
# python 小顶堆实现(根结点为最小值),不要求掌握
class PriorityQueueBase:
#抽象基类为堆
class Item:
#轻量级组合来存储堆项目
__slots__ = '_key' , '_value'
def __init__ (self, k, v):
self._key = k
self._value = v
def __lt__ (self, other): #比较大小
return self._key < other._key
def is_empty(self):
return len(self) == 0
def __str__(self):
return str(self._key)
class HeapPriorityQueue(PriorityQueueBase):
def __init__ (self):
self._data = [ ]
def __len__ (self):
return len(self._data)
def is_empty(self):
return len(self) == 0
def add(self, key, value): #在后面加上然后加上
self._data.append(self.Item(key, value))
self._upheap(len(self._data) - 1)
def min(self):
if self.is_empty():
raise ValueError( "Priority queue is empty." )
item = self._data[0]
return (item._key, item._value)
def remove_min(self):
if self.is_empty():
raise ValueError( "Priority queue is empty." )
self._swap(0, len(self._data) - 1)
item = self._data.pop( )
self._downheap(0)
return (item._key, item._value)
def _parent(self, j):
return (j - 1) // 2
def _left(self, j):
return 2 * j + 1
def _right(self, j):
return 2 * j + 2
def _has_left(self, j):
return self._left(j) < len(self._data)
def _has_right(self, j):
return self._right(j) < len(self._data)
def _swap(self, i, j):
self._data[i], self._data[j] = self._data[j], self._data[i]
def _upheap(self, j):#往上交换
parent = self._parent(j)
if j > 0 and self._data[j] < self._data[parent]:
self._swap(j, parent)
self._upheap(parent)
def _downheap(self, j):#往下交换,递归比较三个值
if self._has_left(j):
left = self._left(j)
small_child = left
if self._has_right(j):
right = self._right(j)
if self._data[right] < self._data[left]:
small_child = right
if self._data[small_child] < self._data[j]:
self._swap(j, small_child)
self._downheap(small_child)
if __name__ == "__main__":
heap = HeapPriorityQueue()
heap.add(4, "D")
heap.add(3, "C")
heap.add(1, "A")
heap.add(5, "E")
heap.add(2, "B")
heap.add(7, "G")
heap.add(6, "F")
heap.add(26, "Z")
for item in heap._data:
print(item)
print("min is: ")
print(heap.min())
print()
print("remove min: ")
print(heap.remove_min())
print("Now min is: ")
print(heap.min())
print()
print("remove min: ")
print(heap.remove_min())
print("Now min is: ")
print(heap.min())
print()
heap.add(1, "A")
print("Now min is: ")
print(heap.min())
print()
链表
链表的每个节点包含两个信息:
- 该节点的值
- 指向下一个节点的指针
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
单链表反转
'''
时间复杂度:O(n) 空间复杂度:O(1)
'''
def reverse_ListNode(head):
if head == None or head.next = None:
return head
cur = head
temp = None
newhead = None
while cur:
'''
1+4: 取除头节点后面的链表赋值给自己
1+2:取下头节点(逆序拼接,新链表指针引到原头节点,作为新链表的后面)
1+3:换新head(其实是新链表的后面)
'''
temp = cur.next
cur.next = newhead
newhead = cur
cur = temp
return new_head