Format python codes with black. (#453)
This commit is contained in:
parent
1c8b7ef559
commit
5ddcb60825
@ -6,18 +6,20 @@ Author: Krahets (krahets@163.com)
|
|||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
def random_access(nums: list[int]) -> int:
|
def random_access(nums: list[int]) -> int:
|
||||||
""" 随机访问元素 """
|
"""随机访问元素"""
|
||||||
# 在区间 [0, len(nums)-1] 中随机抽取一个数字
|
# 在区间 [0, len(nums)-1] 中随机抽取一个数字
|
||||||
random_index = random.randint(0, len(nums) - 1)
|
random_index = random.randint(0, len(nums) - 1)
|
||||||
# 获取并返回随机元素
|
# 获取并返回随机元素
|
||||||
random_num = nums[random_index]
|
random_num = nums[random_index]
|
||||||
return random_num
|
return random_num
|
||||||
|
|
||||||
|
|
||||||
# 请注意,Python 的 list 是动态数组,可以直接扩展
|
# 请注意,Python 的 list 是动态数组,可以直接扩展
|
||||||
# 为了方便学习,本函数将 list 看作是长度不可变的数组
|
# 为了方便学习,本函数将 list 看作是长度不可变的数组
|
||||||
def extend(nums: list[int], enlarge: int) -> list[int]:
|
def extend(nums: list[int], enlarge: int) -> list[int]:
|
||||||
""" 扩展数组长度 """
|
"""扩展数组长度"""
|
||||||
# 初始化一个扩展长度后的数组
|
# 初始化一个扩展长度后的数组
|
||||||
res = [0] * (len(nums) + enlarge)
|
res = [0] * (len(nums) + enlarge)
|
||||||
# 将原数组中的所有元素复制到新数组
|
# 将原数组中的所有元素复制到新数组
|
||||||
@ -26,22 +28,25 @@ def extend(nums: list[int], enlarge: int) -> list[int]:
|
|||||||
# 返回扩展后的新数组
|
# 返回扩展后的新数组
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def insert(nums: list[int], num: int, index: int) -> None:
|
def insert(nums: list[int], num: int, index: int) -> None:
|
||||||
""" 在数组的索引 index 处插入元素 num """
|
"""在数组的索引 index 处插入元素 num"""
|
||||||
# 把索引 index 以及之后的所有元素向后移动一位
|
# 把索引 index 以及之后的所有元素向后移动一位
|
||||||
for i in range(len(nums) - 1, index, -1):
|
for i in range(len(nums) - 1, index, -1):
|
||||||
nums[i] = nums[i - 1]
|
nums[i] = nums[i - 1]
|
||||||
# 将 num 赋给 index 处元素
|
# 将 num 赋给 index 处元素
|
||||||
nums[index] = num
|
nums[index] = num
|
||||||
|
|
||||||
|
|
||||||
def remove(nums: list[int], index: int) -> None:
|
def remove(nums: list[int], index: int) -> None:
|
||||||
""" 删除索引 index 处元素 """
|
"""删除索引 index 处元素"""
|
||||||
# 把索引 index 之后的所有元素向前移动一位
|
# 把索引 index 之后的所有元素向前移动一位
|
||||||
for i in range(index, len(nums) - 1):
|
for i in range(index, len(nums) - 1):
|
||||||
nums[i] = nums[i + 1]
|
nums[i] = nums[i + 1]
|
||||||
|
|
||||||
|
|
||||||
def traverse(nums: list[int]) -> None:
|
def traverse(nums: list[int]) -> None:
|
||||||
""" 遍历数组 """
|
"""遍历数组"""
|
||||||
count = 0
|
count = 0
|
||||||
# 通过索引遍历数组
|
# 通过索引遍历数组
|
||||||
for i in range(len(nums)):
|
for i in range(len(nums)):
|
||||||
@ -50,40 +55,42 @@ def traverse(nums: list[int]) -> None:
|
|||||||
for num in nums:
|
for num in nums:
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
|
|
||||||
def find(nums: list[int], target: int) -> int:
|
def find(nums: list[int], target: int) -> int:
|
||||||
""" 在数组中查找指定元素 """
|
"""在数组中查找指定元素"""
|
||||||
for i in range(len(nums)):
|
for i in range(len(nums)):
|
||||||
if nums[i] == target:
|
if nums[i] == target:
|
||||||
return i
|
return i
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化数组 """
|
# 初始化数组
|
||||||
arr: list[int] = [0] * 5
|
arr: list[int] = [0] * 5
|
||||||
print("数组 arr =", arr)
|
print("数组 arr =", arr)
|
||||||
nums: list[int] = [1, 3, 2, 5, 4]
|
nums: list[int] = [1, 3, 2, 5, 4]
|
||||||
print("数组 nums =", nums)
|
print("数组 nums =", nums)
|
||||||
|
|
||||||
""" 随机访问 """
|
# 随机访问
|
||||||
random_num: int = random_access(nums)
|
random_num: int = random_access(nums)
|
||||||
print("在 nums 中获取随机元素", random_num)
|
print("在 nums 中获取随机元素", random_num)
|
||||||
|
|
||||||
""" 长度扩展 """
|
# 长度扩展
|
||||||
nums: list[int] = extend(nums, 3)
|
nums: list[int] = extend(nums, 3)
|
||||||
print("将数组长度扩展至 8 ,得到 nums =", nums)
|
print("将数组长度扩展至 8 ,得到 nums =", nums)
|
||||||
|
|
||||||
""" 插入元素 """
|
# 插入元素
|
||||||
insert(nums, 6, 3)
|
insert(nums, 6, 3)
|
||||||
print("在索引 3 处插入数字 6 ,得到 nums =", nums)
|
print("在索引 3 处插入数字 6 ,得到 nums =", nums)
|
||||||
|
|
||||||
""" 删除元素 """
|
# 删除元素
|
||||||
remove(nums, 2)
|
remove(nums, 2)
|
||||||
print("删除索引 2 处的元素,得到 nums =", nums)
|
print("删除索引 2 处的元素,得到 nums =", nums)
|
||||||
|
|
||||||
""" 遍历数组 """
|
# 遍历数组
|
||||||
traverse(nums)
|
traverse(nums)
|
||||||
|
|
||||||
""" 查找元素 """
|
# 查找元素
|
||||||
index: int = find(nums, 3)
|
index: int = find(nums, 3)
|
||||||
print("在 nums 中查找元素 3 ,得到索引 =", index)
|
print("在 nums 中查找元素 3 ,得到索引 =", index)
|
||||||
|
@ -5,17 +5,20 @@ Author: Krahets (krahets@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
def insert(n0: ListNode, P: ListNode) -> None:
|
def insert(n0: ListNode, P: ListNode) -> None:
|
||||||
""" 在链表的节点 n0 之后插入节点 P """
|
"""在链表的节点 n0 之后插入节点 P"""
|
||||||
n1 = n0.next
|
n1 = n0.next
|
||||||
P.next = n1
|
P.next = n1
|
||||||
n0.next = P
|
n0.next = P
|
||||||
|
|
||||||
|
|
||||||
def remove(n0: ListNode) -> None:
|
def remove(n0: ListNode) -> None:
|
||||||
""" 删除链表的节点 n0 之后的首个节点 """
|
"""删除链表的节点 n0 之后的首个节点"""
|
||||||
if not n0.next:
|
if not n0.next:
|
||||||
return
|
return
|
||||||
# n0 -> P -> n1
|
# n0 -> P -> n1
|
||||||
@ -23,16 +26,18 @@ def remove(n0: ListNode) -> None:
|
|||||||
n1 = P.next
|
n1 = P.next
|
||||||
n0.next = n1
|
n0.next = n1
|
||||||
|
|
||||||
|
|
||||||
def access(head: ListNode, index: int) -> ListNode | None:
|
def access(head: ListNode, index: int) -> ListNode | None:
|
||||||
""" 访问链表中索引为 index 的节点 """
|
"""访问链表中索引为 index 的节点"""
|
||||||
for _ in range(index):
|
for _ in range(index):
|
||||||
if not head:
|
if not head:
|
||||||
return None
|
return None
|
||||||
head = head.next
|
head = head.next
|
||||||
return head
|
return head
|
||||||
|
|
||||||
|
|
||||||
def find(head: ListNode, target: int) -> int:
|
def find(head: ListNode, target: int) -> int:
|
||||||
""" 在链表中查找值为 target 的首个节点 """
|
"""在链表中查找值为 target 的首个节点"""
|
||||||
index = 0
|
index = 0
|
||||||
while head:
|
while head:
|
||||||
if head.val == target:
|
if head.val == target:
|
||||||
@ -44,8 +49,8 @@ def find(head: ListNode, target: int) -> int:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化链表 """
|
# 初始化链表
|
||||||
# 初始化各个节点
|
# 初始化各个节点
|
||||||
n0 = ListNode(1)
|
n0 = ListNode(1)
|
||||||
n1 = ListNode(3)
|
n1 = ListNode(3)
|
||||||
n2 = ListNode(2)
|
n2 = ListNode(2)
|
||||||
@ -59,20 +64,20 @@ if __name__ == "__main__":
|
|||||||
print("初始化的链表为")
|
print("初始化的链表为")
|
||||||
print_linked_list(n0)
|
print_linked_list(n0)
|
||||||
|
|
||||||
""" 插入节点 """
|
# 插入节点
|
||||||
insert(n0, ListNode(0))
|
insert(n0, ListNode(0))
|
||||||
print("插入节点后的链表为")
|
print("插入节点后的链表为")
|
||||||
print_linked_list(n0)
|
print_linked_list(n0)
|
||||||
|
|
||||||
""" 删除节点 """
|
# 删除节点
|
||||||
remove(n0)
|
remove(n0)
|
||||||
print("删除节点后的链表为")
|
print("删除节点后的链表为")
|
||||||
print_linked_list(n0)
|
print_linked_list(n0)
|
||||||
|
|
||||||
""" 访问节点 """
|
# 访问节点
|
||||||
node: ListNode = access(n0, 3)
|
node: ListNode = access(n0, 3)
|
||||||
print("链表中索引 3 处的节点的值 = {}".format(node.val))
|
print("链表中索引 3 处的节点的值 = {}".format(node.val))
|
||||||
|
|
||||||
""" 查找节点 """
|
# 查找节点
|
||||||
index: int = find(n0, 2)
|
index: int = find(n0, 2)
|
||||||
print("链表中值为 2 的节点的索引 = {}".format(index))
|
print("链表中值为 2 的节点的索引 = {}".format(index))
|
||||||
|
@ -6,23 +6,23 @@ Author: Krahets (krahets@163.com)
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化列表 """
|
# 初始化列表
|
||||||
arr: list[int] = [1, 3, 2, 5, 4]
|
arr: list[int] = [1, 3, 2, 5, 4]
|
||||||
print("列表 arr =", arr)
|
print("列表 arr =", arr)
|
||||||
|
|
||||||
""" 访问元素 """
|
# 访问元素
|
||||||
num: int = arr[1]
|
num: int = arr[1]
|
||||||
print("访问索引 1 处的元素,得到 num =", num)
|
print("访问索引 1 处的元素,得到 num =", num)
|
||||||
|
|
||||||
""" 更新元素 """
|
# 更新元素
|
||||||
arr[1] = 0
|
arr[1] = 0
|
||||||
print("将索引 1 处的元素更新为 0 ,得到 arr =", arr)
|
print("将索引 1 处的元素更新为 0 ,得到 arr =", arr)
|
||||||
|
|
||||||
""" 清空列表 """
|
# 清空列表
|
||||||
arr.clear()
|
arr.clear()
|
||||||
print("清空列表后 arr =", arr)
|
print("清空列表后 arr =", arr)
|
||||||
|
|
||||||
""" 尾部添加元素 """
|
# 尾部添加元素
|
||||||
arr.append(1)
|
arr.append(1)
|
||||||
arr.append(3)
|
arr.append(3)
|
||||||
arr.append(2)
|
arr.append(2)
|
||||||
@ -30,29 +30,29 @@ if __name__ == "__main__":
|
|||||||
arr.append(4)
|
arr.append(4)
|
||||||
print("添加元素后 arr =", arr)
|
print("添加元素后 arr =", arr)
|
||||||
|
|
||||||
""" 中间插入元素 """
|
# 中间插入元素
|
||||||
arr.insert(3, 6)
|
arr.insert(3, 6)
|
||||||
print("在索引 3 处插入数字 6 ,得到 arr =", arr)
|
print("在索引 3 处插入数字 6 ,得到 arr =", arr)
|
||||||
|
|
||||||
""" 删除元素 """
|
# 删除元素
|
||||||
arr.pop(3)
|
arr.pop(3)
|
||||||
print("删除索引 3 处的元素,得到 arr =", arr)
|
print("删除索引 3 处的元素,得到 arr =", arr)
|
||||||
|
|
||||||
""" 通过索引遍历列表 """
|
# 通过索引遍历列表
|
||||||
count: int = 0
|
count: int = 0
|
||||||
for i in range(len(arr)):
|
for i in range(len(arr)):
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
""" 直接遍历列表元素 """
|
# 直接遍历列表元素
|
||||||
count: int = 0
|
count: int = 0
|
||||||
for n in arr:
|
for n in arr:
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
""" 拼接两个列表 """
|
# 拼接两个列表
|
||||||
arr1: list[int] = [6, 8, 7, 10, 9]
|
arr1: list[int] = [6, 8, 7, 10, 9]
|
||||||
arr += arr1
|
arr += arr1
|
||||||
print("将列表 arr1 拼接到 arr 之后,得到 arr =", arr)
|
print("将列表 arr1 拼接到 arr 之后,得到 arr =", arr)
|
||||||
|
|
||||||
""" 排序列表 """
|
# 排序列表
|
||||||
arr.sort()
|
arr.sort()
|
||||||
print("排序列表后 arr =", arr)
|
print("排序列表后 arr =", arr)
|
||||||
|
@ -4,36 +4,38 @@ Created Time: 2022-11-25
|
|||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class MyList:
|
class MyList:
|
||||||
""" 列表类简易实现 """
|
"""列表类简易实现"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.__capacity: int = 10 # 列表容量
|
self.__capacity: int = 10 # 列表容量
|
||||||
self.__nums: my_list[int] = [0] * self.__capacity # 数组(存储列表元素)
|
self.__nums: my_list[int] = [0] * self.__capacity # 数组(存储列表元素)
|
||||||
self.__size: int = 0 # 列表长度(即当前元素数量)
|
self.__size: int = 0 # 列表长度(即当前元素数量)
|
||||||
self.__extend_ratio: int = 2 # 每次列表扩容的倍数
|
self.__extend_ratio: int = 2 # 每次列表扩容的倍数
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取列表长度(即当前元素数量) """
|
"""获取列表长度(即当前元素数量)"""
|
||||||
return self.__size
|
return self.__size
|
||||||
|
|
||||||
def capacity(self) -> int:
|
def capacity(self) -> int:
|
||||||
""" 获取列表容量 """
|
"""获取列表容量"""
|
||||||
return self.__capacity
|
return self.__capacity
|
||||||
|
|
||||||
def get(self, index: int) -> int:
|
def get(self, index: int) -> int:
|
||||||
""" 访问元素 """
|
"""访问元素"""
|
||||||
# 索引如果越界则抛出异常,下同
|
# 索引如果越界则抛出异常,下同
|
||||||
assert index >= 0 and index < self.__size, "索引越界"
|
assert index >= 0 and index < self.__size, "索引越界"
|
||||||
return self.__nums[index]
|
return self.__nums[index]
|
||||||
|
|
||||||
def set(self, num: int, index: int) -> None:
|
def set(self, num: int, index: int) -> None:
|
||||||
""" 更新元素 """
|
"""更新元素"""
|
||||||
assert index >= 0 and index < self.__size, "索引越界"
|
assert index >= 0 and index < self.__size, "索引越界"
|
||||||
self.__nums[index] = num
|
self.__nums[index] = num
|
||||||
|
|
||||||
def add(self, num: int) -> None:
|
def add(self, num: int) -> None:
|
||||||
""" 尾部添加元素 """
|
"""尾部添加元素"""
|
||||||
# 元素数量超出容量时,触发扩容机制
|
# 元素数量超出容量时,触发扩容机制
|
||||||
if self.size() == self.capacity():
|
if self.size() == self.capacity():
|
||||||
self.extend_capacity()
|
self.extend_capacity()
|
||||||
@ -41,7 +43,7 @@ class MyList:
|
|||||||
self.__size += 1
|
self.__size += 1
|
||||||
|
|
||||||
def insert(self, num: int, index: int) -> None:
|
def insert(self, num: int, index: int) -> None:
|
||||||
""" 中间插入元素 """
|
"""中间插入元素"""
|
||||||
assert index >= 0 and index < self.__size, "索引越界"
|
assert index >= 0 and index < self.__size, "索引越界"
|
||||||
# 元素数量超出容量时,触发扩容机制
|
# 元素数量超出容量时,触发扩容机制
|
||||||
if self.__size == self.capacity():
|
if self.__size == self.capacity():
|
||||||
@ -54,7 +56,7 @@ class MyList:
|
|||||||
self.__size += 1
|
self.__size += 1
|
||||||
|
|
||||||
def remove(self, index: int) -> int:
|
def remove(self, index: int) -> int:
|
||||||
""" 删除元素 """
|
"""删除元素"""
|
||||||
assert index >= 0 and index < self.__size, "索引越界"
|
assert index >= 0 and index < self.__size, "索引越界"
|
||||||
num = self.__nums[index]
|
num = self.__nums[index]
|
||||||
# 索引 i 之后的元素都向前移动一位
|
# 索引 i 之后的元素都向前移动一位
|
||||||
@ -66,49 +68,51 @@ class MyList:
|
|||||||
return num
|
return num
|
||||||
|
|
||||||
def extend_capacity(self) -> None:
|
def extend_capacity(self) -> None:
|
||||||
""" 列表扩容 """
|
"""列表扩容"""
|
||||||
# 新建一个长度为 self.__size 的数组,并将原数组拷贝到新数组
|
# 新建一个长度为 self.__size 的数组,并将原数组拷贝到新数组
|
||||||
self.__nums = self.__nums + [0] * self.capacity() * (self.__extend_ratio - 1)
|
self.__nums = self.__nums + [0] * self.capacity() * (self.__extend_ratio - 1)
|
||||||
# 更新列表容量
|
# 更新列表容量
|
||||||
self.__capacity = len(self.__nums)
|
self.__capacity = len(self.__nums)
|
||||||
|
|
||||||
def to_array(self) -> list[int]:
|
def to_array(self) -> list[int]:
|
||||||
""" 返回有效长度的列表 """
|
"""返回有效长度的列表"""
|
||||||
return self.__nums[:self.__size]
|
return self.__nums[: self.__size]
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化列表 """
|
# 初始化列表
|
||||||
my_list = MyList()
|
my_list = MyList()
|
||||||
""" 尾部添加元素 """
|
# 尾部添加元素
|
||||||
my_list.add(1)
|
my_list.add(1)
|
||||||
my_list.add(3)
|
my_list.add(3)
|
||||||
my_list.add(2)
|
my_list.add(2)
|
||||||
my_list.add(5)
|
my_list.add(5)
|
||||||
my_list.add(4)
|
my_list.add(4)
|
||||||
print("列表 my_list = {} ,容量 = {} ,长度 = {}"
|
print(
|
||||||
.format(my_list.to_array(), my_list.capacity(), my_list.size()))
|
f"列表 my_list = {my_list.to_array()} ,容量 = {my_list.capacity()} ,长度 = {my_list.size()}"
|
||||||
|
)
|
||||||
|
|
||||||
""" 中间插入元素 """
|
# 中间插入元素
|
||||||
my_list.insert(6, index=3)
|
my_list.insert(6, index=3)
|
||||||
print("在索引 3 处插入数字 6 ,得到 my_list =", my_list.to_array())
|
print("在索引 3 处插入数字 6 ,得到 my_list =", my_list.to_array())
|
||||||
|
|
||||||
""" 删除元素 """
|
# 删除元素
|
||||||
my_list.remove(3)
|
my_list.remove(3)
|
||||||
print("删除索引 3 处的元素,得到 my_list =", my_list.to_array())
|
print("删除索引 3 处的元素,得到 my_list =", my_list.to_array())
|
||||||
|
|
||||||
""" 访问元素 """
|
# 访问元素
|
||||||
num = my_list.get(1)
|
num = my_list.get(1)
|
||||||
print("访问索引 1 处的元素,得到 num =", num)
|
print("访问索引 1 处的元素,得到 num =", num)
|
||||||
|
|
||||||
""" 更新元素 """
|
# 更新元素
|
||||||
my_list.set(0, 1)
|
my_list.set(0, 1)
|
||||||
print("将索引 1 处的元素更新为 0 ,得到 my_list =", my_list.to_array())
|
print("将索引 1 处的元素更新为 0 ,得到 my_list =", my_list.to_array())
|
||||||
|
|
||||||
""" 测试扩容机制 """
|
# 测试扩容机制
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
# 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制
|
# 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制
|
||||||
my_list.add(i)
|
my_list.add(i)
|
||||||
print("扩容后的列表 my_list = {} ,容量 = {} ,长度 = {}"
|
print(
|
||||||
.format(my_list.to_array(), my_list.capacity(), my_list.size()))
|
"扩容后的列表 {my_list.to_array()} ,容量 = {my_list.capacity()} ,长度 = {my_list.size()}"
|
||||||
|
)
|
||||||
|
@ -4,8 +4,9 @@ Created Time: 2022-11-25
|
|||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def two_sum_brute_force(nums: list[int], target: int) -> list[int]:
|
def two_sum_brute_force(nums: list[int], target: int) -> list[int]:
|
||||||
""" 方法一:暴力枚举 """
|
"""方法一:暴力枚举"""
|
||||||
# 两层循环,时间复杂度 O(n^2)
|
# 两层循环,时间复杂度 O(n^2)
|
||||||
for i in range(len(nums) - 1):
|
for i in range(len(nums) - 1):
|
||||||
for j in range(i + 1, len(nums)):
|
for j in range(i + 1, len(nums)):
|
||||||
@ -13,8 +14,9 @@ def two_sum_brute_force(nums: list[int], target: int) -> list[int]:
|
|||||||
return [i, j]
|
return [i, j]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def two_sum_hash_table(nums: list[int], target: int) -> list[int]:
|
def two_sum_hash_table(nums: list[int], target: int) -> list[int]:
|
||||||
""" 方法二:辅助哈希表 """
|
"""方法二:辅助哈希表"""
|
||||||
# 辅助哈希表,空间复杂度 O(n)
|
# 辅助哈希表,空间复杂度 O(n)
|
||||||
dic = {}
|
dic = {}
|
||||||
# 单层循环,时间复杂度 O(n)
|
# 单层循环,时间复杂度 O(n)
|
||||||
@ -26,11 +28,11 @@ def two_sum_hash_table(nums: list[int], target: int) -> list[int]:
|
|||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
# ======= Test Case =======
|
# ======= Test Case =======
|
||||||
nums = [2,7,11,15]
|
nums = [2, 7, 11, 15]
|
||||||
target = 9
|
target = 9
|
||||||
|
|
||||||
# ====== Driver Code ======
|
# ====== Driver Code ======
|
||||||
# 方法一
|
# 方法一
|
||||||
res: list[int] = two_sum_brute_force(nums, target)
|
res: list[int] = two_sum_brute_force(nums, target)
|
||||||
|
@ -5,16 +5,19 @@ Author: Krahets (krahets@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
def function() -> int:
|
def function() -> int:
|
||||||
""" 函数 """
|
"""函数"""
|
||||||
# do something
|
# do something
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def constant(n: int) -> None:
|
def constant(n: int) -> None:
|
||||||
""" 常数阶 """
|
"""常数阶"""
|
||||||
# 常量、变量、对象占用 O(1) 空间
|
# 常量、变量、对象占用 O(1) 空间
|
||||||
a: int = 0
|
a: int = 0
|
||||||
nums: list[int] = [0] * 10000
|
nums: list[int] = [0] * 10000
|
||||||
@ -26,8 +29,9 @@ def constant(n: int) -> None:
|
|||||||
for _ in range(n):
|
for _ in range(n):
|
||||||
function()
|
function()
|
||||||
|
|
||||||
|
|
||||||
def linear(n: int) -> None:
|
def linear(n: int) -> None:
|
||||||
""" 线性阶 """
|
"""线性阶"""
|
||||||
# 长度为 n 的列表占用 O(n) 空间
|
# 长度为 n 的列表占用 O(n) 空间
|
||||||
nums: list[int] = [0] * n
|
nums: list[int] = [0] * n
|
||||||
# 长度为 n 的哈希表占用 O(n) 空间
|
# 长度为 n 的哈希表占用 O(n) 空间
|
||||||
@ -35,27 +39,34 @@ def linear(n: int) -> None:
|
|||||||
for i in range(n):
|
for i in range(n):
|
||||||
mapp[i] = str(i)
|
mapp[i] = str(i)
|
||||||
|
|
||||||
|
|
||||||
def linear_recur(n: int) -> None:
|
def linear_recur(n: int) -> None:
|
||||||
""" 线性阶(递归实现) """
|
"""线性阶(递归实现)"""
|
||||||
print("递归 n =", n)
|
print("递归 n =", n)
|
||||||
if n == 1: return
|
if n == 1:
|
||||||
|
return
|
||||||
linear_recur(n - 1)
|
linear_recur(n - 1)
|
||||||
|
|
||||||
|
|
||||||
def quadratic(n: int) -> None:
|
def quadratic(n: int) -> None:
|
||||||
""" 平方阶 """
|
"""平方阶"""
|
||||||
# 二维列表占用 O(n^2) 空间
|
# 二维列表占用 O(n^2) 空间
|
||||||
num_matrix: list[list[int]] = [[0] * n for _ in range(n)]
|
num_matrix: list[list[int]] = [[0] * n for _ in range(n)]
|
||||||
|
|
||||||
|
|
||||||
def quadratic_recur(n: int) -> int:
|
def quadratic_recur(n: int) -> int:
|
||||||
""" 平方阶(递归实现) """
|
"""平方阶(递归实现)"""
|
||||||
if n <= 0: return 0
|
if n <= 0:
|
||||||
|
return 0
|
||||||
# 数组 nums 长度为 n, n-1, ..., 2, 1
|
# 数组 nums 长度为 n, n-1, ..., 2, 1
|
||||||
nums: list[int] = [0] * n
|
nums: list[int] = [0] * n
|
||||||
return quadratic_recur(n - 1)
|
return quadratic_recur(n - 1)
|
||||||
|
|
||||||
|
|
||||||
def build_tree(n: int) -> TreeNode | None:
|
def build_tree(n: int) -> TreeNode | None:
|
||||||
""" 指数阶(建立满二叉树) """
|
"""指数阶(建立满二叉树)"""
|
||||||
if n == 0: return None
|
if n == 0:
|
||||||
|
return None
|
||||||
root = TreeNode(0)
|
root = TreeNode(0)
|
||||||
root.left = build_tree(n - 1)
|
root.left = build_tree(n - 1)
|
||||||
root.right = build_tree(n - 1)
|
root.right = build_tree(n - 1)
|
||||||
|
@ -4,31 +4,35 @@ Created Time: 2022-11-25
|
|||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def constant(n: int) -> int:
|
def constant(n: int) -> int:
|
||||||
""" 常数阶 """
|
"""常数阶"""
|
||||||
count: int = 0
|
count: int = 0
|
||||||
size: int = 100000
|
size: int = 100000
|
||||||
for _ in range(size):
|
for _ in range(size):
|
||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
def linear(n: int) -> int:
|
def linear(n: int) -> int:
|
||||||
""" 线性阶 """
|
"""线性阶"""
|
||||||
count: int = 0
|
count: int = 0
|
||||||
for _ in range(n):
|
for _ in range(n):
|
||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
def array_traversal(nums: list[int]) -> int:
|
def array_traversal(nums: list[int]) -> int:
|
||||||
""" 线性阶(遍历数组)"""
|
"""线性阶(遍历数组)"""
|
||||||
count: int = 0
|
count: int = 0
|
||||||
# 循环次数与数组长度成正比
|
# 循环次数与数组长度成正比
|
||||||
for num in nums:
|
for num in nums:
|
||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
def quadratic(n: int) -> int:
|
def quadratic(n: int) -> int:
|
||||||
""" 平方阶 """
|
"""平方阶"""
|
||||||
count: int = 0
|
count: int = 0
|
||||||
# 循环次数与数组长度成平方关系
|
# 循环次数与数组长度成平方关系
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
@ -36,8 +40,9 @@ def quadratic(n: int) -> int:
|
|||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
def bubble_sort(nums: list[int]) -> int:
|
def bubble_sort(nums: list[int]) -> int:
|
||||||
""" 平方阶(冒泡排序)"""
|
"""平方阶(冒泡排序)"""
|
||||||
count: int = 0 # 计数器
|
count: int = 0 # 计数器
|
||||||
# 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
# 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||||
for i in range(len(nums) - 1, 0, -1):
|
for i in range(len(nums) - 1, 0, -1):
|
||||||
@ -51,8 +56,9 @@ def bubble_sort(nums: list[int]) -> int:
|
|||||||
count += 3 # 元素交换包含 3 个单元操作
|
count += 3 # 元素交换包含 3 个单元操作
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
def exponential(n: int) -> int:
|
def exponential(n: int) -> int:
|
||||||
""" 指数阶(循环实现)"""
|
"""指数阶(循环实现)"""
|
||||||
count: int = 0
|
count: int = 0
|
||||||
base: int = 1
|
base: int = 1
|
||||||
# cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
|
# cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
|
||||||
@ -63,36 +69,44 @@ def exponential(n: int) -> int:
|
|||||||
# count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
|
# count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
def exp_recur(n: int) -> int:
|
def exp_recur(n: int) -> int:
|
||||||
""" 指数阶(递归实现)"""
|
"""指数阶(递归实现)"""
|
||||||
if n == 1: return 1
|
if n == 1:
|
||||||
|
return 1
|
||||||
return exp_recur(n - 1) + exp_recur(n - 1) + 1
|
return exp_recur(n - 1) + exp_recur(n - 1) + 1
|
||||||
|
|
||||||
|
|
||||||
def logarithmic(n: float) -> int:
|
def logarithmic(n: float) -> int:
|
||||||
""" 对数阶(循环实现)"""
|
"""对数阶(循环实现)"""
|
||||||
count: int = 0
|
count: int = 0
|
||||||
while n > 1:
|
while n > 1:
|
||||||
n = n / 2
|
n = n / 2
|
||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
def log_recur(n: float) -> int:
|
def log_recur(n: float) -> int:
|
||||||
""" 对数阶(递归实现)"""
|
"""对数阶(递归实现)"""
|
||||||
if n <= 1: return 0
|
if n <= 1:
|
||||||
|
return 0
|
||||||
return log_recur(n / 2) + 1
|
return log_recur(n / 2) + 1
|
||||||
|
|
||||||
|
|
||||||
def linear_log_recur(n: float) -> int:
|
def linear_log_recur(n: float) -> int:
|
||||||
""" 线性对数阶 """
|
"""线性对数阶"""
|
||||||
if n <= 1: return 1
|
if n <= 1:
|
||||||
count: int = linear_log_recur(n // 2) + \
|
return 1
|
||||||
linear_log_recur(n // 2)
|
count: int = linear_log_recur(n // 2) + linear_log_recur(n // 2)
|
||||||
for _ in range(n):
|
for _ in range(n):
|
||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
def factorial_recur(n: int) -> int:
|
def factorial_recur(n: int) -> int:
|
||||||
""" 阶乘阶(递归实现)"""
|
"""阶乘阶(递归实现)"""
|
||||||
if n == 0: return 1
|
if n == 0:
|
||||||
|
return 1
|
||||||
count: int = 0
|
count: int = 0
|
||||||
# 从 1 个分裂出 n 个
|
# 从 1 个分裂出 n 个
|
||||||
for _ in range(n):
|
for _ in range(n):
|
||||||
|
@ -6,16 +6,18 @@ Author: Krahets (krahets@163.com)
|
|||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
def random_numbers(n: int) -> list[int]:
|
def random_numbers(n: int) -> list[int]:
|
||||||
""" 生成一个数组,元素为: 1, 2, ..., n ,顺序被打乱 """
|
"""生成一个数组,元素为: 1, 2, ..., n ,顺序被打乱"""
|
||||||
# 生成数组 nums =: 1, 2, 3, ..., n
|
# 生成数组 nums =: 1, 2, 3, ..., n
|
||||||
nums: list[int] = [i for i in range(1, n + 1)]
|
nums: list[int] = [i for i in range(1, n + 1)]
|
||||||
# 随机打乱数组元素
|
# 随机打乱数组元素
|
||||||
random.shuffle(nums)
|
random.shuffle(nums)
|
||||||
return nums
|
return nums
|
||||||
|
|
||||||
|
|
||||||
def find_one(nums: list[int]) -> int:
|
def find_one(nums: list[int]) -> int:
|
||||||
""" 查找数组 nums 中数字 1 所在索引 """
|
"""查找数组 nums 中数字 1 所在索引"""
|
||||||
for i in range(len(nums)):
|
for i in range(len(nums)):
|
||||||
# 当元素 1 在数组头部时,达到最佳时间复杂度 O(1)
|
# 当元素 1 在数组头部时,达到最佳时间复杂度 O(1)
|
||||||
# 当元素 1 在数组尾部时,达到最差时间复杂度 O(n)
|
# 当元素 1 在数组尾部时,达到最差时间复杂度 O(n)
|
||||||
|
@ -5,13 +5,16 @@ Author: Krahets (krahets@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
class GraphAdjList:
|
class GraphAdjList:
|
||||||
""" 基于邻接表实现的无向图类 """
|
"""基于邻接表实现的无向图类"""
|
||||||
|
|
||||||
def __init__(self, edges: list[list[Vertex]]) -> None:
|
def __init__(self, edges: list[list[Vertex]]) -> None:
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
# 邻接表,key: 顶点,value:该顶点的所有邻接顶点
|
# 邻接表,key: 顶点,value:该顶点的所有邻接顶点
|
||||||
self.adj_list = dict[Vertex, Vertex]()
|
self.adj_list = dict[Vertex, Vertex]()
|
||||||
# 添加所有顶点和边
|
# 添加所有顶点和边
|
||||||
@ -21,11 +24,11 @@ class GraphAdjList:
|
|||||||
self.add_edge(edge[0], edge[1])
|
self.add_edge(edge[0], edge[1])
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取顶点数量 """
|
"""获取顶点数量"""
|
||||||
return len(self.adj_list)
|
return len(self.adj_list)
|
||||||
|
|
||||||
def add_edge(self, vet1: Vertex, vet2: Vertex) -> None:
|
def add_edge(self, vet1: Vertex, vet2: Vertex) -> None:
|
||||||
""" 添加边 """
|
"""添加边"""
|
||||||
if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:
|
if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
# 添加边 vet1 - vet2
|
# 添加边 vet1 - vet2
|
||||||
@ -33,7 +36,7 @@ class GraphAdjList:
|
|||||||
self.adj_list[vet2].append(vet1)
|
self.adj_list[vet2].append(vet1)
|
||||||
|
|
||||||
def remove_edge(self, vet1: Vertex, vet2: Vertex) -> None:
|
def remove_edge(self, vet1: Vertex, vet2: Vertex) -> None:
|
||||||
""" 删除边 """
|
"""删除边"""
|
||||||
if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:
|
if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
# 删除边 vet1 - vet2
|
# 删除边 vet1 - vet2
|
||||||
@ -41,14 +44,14 @@ class GraphAdjList:
|
|||||||
self.adj_list[vet2].remove(vet1)
|
self.adj_list[vet2].remove(vet1)
|
||||||
|
|
||||||
def add_vertex(self, vet: Vertex) -> None:
|
def add_vertex(self, vet: Vertex) -> None:
|
||||||
""" 添加顶点 """
|
"""添加顶点"""
|
||||||
if vet in self.adj_list:
|
if vet in self.adj_list:
|
||||||
return
|
return
|
||||||
# 在邻接表中添加一个新链表
|
# 在邻接表中添加一个新链表
|
||||||
self.adj_list[vet] = []
|
self.adj_list[vet] = []
|
||||||
|
|
||||||
def remove_vertex(self, vet: Vertex) -> None:
|
def remove_vertex(self, vet: Vertex) -> None:
|
||||||
""" 删除顶点 """
|
"""删除顶点"""
|
||||||
if vet not in self.adj_list:
|
if vet not in self.adj_list:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
# 在邻接表中删除顶点 vet 对应的链表
|
# 在邻接表中删除顶点 vet 对应的链表
|
||||||
@ -59,7 +62,7 @@ class GraphAdjList:
|
|||||||
self.adj_list[vertex].remove(vet)
|
self.adj_list[vertex].remove(vet)
|
||||||
|
|
||||||
def print(self) -> None:
|
def print(self) -> None:
|
||||||
""" 打印邻接表 """
|
"""打印邻接表"""
|
||||||
print("邻接表 =")
|
print("邻接表 =")
|
||||||
for vertex in self.adj_list:
|
for vertex in self.adj_list:
|
||||||
tmp = [v.val for v in self.adj_list[vertex]]
|
tmp = [v.val for v in self.adj_list[vertex]]
|
||||||
@ -68,33 +71,39 @@ class GraphAdjList:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化无向图 """
|
# 初始化无向图
|
||||||
v = vals_to_vets([1, 3, 2, 5, 4])
|
v = vals_to_vets([1, 3, 2, 5, 4])
|
||||||
edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]],
|
edges = [
|
||||||
[v[2], v[3]], [v[2], v[4]], [v[3], v[4]]]
|
[v[0], v[1]],
|
||||||
|
[v[0], v[3]],
|
||||||
|
[v[1], v[2]],
|
||||||
|
[v[2], v[3]],
|
||||||
|
[v[2], v[4]],
|
||||||
|
[v[3], v[4]],
|
||||||
|
]
|
||||||
graph = GraphAdjList(edges)
|
graph = GraphAdjList(edges)
|
||||||
print("\n初始化后,图为")
|
print("\n初始化后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
""" 添加边 """
|
# 添加边
|
||||||
# 顶点 1, 2 即 v[0], v[2]
|
# 顶点 1, 2 即 v[0], v[2]
|
||||||
graph.add_edge(v[0], v[2])
|
graph.add_edge(v[0], v[2])
|
||||||
print("\n添加边 1-2 后,图为")
|
print("\n添加边 1-2 后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
""" 删除边 """
|
# 删除边
|
||||||
# 顶点 1, 3 即 v[0], v[1]
|
# 顶点 1, 3 即 v[0], v[1]
|
||||||
graph.remove_edge(v[0], v[1])
|
graph.remove_edge(v[0], v[1])
|
||||||
print("\n删除边 1-3 后,图为")
|
print("\n删除边 1-3 后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
""" 添加顶点 """
|
# 添加顶点
|
||||||
v5 = Vertex(6)
|
v5 = Vertex(6)
|
||||||
graph.add_vertex(v5)
|
graph.add_vertex(v5)
|
||||||
print("\n添加顶点 6 后,图为")
|
print("\n添加顶点 6 后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
""" 删除顶点 """
|
# 删除顶点
|
||||||
# 顶点 3 即 v[1]
|
# 顶点 3 即 v[1]
|
||||||
graph.remove_vertex(v[1])
|
graph.remove_vertex(v[1])
|
||||||
print("\n删除顶点 3 后,图为")
|
print("\n删除顶点 3 后,图为")
|
||||||
|
@ -5,18 +5,21 @@ Author: Krahets (krahets@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
class GraphAdjMat:
|
class GraphAdjMat:
|
||||||
""" 基于邻接矩阵实现的无向图类 """
|
"""基于邻接矩阵实现的无向图类"""
|
||||||
|
|
||||||
# 顶点列表,元素代表“顶点值”,索引代表“顶点索引”
|
# 顶点列表,元素代表“顶点值”,索引代表“顶点索引”
|
||||||
vertices: list[int] = []
|
vertices: list[int] = []
|
||||||
# 邻接矩阵,行列索引对应“顶点索引”
|
# 邻接矩阵,行列索引对应“顶点索引”
|
||||||
adj_mat: list[list[int]] = []
|
adj_mat: list[list[int]] = []
|
||||||
|
|
||||||
def __init__(self, vertices: list[int], edges: list[list[int]]) -> None:
|
def __init__(self, vertices: list[int], edges: list[list[int]]) -> None:
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.vertices: list[int] = []
|
self.vertices: list[int] = []
|
||||||
self.adj_mat: list[list[int]] = []
|
self.adj_mat: list[list[int]] = []
|
||||||
# 添加顶点
|
# 添加顶点
|
||||||
@ -28,11 +31,11 @@ class GraphAdjMat:
|
|||||||
self.add_edge(e[0], e[1])
|
self.add_edge(e[0], e[1])
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取顶点数量 """
|
"""获取顶点数量"""
|
||||||
return len(self.vertices)
|
return len(self.vertices)
|
||||||
|
|
||||||
def add_vertex(self, val: int) -> None:
|
def add_vertex(self, val: int) -> None:
|
||||||
""" 添加顶点 """
|
"""添加顶点"""
|
||||||
n = self.size()
|
n = self.size()
|
||||||
# 向顶点列表中添加新顶点的值
|
# 向顶点列表中添加新顶点的值
|
||||||
self.vertices.append(val)
|
self.vertices.append(val)
|
||||||
@ -44,7 +47,7 @@ class GraphAdjMat:
|
|||||||
row.append(0)
|
row.append(0)
|
||||||
|
|
||||||
def remove_vertex(self, index: int) -> None:
|
def remove_vertex(self, index: int) -> None:
|
||||||
""" 删除顶点 """
|
"""删除顶点"""
|
||||||
if index >= self.size():
|
if index >= self.size():
|
||||||
raise IndexError()
|
raise IndexError()
|
||||||
# 在顶点列表中移除索引 index 的顶点
|
# 在顶点列表中移除索引 index 的顶点
|
||||||
@ -56,7 +59,7 @@ class GraphAdjMat:
|
|||||||
row.pop(index)
|
row.pop(index)
|
||||||
|
|
||||||
def add_edge(self, i: int, j: int) -> None:
|
def add_edge(self, i: int, j: int) -> None:
|
||||||
""" 添加边 """
|
"""添加边"""
|
||||||
# 参数 i, j 对应 vertices 元素索引
|
# 参数 i, j 对应 vertices 元素索引
|
||||||
# 索引越界与相等处理
|
# 索引越界与相等处理
|
||||||
if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:
|
if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:
|
||||||
@ -66,7 +69,7 @@ class GraphAdjMat:
|
|||||||
self.adj_mat[j][i] = 1
|
self.adj_mat[j][i] = 1
|
||||||
|
|
||||||
def remove_edge(self, i: int, j: int) -> None:
|
def remove_edge(self, i: int, j: int) -> None:
|
||||||
""" 删除边 """
|
"""删除边"""
|
||||||
# 参数 i, j 对应 vertices 元素索引
|
# 参数 i, j 对应 vertices 元素索引
|
||||||
# 索引越界与相等处理
|
# 索引越界与相等处理
|
||||||
if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:
|
if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j:
|
||||||
@ -75,7 +78,7 @@ class GraphAdjMat:
|
|||||||
self.adj_mat[j][i] = 0
|
self.adj_mat[j][i] = 0
|
||||||
|
|
||||||
def print(self) -> None:
|
def print(self) -> None:
|
||||||
""" 打印邻接矩阵 """
|
"""打印邻接矩阵"""
|
||||||
print("顶点列表 =", self.vertices)
|
print("顶点列表 =", self.vertices)
|
||||||
print("邻接矩阵 =")
|
print("邻接矩阵 =")
|
||||||
print_matrix(self.adj_mat)
|
print_matrix(self.adj_mat)
|
||||||
@ -83,7 +86,7 @@ class GraphAdjMat:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化无向图 """
|
# 初始化无向图
|
||||||
# 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引
|
# 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引
|
||||||
vertices: list[int] = [1, 3, 2, 5, 4]
|
vertices: list[int] = [1, 3, 2, 5, 4]
|
||||||
edges: list[list[int]] = [[0, 1], [0, 3], [1, 2], [2, 3], [2, 4], [3, 4]]
|
edges: list[list[int]] = [[0, 1], [0, 3], [1, 2], [2, 3], [2, 4], [3, 4]]
|
||||||
@ -91,24 +94,24 @@ if __name__ == "__main__":
|
|||||||
print("\n初始化后,图为")
|
print("\n初始化后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
""" 添加边 """
|
# 添加边
|
||||||
# 顶点 1, 2 的索引分别为 0, 2
|
# 顶点 1, 2 的索引分别为 0, 2
|
||||||
graph.add_edge(0, 2)
|
graph.add_edge(0, 2)
|
||||||
print("\n添加边 1-2 后,图为")
|
print("\n添加边 1-2 后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
""" 删除边 """
|
# 删除边
|
||||||
# 顶点 1, 3 的索引分别为 0, 1
|
# 顶点 1, 3 的索引分别为 0, 1
|
||||||
graph.remove_edge(0, 1)
|
graph.remove_edge(0, 1)
|
||||||
print("\n删除边 1-3 后,图为")
|
print("\n删除边 1-3 后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
""" 添加顶点 """
|
# 添加顶点
|
||||||
graph.add_vertex(6)
|
graph.add_vertex(6)
|
||||||
print("\n添加顶点 6 后,图为")
|
print("\n添加顶点 6 后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
""" 删除顶点 """
|
# 删除顶点
|
||||||
# 顶点 3 的索引为 1
|
# 顶点 3 的索引为 1
|
||||||
graph.remove_vertex(1)
|
graph.remove_vertex(1)
|
||||||
print("\n删除顶点 3 后,图为")
|
print("\n删除顶点 3 后,图为")
|
||||||
|
@ -5,13 +5,15 @@ Author: Krahets (krahets@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from graph_adjacency_list import GraphAdjList
|
from graph_adjacency_list import GraphAdjList
|
||||||
|
|
||||||
|
|
||||||
def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
|
def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
|
||||||
""" 广度优先遍历 BFS """
|
"""广度优先遍历 BFS"""
|
||||||
# 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
|
# 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
|
||||||
# 顶点遍历序列
|
# 顶点遍历序列
|
||||||
res = []
|
res = []
|
||||||
@ -22,29 +24,40 @@ def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
|
|||||||
# 以顶点 vet 为起点,循环直至访问完所有顶点
|
# 以顶点 vet 为起点,循环直至访问完所有顶点
|
||||||
while len(que) > 0:
|
while len(que) > 0:
|
||||||
vet = que.popleft() # 队首顶点出队
|
vet = que.popleft() # 队首顶点出队
|
||||||
res.append(vet) # 记录访问顶点
|
res.append(vet) # 记录访问顶点
|
||||||
# 遍历该顶点的所有邻接顶点
|
# 遍历该顶点的所有邻接顶点
|
||||||
for adj_vet in graph.adj_list[vet]:
|
for adj_vet in graph.adj_list[vet]:
|
||||||
if adj_vet in visited:
|
if adj_vet in visited:
|
||||||
continue # 跳过已被访问过的顶点
|
continue # 跳过已被访问过的顶点
|
||||||
que.append(adj_vet) # 只入队未访问的顶点
|
que.append(adj_vet) # 只入队未访问的顶点
|
||||||
visited.add(adj_vet) # 标记该顶点已被访问
|
visited.add(adj_vet) # 标记该顶点已被访问
|
||||||
# 返回顶点遍历序列
|
# 返回顶点遍历序列
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
"""初始化无向图"""
|
# 初始化无向图
|
||||||
v = vals_to_vets([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
|
v = vals_to_vets([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||||||
edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]], [v[1], v[4]],
|
edges = [
|
||||||
[v[2], v[5]], [v[3], v[4]], [v[3], v[6]], [v[4], v[5]],
|
[v[0], v[1]],
|
||||||
[v[4], v[7]], [v[5], v[8]], [v[6], v[7]], [v[7], v[8]]]
|
[v[0], v[3]],
|
||||||
|
[v[1], v[2]],
|
||||||
|
[v[1], v[4]],
|
||||||
|
[v[2], v[5]],
|
||||||
|
[v[3], v[4]],
|
||||||
|
[v[3], v[6]],
|
||||||
|
[v[4], v[5]],
|
||||||
|
[v[4], v[7]],
|
||||||
|
[v[5], v[8]],
|
||||||
|
[v[6], v[7]],
|
||||||
|
[v[7], v[8]],
|
||||||
|
]
|
||||||
graph = GraphAdjList(edges)
|
graph = GraphAdjList(edges)
|
||||||
print("\n初始化后,图为")
|
print("\n初始化后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
"""广度优先遍历 BFS"""
|
# 广度优先遍历 BFS
|
||||||
res = graph_bfs(graph, v[0])
|
res = graph_bfs(graph, v[0])
|
||||||
print("\n广度优先遍历(BFS)顶点序列为")
|
print("\n广度优先遍历(BFS)顶点序列为")
|
||||||
print(vets_to_vals(res))
|
print(vets_to_vals(res))
|
||||||
|
@ -5,24 +5,27 @@ Author: Krahets (krahets@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
from graph_adjacency_list import GraphAdjList
|
from graph_adjacency_list import GraphAdjList
|
||||||
|
|
||||||
|
|
||||||
def dfs(graph: GraphAdjList, visited: set[Vertex], res: list[Vertex], vet: Vertex):
|
def dfs(graph: GraphAdjList, visited: set[Vertex], res: list[Vertex], vet: Vertex):
|
||||||
""" 深度优先遍历 DFS 辅助函数 """
|
"""深度优先遍历 DFS 辅助函数"""
|
||||||
res.append(vet) # 记录访问顶点
|
res.append(vet) # 记录访问顶点
|
||||||
visited.add(vet) # 标记该顶点已被访问
|
visited.add(vet) # 标记该顶点已被访问
|
||||||
# 遍历该顶点的所有邻接顶点
|
# 遍历该顶点的所有邻接顶点
|
||||||
for adjVet in graph.adj_list[vet]:
|
for adjVet in graph.adj_list[vet]:
|
||||||
if adjVet in visited:
|
if adjVet in visited:
|
||||||
continue # 跳过已被访问过的顶点
|
continue # 跳过已被访问过的顶点
|
||||||
# 递归访问邻接顶点
|
# 递归访问邻接顶点
|
||||||
dfs(graph, visited, res, adjVet)
|
dfs(graph, visited, res, adjVet)
|
||||||
|
|
||||||
|
|
||||||
# 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
|
# 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
|
||||||
def graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
|
def graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
|
||||||
""" 深度优先遍历 DFS """
|
"""深度优先遍历 DFS"""
|
||||||
# 顶点遍历序列
|
# 顶点遍历序列
|
||||||
res = []
|
res = []
|
||||||
# 哈希表,用于记录已被访问过的顶点
|
# 哈希表,用于记录已被访问过的顶点
|
||||||
@ -35,12 +38,18 @@ def graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# 初始化无向图
|
# 初始化无向图
|
||||||
v = vals_to_vets([0, 1, 2, 3, 4, 5, 6])
|
v = vals_to_vets([0, 1, 2, 3, 4, 5, 6])
|
||||||
edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]],
|
edges = [
|
||||||
[v[2], v[5]], [v[4], v[5]], [v[5], v[6]]]
|
[v[0], v[1]],
|
||||||
|
[v[0], v[3]],
|
||||||
|
[v[1], v[2]],
|
||||||
|
[v[2], v[5]],
|
||||||
|
[v[4], v[5]],
|
||||||
|
[v[5], v[6]],
|
||||||
|
]
|
||||||
graph = GraphAdjList(edges)
|
graph = GraphAdjList(edges)
|
||||||
print("\n初始化后,图为")
|
print("\n初始化后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
# 深度优先遍历 DFS
|
# 深度优先遍历 DFS
|
||||||
res = graph_dfs(graph, v[0])
|
res = graph_dfs(graph, v[0])
|
||||||
print("\n深度优先遍历(DFS)顶点序列为")
|
print("\n深度优先遍历(DFS)顶点序列为")
|
||||||
|
@ -4,26 +4,30 @@ Created Time: 2022-12-14
|
|||||||
Author: msk397 (machangxinq@gmail.com)
|
Author: msk397 (machangxinq@gmail.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Entry:
|
class Entry:
|
||||||
""" 键值对 int->String """
|
"""键值对 int->String"""
|
||||||
|
|
||||||
def __init__(self, key: int, val: str):
|
def __init__(self, key: int, val: str):
|
||||||
self.key = key
|
self.key = key
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
|
|
||||||
class ArrayHashMap:
|
class ArrayHashMap:
|
||||||
""" 基于数组简易实现的哈希表 """
|
"""基于数组简易实现的哈希表"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
# 初始化数组,包含 100 个桶
|
# 初始化数组,包含 100 个桶
|
||||||
self.buckets: list[Entry | None] = [None] * 100
|
self.buckets: list[Entry | None] = [None] * 100
|
||||||
|
|
||||||
def hash_func(self, key: int) -> int:
|
def hash_func(self, key: int) -> int:
|
||||||
""" 哈希函数 """
|
"""哈希函数"""
|
||||||
index: int = key % 100
|
index: int = key % 100
|
||||||
return index
|
return index
|
||||||
|
|
||||||
def get(self, key: int) -> str:
|
def get(self, key: int) -> str:
|
||||||
""" 查询操作 """
|
"""查询操作"""
|
||||||
index: int = self.hash_func(key)
|
index: int = self.hash_func(key)
|
||||||
pair: Entry = self.buckets[index]
|
pair: Entry = self.buckets[index]
|
||||||
if pair is None:
|
if pair is None:
|
||||||
@ -31,19 +35,19 @@ class ArrayHashMap:
|
|||||||
return pair.val
|
return pair.val
|
||||||
|
|
||||||
def put(self, key: int, val: str) -> None:
|
def put(self, key: int, val: str) -> None:
|
||||||
""" 添加操作 """
|
"""添加操作"""
|
||||||
pair = Entry(key, val)
|
pair = Entry(key, val)
|
||||||
index: int = self.hash_func(key)
|
index: int = self.hash_func(key)
|
||||||
self.buckets[index] = pair
|
self.buckets[index] = pair
|
||||||
|
|
||||||
def remove(self, key: int) -> None:
|
def remove(self, key: int) -> None:
|
||||||
""" 删除操作 """
|
"""删除操作"""
|
||||||
index: int = self.hash_func(key)
|
index: int = self.hash_func(key)
|
||||||
# 置为 None ,代表删除
|
# 置为 None ,代表删除
|
||||||
self.buckets[index] = None
|
self.buckets[index] = None
|
||||||
|
|
||||||
def entry_set(self) -> list[Entry]:
|
def entry_set(self) -> list[Entry]:
|
||||||
""" 获取所有键值对 """
|
"""获取所有键值对"""
|
||||||
result: list[Entry] = []
|
result: list[Entry] = []
|
||||||
for pair in self.buckets:
|
for pair in self.buckets:
|
||||||
if pair is not None:
|
if pair is not None:
|
||||||
@ -51,7 +55,7 @@ class ArrayHashMap:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def key_set(self) -> list[int]:
|
def key_set(self) -> list[int]:
|
||||||
""" 获取所有键 """
|
"""获取所有键"""
|
||||||
result: list[int] = []
|
result: list[int] = []
|
||||||
for pair in self.buckets:
|
for pair in self.buckets:
|
||||||
if pair is not None:
|
if pair is not None:
|
||||||
@ -59,7 +63,7 @@ class ArrayHashMap:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def value_set(self) -> list[str]:
|
def value_set(self) -> list[str]:
|
||||||
""" 获取所有值 """
|
"""获取所有值"""
|
||||||
result: list[str] = []
|
result: list[str] = []
|
||||||
for pair in self.buckets:
|
for pair in self.buckets:
|
||||||
if pair is not None:
|
if pair is not None:
|
||||||
@ -67,7 +71,7 @@ class ArrayHashMap:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def print(self) -> None:
|
def print(self) -> None:
|
||||||
""" 打印哈希表 """
|
"""打印哈希表"""
|
||||||
for pair in self.buckets:
|
for pair in self.buckets:
|
||||||
if pair is not None:
|
if pair is not None:
|
||||||
print(pair.key, "->", pair.val)
|
print(pair.key, "->", pair.val)
|
||||||
@ -75,10 +79,10 @@ class ArrayHashMap:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化哈希表 """
|
# 初始化哈希表
|
||||||
mapp = ArrayHashMap()
|
mapp = ArrayHashMap()
|
||||||
|
|
||||||
""" 添加操作 """
|
# 添加操作
|
||||||
# 在哈希表中添加键值对 (key, value)
|
# 在哈希表中添加键值对 (key, value)
|
||||||
mapp.put(12836, "小哈")
|
mapp.put(12836, "小哈")
|
||||||
mapp.put(15937, "小啰")
|
mapp.put(15937, "小啰")
|
||||||
@ -88,18 +92,18 @@ if __name__ == "__main__":
|
|||||||
print("\n添加完成后,哈希表为\nKey -> Value")
|
print("\n添加完成后,哈希表为\nKey -> Value")
|
||||||
mapp.print()
|
mapp.print()
|
||||||
|
|
||||||
""" 查询操作 """
|
# 查询操作
|
||||||
# 向哈希表输入键 key ,得到值 value
|
# 向哈希表输入键 key ,得到值 value
|
||||||
name = mapp.get(15937)
|
name = mapp.get(15937)
|
||||||
print("\n输入学号 15937 ,查询到姓名 " + name)
|
print("\n输入学号 15937 ,查询到姓名 " + name)
|
||||||
|
|
||||||
""" 删除操作 """
|
# 删除操作
|
||||||
# 在哈希表中删除键值对 (key, value)
|
# 在哈希表中删除键值对 (key, value)
|
||||||
mapp.remove(10583)
|
mapp.remove(10583)
|
||||||
print("\n删除 10583 后,哈希表为\nKey -> Value")
|
print("\n删除 10583 后,哈希表为\nKey -> Value")
|
||||||
mapp.print()
|
mapp.print()
|
||||||
|
|
||||||
""" 遍历哈希表 """
|
# 遍历哈希表
|
||||||
print("\n遍历键值对 Key->Value")
|
print("\n遍历键值对 Key->Value")
|
||||||
for pair in mapp.entry_set():
|
for pair in mapp.entry_set():
|
||||||
print(pair.key, "->", pair.val)
|
print(pair.key, "->", pair.val)
|
||||||
|
@ -5,15 +5,16 @@ Author: msk397 (machangxinq@gmail.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化哈希表 """
|
# 初始化哈希表
|
||||||
mapp = dict[int, str]()
|
mapp = dict[int, str]()
|
||||||
|
|
||||||
""" 添加操作 """
|
# 添加操作
|
||||||
# 在哈希表中添加键值对 (key, value)
|
# 在哈希表中添加键值对 (key, value)
|
||||||
mapp[12836] = "小哈"
|
mapp[12836] = "小哈"
|
||||||
mapp[15937] = "小啰"
|
mapp[15937] = "小啰"
|
||||||
@ -23,18 +24,18 @@ if __name__ == "__main__":
|
|||||||
print("\n添加完成后,哈希表为\nKey -> Value")
|
print("\n添加完成后,哈希表为\nKey -> Value")
|
||||||
print_dict(mapp)
|
print_dict(mapp)
|
||||||
|
|
||||||
""" 查询操作 """
|
# 查询操作
|
||||||
# 向哈希表输入键 key ,得到值 value
|
# 向哈希表输入键 key ,得到值 value
|
||||||
name: str = mapp[15937]
|
name: str = mapp[15937]
|
||||||
print("\n输入学号 15937 ,查询到姓名 " + name)
|
print("\n输入学号 15937 ,查询到姓名 " + name)
|
||||||
|
|
||||||
""" 删除操作 """
|
# 删除操作
|
||||||
# 在哈希表中删除键值对 (key, value)
|
# 在哈希表中删除键值对 (key, value)
|
||||||
mapp.pop(10583)
|
mapp.pop(10583)
|
||||||
print("\n删除 10583 后,哈希表为\nKey -> Value")
|
print("\n删除 10583 后,哈希表为\nKey -> Value")
|
||||||
print_dict(mapp)
|
print_dict(mapp)
|
||||||
|
|
||||||
""" 遍历哈希表 """
|
# 遍历哈希表
|
||||||
print("\n遍历键值对 Key->Value")
|
print("\n遍历键值对 Key->Value")
|
||||||
for key, value in mapp.items():
|
for key, value in mapp.items():
|
||||||
print(key, "->", value)
|
print(key, "->", value)
|
||||||
|
@ -5,6 +5,7 @@ Author: Krahets (krahets@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
@ -16,11 +17,13 @@ def test_push(heap: list, val: int, flag: int = 1) -> None:
|
|||||||
print(f"\n元素 {val} 入堆后")
|
print(f"\n元素 {val} 入堆后")
|
||||||
print_heap([flag * val for val in heap])
|
print_heap([flag * val for val in heap])
|
||||||
|
|
||||||
|
|
||||||
def test_pop(heap: list, flag: int = 1) -> None:
|
def test_pop(heap: list, flag: int = 1) -> None:
|
||||||
val = flag * heapq.heappop(heap) # 堆顶元素出堆
|
val = flag * heapq.heappop(heap) # 堆顶元素出堆
|
||||||
print(f"\n堆顶元素 {val} 出堆后")
|
print(f"\n堆顶元素 {val} 出堆后")
|
||||||
print_heap([flag * val for val in heap])
|
print_heap([flag * val for val in heap])
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# 初始化小顶堆
|
# 初始化小顶堆
|
||||||
|
@ -5,13 +5,16 @@ Author: Krahets (krahets@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
class MaxHeap:
|
class MaxHeap:
|
||||||
""" 大顶堆 """
|
"""大顶堆"""
|
||||||
|
|
||||||
def __init__(self, nums: list[int]):
|
def __init__(self, nums: list[int]):
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
# 将列表元素原封不动添加进堆
|
# 将列表元素原封不动添加进堆
|
||||||
self.max_heap = nums
|
self.max_heap = nums
|
||||||
# 堆化除叶节点以外的其他所有节点
|
# 堆化除叶节点以外的其他所有节点
|
||||||
@ -19,43 +22,43 @@ class MaxHeap:
|
|||||||
self.sift_down(i)
|
self.sift_down(i)
|
||||||
|
|
||||||
def left(self, i: int) -> int:
|
def left(self, i: int) -> int:
|
||||||
""" 获取左子节点索引 """
|
"""获取左子节点索引"""
|
||||||
return 2 * i + 1
|
return 2 * i + 1
|
||||||
|
|
||||||
def right(self, i: int) -> int:
|
def right(self, i: int) -> int:
|
||||||
""" 获取右子节点索引 """
|
"""获取右子节点索引"""
|
||||||
return 2 * i + 2
|
return 2 * i + 2
|
||||||
|
|
||||||
def parent(self, i: int) -> int:
|
def parent(self, i: int) -> int:
|
||||||
""" 获取父节点索引 """
|
"""获取父节点索引"""
|
||||||
return (i - 1) // 2 # 向下整除
|
return (i - 1) // 2 # 向下整除
|
||||||
|
|
||||||
def swap(self, i: int, j: int):
|
def swap(self, i: int, j: int):
|
||||||
""" 交换元素 """
|
"""交换元素"""
|
||||||
a, b = self.max_heap[i], self.max_heap[j]
|
a, b = self.max_heap[i], self.max_heap[j]
|
||||||
self.max_heap[i], self.max_heap[j] = b, a
|
self.max_heap[i], self.max_heap[j] = b, a
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取堆大小 """
|
"""获取堆大小"""
|
||||||
return len(self.max_heap)
|
return len(self.max_heap)
|
||||||
|
|
||||||
def is_empty(self) -> bool:
|
def is_empty(self) -> bool:
|
||||||
""" 判断堆是否为空 """
|
"""判断堆是否为空"""
|
||||||
return self.size() == 0
|
return self.size() == 0
|
||||||
|
|
||||||
def peek(self) -> int:
|
def peek(self) -> int:
|
||||||
""" 访问堆顶元素 """
|
"""访问堆顶元素"""
|
||||||
return self.max_heap[0]
|
return self.max_heap[0]
|
||||||
|
|
||||||
def push(self, val: int):
|
def push(self, val: int):
|
||||||
""" 元素入堆 """
|
"""元素入堆"""
|
||||||
# 添加节点
|
# 添加节点
|
||||||
self.max_heap.append(val)
|
self.max_heap.append(val)
|
||||||
# 从底至顶堆化
|
# 从底至顶堆化
|
||||||
self.sift_up(self.size() - 1)
|
self.sift_up(self.size() - 1)
|
||||||
|
|
||||||
def sift_up(self, i: int):
|
def sift_up(self, i: int):
|
||||||
""" 从节点 i 开始,从底至顶堆化 """
|
"""从节点 i 开始,从底至顶堆化"""
|
||||||
while True:
|
while True:
|
||||||
# 获取节点 i 的父节点
|
# 获取节点 i 的父节点
|
||||||
p = self.parent(i)
|
p = self.parent(i)
|
||||||
@ -68,7 +71,7 @@ class MaxHeap:
|
|||||||
i = p
|
i = p
|
||||||
|
|
||||||
def pop(self) -> int:
|
def pop(self) -> int:
|
||||||
""" 元素出堆 """
|
"""元素出堆"""
|
||||||
# 判空处理
|
# 判空处理
|
||||||
assert not self.is_empty()
|
assert not self.is_empty()
|
||||||
# 交换根节点与最右叶节点(即交换首元素与尾元素)
|
# 交换根节点与最右叶节点(即交换首元素与尾元素)
|
||||||
@ -81,7 +84,7 @@ class MaxHeap:
|
|||||||
return val
|
return val
|
||||||
|
|
||||||
def sift_down(self, i: int):
|
def sift_down(self, i: int):
|
||||||
""" 从节点 i 开始,从顶至底堆化 """
|
"""从节点 i 开始,从顶至底堆化"""
|
||||||
while True:
|
while True:
|
||||||
# 判断节点 i, l, r 中值最大的节点,记为 ma
|
# 判断节点 i, l, r 中值最大的节点,记为 ma
|
||||||
l, r, ma = self.left(i), self.right(i), i
|
l, r, ma = self.left(i), self.right(i), i
|
||||||
@ -98,7 +101,7 @@ class MaxHeap:
|
|||||||
i = ma
|
i = ma
|
||||||
|
|
||||||
def print(self):
|
def print(self):
|
||||||
""" 打印堆(二叉树) """
|
"""打印堆(二叉树)"""
|
||||||
print_heap(self.max_heap)
|
print_heap(self.max_heap)
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,46 +4,47 @@ Created Time: 2022-11-26
|
|||||||
Author: timi (xisunyy@163.com)
|
Author: timi (xisunyy@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def binary_search(nums: list[int], target: int) -> int:
|
def binary_search(nums: list[int], target: int) -> int:
|
||||||
""" 二分查找(双闭区间) """
|
"""二分查找(双闭区间)"""
|
||||||
# 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
# 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
||||||
i, j = 0, len(nums) - 1
|
i, j = 0, len(nums) - 1
|
||||||
while i <= j:
|
while i <= j:
|
||||||
m = (i + j) // 2 # 计算中点索引 m
|
m = (i + j) // 2 # 计算中点索引 m
|
||||||
if nums[m] < target: # 此情况说明 target 在区间 [m+1, j] 中
|
if nums[m] < target: # 此情况说明 target 在区间 [m+1, j] 中
|
||||||
i = m + 1
|
i = m + 1
|
||||||
elif nums[m] > target: # 此情况说明 target 在区间 [i, m-1] 中
|
elif nums[m] > target: # 此情况说明 target 在区间 [i, m-1] 中
|
||||||
j = m - 1
|
j = m - 1
|
||||||
else:
|
else:
|
||||||
return m # 找到目标元素,返回其索引
|
return m # 找到目标元素,返回其索引
|
||||||
return -1 # 未找到目标元素,返回 -1
|
return -1 # 未找到目标元素,返回 -1
|
||||||
|
|
||||||
|
|
||||||
def binary_search1(nums: list[int], target: int) -> int:
|
def binary_search1(nums: list[int], target: int) -> int:
|
||||||
""" 二分查找(左闭右开) """
|
"""二分查找(左闭右开)"""
|
||||||
# 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
|
# 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
|
||||||
i, j = 0, len(nums)
|
i, j = 0, len(nums)
|
||||||
# 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
# 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
||||||
while i < j:
|
while i < j:
|
||||||
m = (i + j) // 2 # 计算中点索引 m
|
m = (i + j) // 2 # 计算中点索引 m
|
||||||
if nums[m] < target: # 此情况说明 target 在区间 [m+1, j) 中
|
if nums[m] < target: # 此情况说明 target 在区间 [m+1, j) 中
|
||||||
i = m + 1
|
i = m + 1
|
||||||
elif nums[m] > target: # 此情况说明 target 在区间 [i, m) 中
|
elif nums[m] > target: # 此情况说明 target 在区间 [i, m) 中
|
||||||
j = m
|
j = m
|
||||||
else: # 找到目标元素,返回其索引
|
else: # 找到目标元素,返回其索引
|
||||||
return m
|
return m
|
||||||
return -1 # 未找到目标元素,返回 -1
|
return -1 # 未找到目标元素,返回 -1
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
target: int = 6
|
target: int = 6
|
||||||
nums: list[int] = [1, 3, 6, 8, 12, 15, 23, 67, 70, 92]
|
nums: list[int] = [1, 3, 6, 8, 12, 15, 23, 67, 70, 92]
|
||||||
|
|
||||||
# 二分查找(双闭区间)
|
# 二分查找(双闭区间)
|
||||||
index: int = binary_search(nums, target)
|
index: int = binary_search(nums, target)
|
||||||
print("目标元素 6 的索引 = ", index)
|
print("目标元素 6 的索引 = ", index)
|
||||||
|
|
||||||
# 二分查找(左闭右开)
|
# 二分查找(左闭右开)
|
||||||
index: int = binary_search1(nums, target)
|
index: int = binary_search1(nums, target)
|
||||||
print("目标元素 6 的索引 = ", index)
|
print("目标元素 6 的索引 = ", index)
|
||||||
|
@ -5,26 +5,31 @@ Author: timi (xisunyy@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
def hashing_search_array(mapp: dict[int, int], target: int) -> int:
|
def hashing_search_array(mapp: dict[int, int], target: int) -> int:
|
||||||
""" 哈希查找(数组) """
|
"""哈希查找(数组)"""
|
||||||
# 哈希表的 key: 目标元素,value: 索引
|
# 哈希表的 key: 目标元素,value: 索引
|
||||||
# 若哈希表中无此 key ,返回 -1
|
# 若哈希表中无此 key ,返回 -1
|
||||||
return mapp.get(target, -1)
|
return mapp.get(target, -1)
|
||||||
|
|
||||||
def hashing_search_linkedlist(mapp: dict[int, ListNode], target: int) -> ListNode | None:
|
|
||||||
""" 哈希查找(链表) """
|
def hashing_search_linkedlist(
|
||||||
|
mapp: dict[int, ListNode], target: int
|
||||||
|
) -> ListNode | None:
|
||||||
|
"""哈希查找(链表)"""
|
||||||
# 哈希表的 key: 目标元素,value: 节点对象
|
# 哈希表的 key: 目标元素,value: 节点对象
|
||||||
# 若哈希表中无此 key ,返回 None
|
# 若哈希表中无此 key ,返回 None
|
||||||
return mapp.get(target, None)
|
return mapp.get(target, None)
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
target: int = 3
|
target: int = 3
|
||||||
|
|
||||||
# 哈希查找(数组)
|
# 哈希查找(数组)
|
||||||
nums: list[int] = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8]
|
nums: list[int] = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8]
|
||||||
# 初始化哈希表
|
# 初始化哈希表
|
||||||
|
@ -5,31 +5,34 @@ Author: timi (xisunyy@163.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
def linear_search_array(nums: list[int], target: int) -> int:
|
def linear_search_array(nums: list[int], target: int) -> int:
|
||||||
""" 线性查找(数组) """
|
"""线性查找(数组)"""
|
||||||
# 遍历数组
|
# 遍历数组
|
||||||
for i in range(len(nums)):
|
for i in range(len(nums)):
|
||||||
if nums[i] == target: # 找到目标元素,返回其索引
|
if nums[i] == target: # 找到目标元素,返回其索引
|
||||||
return i
|
return i
|
||||||
return -1 # 未找到目标元素,返回 -1
|
return -1 # 未找到目标元素,返回 -1
|
||||||
|
|
||||||
|
|
||||||
def linear_search_linkedlist(head: ListNode, target: int) -> ListNode | None:
|
def linear_search_linkedlist(head: ListNode, target: int) -> ListNode | None:
|
||||||
""" 线性查找(链表) """
|
"""线性查找(链表)"""
|
||||||
# 遍历链表
|
# 遍历链表
|
||||||
while head:
|
while head:
|
||||||
if head.val == target: # 找到目标节点,返回之
|
if head.val == target: # 找到目标节点,返回之
|
||||||
return head
|
return head
|
||||||
head = head.next
|
head = head.next
|
||||||
return None # 未找到目标节点,返回 None
|
return None # 未找到目标节点,返回 None
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
target: int = 3
|
target: int = 3
|
||||||
|
|
||||||
# 在数组中执行线性查找
|
# 在数组中执行线性查找
|
||||||
nums: list[int] = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8]
|
nums: list[int] = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8]
|
||||||
index: int = linear_search_array(nums, target)
|
index: int = linear_search_array(nums, target)
|
||||||
|
@ -4,8 +4,9 @@ Created Time: 2022-11-25
|
|||||||
Author: timi (xisunyy@163.com)
|
Author: timi (xisunyy@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def bubble_sort(nums: list[int]) -> None:
|
def bubble_sort(nums: list[int]) -> None:
|
||||||
""" 冒泡排序 """
|
"""冒泡排序"""
|
||||||
n: int = len(nums)
|
n: int = len(nums)
|
||||||
# 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
# 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||||
for i in range(n - 1, 0, -1):
|
for i in range(n - 1, 0, -1):
|
||||||
@ -15,8 +16,9 @@ def bubble_sort(nums: list[int]) -> None:
|
|||||||
# 交换 nums[j] 与 nums[j + 1]
|
# 交换 nums[j] 与 nums[j + 1]
|
||||||
nums[j], nums[j + 1] = nums[j + 1], nums[j]
|
nums[j], nums[j + 1] = nums[j + 1], nums[j]
|
||||||
|
|
||||||
|
|
||||||
def bubble_sort_with_flag(nums: list[int]) -> None:
|
def bubble_sort_with_flag(nums: list[int]) -> None:
|
||||||
""" 冒泡排序(标志优化) """
|
"""冒泡排序(标志优化)"""
|
||||||
n: int = len(nums)
|
n: int = len(nums)
|
||||||
# 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
# 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||||
for i in range(n - 1, 0, -1):
|
for i in range(n - 1, 0, -1):
|
||||||
@ -28,11 +30,11 @@ def bubble_sort_with_flag(nums: list[int]) -> None:
|
|||||||
nums[j], nums[j + 1] = nums[j + 1], nums[j]
|
nums[j], nums[j + 1] = nums[j + 1], nums[j]
|
||||||
flag = True # 记录交换元素
|
flag = True # 记录交换元素
|
||||||
if not flag:
|
if not flag:
|
||||||
break # 此轮冒泡未交换任何元素,直接跳出
|
break # 此轮冒泡未交换任何元素,直接跳出
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
nums: list[int] = [4, 1, 3, 1, 5, 2]
|
nums: list[int] = [4, 1, 3, 1, 5, 2]
|
||||||
bubble_sort(nums)
|
bubble_sort(nums)
|
||||||
print("排序后数组 nums =", nums)
|
print("排序后数组 nums =", nums)
|
||||||
|
@ -4,6 +4,7 @@ Created Time: 2023-03-30
|
|||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def bucket_sort(nums: list[float]) -> None:
|
def bucket_sort(nums: list[float]) -> None:
|
||||||
# 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
|
# 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
|
||||||
k = len(nums) // 2
|
k = len(nums) // 2
|
||||||
@ -26,7 +27,7 @@ def bucket_sort(nums: list[float]) -> None:
|
|||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
# 设输入数据为浮点数,范围为 [0, 1)
|
# 设输入数据为浮点数,范围为 [0, 1)
|
||||||
nums = [0.49, 0.96, 0.82, 0.09, 0.57, 0.43, 0.91, 0.75, 0.15, 0.37]
|
nums = [0.49, 0.96, 0.82, 0.09, 0.57, 0.43, 0.91, 0.75, 0.15, 0.37]
|
||||||
bucket_sort(nums)
|
bucket_sort(nums)
|
||||||
|
@ -4,8 +4,9 @@ Created Time: 2023-03-21
|
|||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def counting_sort_naive(nums: list[int]) -> None:
|
def counting_sort_naive(nums: list[int]) -> None:
|
||||||
""" 计数排序 """
|
"""计数排序"""
|
||||||
# 简单实现,无法用于排序对象
|
# 简单实现,无法用于排序对象
|
||||||
# 1. 统计数组最大元素 m
|
# 1. 统计数组最大元素 m
|
||||||
m = 0
|
m = 0
|
||||||
@ -23,8 +24,9 @@ def counting_sort_naive(nums: list[int]) -> None:
|
|||||||
nums[i] = num
|
nums[i] = num
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
def counting_sort(nums: list[int]) -> None:
|
def counting_sort(nums: list[int]) -> None:
|
||||||
""" 计数排序 """
|
"""计数排序"""
|
||||||
# 完整实现,可排序对象,并且是稳定排序
|
# 完整实现,可排序对象,并且是稳定排序
|
||||||
# 1. 统计数组最大元素 m
|
# 1. 统计数组最大元素 m
|
||||||
m = max(nums)
|
m = max(nums)
|
||||||
@ -49,6 +51,7 @@ def counting_sort(nums: list[int]) -> None:
|
|||||||
for i in range(n):
|
for i in range(n):
|
||||||
nums[i] = res[i]
|
nums[i] = res[i]
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
nums = [1, 0, 1, 2, 0, 4, 0, 2, 2, 4]
|
nums = [1, 0, 1, 2, 0, 4, 0, 2, 2, 4]
|
||||||
|
@ -4,9 +4,10 @@ Created Time: 2022-11-25
|
|||||||
Author: timi (xisunyy@163.com)
|
Author: timi (xisunyy@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def insertion_sort(nums: list[int]) -> None:
|
def insertion_sort(nums: list[int]) -> None:
|
||||||
""" 插入排序 """
|
"""插入排序"""
|
||||||
# 外循环:base = nums[1], nums[2], ..., nums[n-1]
|
# 外循环:base = nums[1], nums[2], ..., nums[n-1]
|
||||||
for i in range(1, len(nums)):
|
for i in range(1, len(nums)):
|
||||||
base: int = nums[i]
|
base: int = nums[i]
|
||||||
j: int = i - 1
|
j: int = i - 1
|
||||||
@ -14,11 +15,11 @@ def insertion_sort(nums: list[int]) -> None:
|
|||||||
while j >= 0 and nums[j] > base:
|
while j >= 0 and nums[j] > base:
|
||||||
nums[j + 1] = nums[j] # 1. 将 nums[j] 向右移动一位
|
nums[j + 1] = nums[j] # 1. 将 nums[j] 向右移动一位
|
||||||
j -= 1
|
j -= 1
|
||||||
nums[j + 1] = base # 2. 将 base 赋值到正确位置
|
nums[j + 1] = base # 2. 将 base 赋值到正确位置
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
nums: list[int] = [4, 1, 3, 1, 5, 2]
|
nums: list[int] = [4, 1, 3, 1, 5, 2]
|
||||||
insertion_sort(nums)
|
insertion_sort(nums)
|
||||||
print("排序后数组 nums =", nums)
|
print("排序后数组 nums =", nums)
|
||||||
|
@ -4,12 +4,13 @@ Created Time: 2022-11-25
|
|||||||
Author: timi (xisunyy@163.com)
|
Author: timi (xisunyy@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def merge(nums: list[int], left: int, mid: int, right: int) -> None:
|
def merge(nums: list[int], left: int, mid: int, right: int) -> None:
|
||||||
""" 合并左子数组和右子数组 """
|
"""合并左子数组和右子数组"""
|
||||||
# 左子数组区间 [left, mid]
|
# 左子数组区间 [left, mid]
|
||||||
# 右子数组区间 [mid + 1, right]
|
# 右子数组区间 [mid + 1, right]
|
||||||
# 初始化辅助数组
|
# 初始化辅助数组
|
||||||
tmp: list[int] = list(nums[left:right + 1])
|
tmp: list[int] = list(nums[left : right + 1])
|
||||||
# 左子数组的起始索引和结束索引
|
# 左子数组的起始索引和结束索引
|
||||||
left_start: int = 0
|
left_start: int = 0
|
||||||
left_end: int = mid - left
|
left_end: int = mid - left
|
||||||
@ -34,21 +35,22 @@ def merge(nums: list[int], left: int, mid: int, right: int) -> None:
|
|||||||
nums[k] = tmp[j]
|
nums[k] = tmp[j]
|
||||||
j += 1
|
j += 1
|
||||||
|
|
||||||
|
|
||||||
def merge_sort(nums: list[int], left: int, right: int) -> None:
|
def merge_sort(nums: list[int], left: int, right: int) -> None:
|
||||||
""" 归并排序 """
|
"""归并排序"""
|
||||||
# 终止条件
|
# 终止条件
|
||||||
if left >= right:
|
if left >= right:
|
||||||
return # 当子数组长度为 1 时终止递归
|
return # 当子数组长度为 1 时终止递归
|
||||||
# 划分阶段
|
# 划分阶段
|
||||||
mid: int = (left + right) // 2 # 计算中点
|
mid: int = (left + right) // 2 # 计算中点
|
||||||
merge_sort(nums, left, mid) # 递归左子数组
|
merge_sort(nums, left, mid) # 递归左子数组
|
||||||
merge_sort(nums, mid + 1, right) # 递归右子数组
|
merge_sort(nums, mid + 1, right) # 递归右子数组
|
||||||
# 合并阶段
|
# 合并阶段
|
||||||
merge(nums, left, mid, right)
|
merge(nums, left, mid, right)
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
nums: list[int] = [ 7, 3, 2, 6, 0, 1, 5, 4 ]
|
nums: list[int] = [7, 3, 2, 6, 0, 1, 5, 4]
|
||||||
merge_sort(nums, 0, len(nums) - 1)
|
merge_sort(nums, 0, len(nums) - 1)
|
||||||
print("归并排序完成后 nums =", nums)
|
print("归并排序完成后 nums =", nums)
|
||||||
|
@ -4,10 +4,12 @@ Created Time: 2022-11-25
|
|||||||
Author: timi (xisunyy@163.com)
|
Author: timi (xisunyy@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class QuickSort:
|
class QuickSort:
|
||||||
""" 快速排序类 """
|
"""快速排序类"""
|
||||||
|
|
||||||
def partition(self, nums: list[int], left: int, right: int) -> int:
|
def partition(self, nums: list[int], left: int, right: int) -> int:
|
||||||
""" 哨兵划分 """
|
"""哨兵划分"""
|
||||||
# 以 nums[left] 作为基准数
|
# 以 nums[left] 作为基准数
|
||||||
i, j = left, right
|
i, j = left, right
|
||||||
while i < j:
|
while i < j:
|
||||||
@ -22,7 +24,7 @@ class QuickSort:
|
|||||||
return i # 返回基准数的索引
|
return i # 返回基准数的索引
|
||||||
|
|
||||||
def quick_sort(self, nums: list[int], left: int, right: int) -> None:
|
def quick_sort(self, nums: list[int], left: int, right: int) -> None:
|
||||||
""" 快速排序 """
|
"""快速排序"""
|
||||||
# 子数组长度为 1 时终止递归
|
# 子数组长度为 1 时终止递归
|
||||||
if left >= right:
|
if left >= right:
|
||||||
return
|
return
|
||||||
@ -32,10 +34,12 @@ class QuickSort:
|
|||||||
self.quick_sort(nums, left, pivot - 1)
|
self.quick_sort(nums, left, pivot - 1)
|
||||||
self.quick_sort(nums, pivot + 1, right)
|
self.quick_sort(nums, pivot + 1, right)
|
||||||
|
|
||||||
|
|
||||||
class QuickSortMedian:
|
class QuickSortMedian:
|
||||||
""" 快速排序类(中位基准数优化)"""
|
"""快速排序类(中位基准数优化)"""
|
||||||
|
|
||||||
def median_three(self, nums: list[int], left: int, mid: int, right: int) -> int:
|
def median_three(self, nums: list[int], left: int, mid: int, right: int) -> int:
|
||||||
""" 选取三个元素的中位数 """
|
"""选取三个元素的中位数"""
|
||||||
# 此处使用异或运算来简化代码
|
# 此处使用异或运算来简化代码
|
||||||
# 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
|
# 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
|
||||||
if (nums[left] < nums[mid]) ^ (nums[left] < nums[right]):
|
if (nums[left] < nums[mid]) ^ (nums[left] < nums[right]):
|
||||||
@ -45,7 +49,7 @@ class QuickSortMedian:
|
|||||||
return right
|
return right
|
||||||
|
|
||||||
def partition(self, nums: list[int], left: int, right: int) -> int:
|
def partition(self, nums: list[int], left: int, right: int) -> int:
|
||||||
""" 哨兵划分(三数取中值) """
|
"""哨兵划分(三数取中值)"""
|
||||||
# 以 nums[left] 作为基准数
|
# 以 nums[left] 作为基准数
|
||||||
med: int = self.median_three(nums, left, (left + right) // 2, right)
|
med: int = self.median_three(nums, left, (left + right) // 2, right)
|
||||||
# 将中位数交换至数组最左端
|
# 将中位数交换至数组最左端
|
||||||
@ -64,7 +68,7 @@ class QuickSortMedian:
|
|||||||
return i # 返回基准数的索引
|
return i # 返回基准数的索引
|
||||||
|
|
||||||
def quick_sort(self, nums: list[int], left: int, right: int) -> None:
|
def quick_sort(self, nums: list[int], left: int, right: int) -> None:
|
||||||
""" 快速排序 """
|
"""快速排序"""
|
||||||
# 子数组长度为 1 时终止递归
|
# 子数组长度为 1 时终止递归
|
||||||
if left >= right:
|
if left >= right:
|
||||||
return
|
return
|
||||||
@ -74,10 +78,12 @@ class QuickSortMedian:
|
|||||||
self.quick_sort(nums, left, pivot - 1)
|
self.quick_sort(nums, left, pivot - 1)
|
||||||
self.quick_sort(nums, pivot + 1, right)
|
self.quick_sort(nums, pivot + 1, right)
|
||||||
|
|
||||||
|
|
||||||
class QuickSortTailCall:
|
class QuickSortTailCall:
|
||||||
""" 快速排序类(尾递归优化) """
|
"""快速排序类(尾递归优化)"""
|
||||||
|
|
||||||
def partition(self, nums: list[int], left: int, right: int) -> int:
|
def partition(self, nums: list[int], left: int, right: int) -> int:
|
||||||
""" 哨兵划分 """
|
"""哨兵划分"""
|
||||||
# 以 nums[left] 作为基准数
|
# 以 nums[left] 作为基准数
|
||||||
i, j = left, right
|
i, j = left, right
|
||||||
while i < j:
|
while i < j:
|
||||||
@ -92,7 +98,7 @@ class QuickSortTailCall:
|
|||||||
return i # 返回基准数的索引
|
return i # 返回基准数的索引
|
||||||
|
|
||||||
def quick_sort(self, nums: list[int], left: int, right: int) -> None:
|
def quick_sort(self, nums: list[int], left: int, right: int) -> None:
|
||||||
""" 快速排序(尾递归优化) """
|
"""快速排序(尾递归优化)"""
|
||||||
# 子数组长度为 1 时终止
|
# 子数组长度为 1 时终止
|
||||||
while left < right:
|
while left < right:
|
||||||
# 哨兵划分操作
|
# 哨兵划分操作
|
||||||
@ -100,15 +106,15 @@ class QuickSortTailCall:
|
|||||||
# 对两个子数组中较短的那个执行快排
|
# 对两个子数组中较短的那个执行快排
|
||||||
if pivot - left < right - pivot:
|
if pivot - left < right - pivot:
|
||||||
self.quick_sort(nums, left, pivot - 1) # 递归排序左子数组
|
self.quick_sort(nums, left, pivot - 1) # 递归排序左子数组
|
||||||
left = pivot + 1 # 剩余待排序区间为 [pivot + 1, right]
|
left = pivot + 1 # 剩余待排序区间为 [pivot + 1, right]
|
||||||
else:
|
else:
|
||||||
self.quick_sort(nums, pivot + 1, right) # 递归排序右子数组
|
self.quick_sort(nums, pivot + 1, right) # 递归排序右子数组
|
||||||
right = pivot - 1 # 剩余待排序区间为 [left, pivot - 1]
|
right = pivot - 1 # 剩余待排序区间为 [left, pivot - 1]
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
# 快速排序
|
# 快速排序
|
||||||
nums: list[int] = [2, 4, 1, 0, 3, 5]
|
nums: list[int] = [2, 4, 1, 0, 3, 5]
|
||||||
QuickSort().quick_sort(nums, 0, len(nums) - 1)
|
QuickSort().quick_sort(nums, 0, len(nums) - 1)
|
||||||
print("快速排序完成后 nums =", nums)
|
print("快速排序完成后 nums =", nums)
|
||||||
|
@ -6,19 +6,20 @@ Author: Krahets (krahets@163.com)
|
|||||||
|
|
||||||
|
|
||||||
def digit(num: int, exp: int) -> int:
|
def digit(num: int, exp: int) -> int:
|
||||||
""" 获取元素 num 的第 k 位,其中 exp = 10^(k-1) """
|
"""获取元素 num 的第 k 位,其中 exp = 10^(k-1)"""
|
||||||
# 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
|
# 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算
|
||||||
return (num // exp) % 10
|
return (num // exp) % 10
|
||||||
|
|
||||||
|
|
||||||
def counting_sort_digit(nums: list[int], exp: int) -> None:
|
def counting_sort_digit(nums: list[int], exp: int) -> None:
|
||||||
""" 计数排序(根据 nums 第 k 位排序) """
|
"""计数排序(根据 nums 第 k 位排序)"""
|
||||||
# 十进制的位范围为 0~9 ,因此需要长度为 10 的桶
|
# 十进制的位范围为 0~9 ,因此需要长度为 10 的桶
|
||||||
counter = [0] * 10
|
counter = [0] * 10
|
||||||
n = len(nums)
|
n = len(nums)
|
||||||
# 统计 0~9 各数字的出现次数
|
# 统计 0~9 各数字的出现次数
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
d = digit(nums[i], exp) # 获取 nums[i] 第 k 位,记为 d
|
d = digit(nums[i], exp) # 获取 nums[i] 第 k 位,记为 d
|
||||||
counter[d] += 1 # 统计数字 d 的出现次数
|
counter[d] += 1 # 统计数字 d 的出现次数
|
||||||
# 求前缀和,将“出现个数”转换为“数组索引”
|
# 求前缀和,将“出现个数”转换为“数组索引”
|
||||||
for i in range(1, 10):
|
for i in range(1, 10):
|
||||||
counter[i] += counter[i - 1]
|
counter[i] += counter[i - 1]
|
||||||
@ -27,14 +28,15 @@ def counting_sort_digit(nums: list[int], exp: int) -> None:
|
|||||||
for i in range(n - 1, -1, -1):
|
for i in range(n - 1, -1, -1):
|
||||||
d = digit(nums[i], exp)
|
d = digit(nums[i], exp)
|
||||||
j = counter[d] - 1 # 获取 d 在数组中的索引 j
|
j = counter[d] - 1 # 获取 d 在数组中的索引 j
|
||||||
res[j] = nums[i] # 将当前元素填入索引 j
|
res[j] = nums[i] # 将当前元素填入索引 j
|
||||||
counter[d] -= 1 # 将 d 的数量减 1
|
counter[d] -= 1 # 将 d 的数量减 1
|
||||||
# 使用结果覆盖原数组 nums
|
# 使用结果覆盖原数组 nums
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
nums[i] = res[i]
|
nums[i] = res[i]
|
||||||
|
|
||||||
|
|
||||||
def radix_sort(nums: list[int]) -> None:
|
def radix_sort(nums: list[int]) -> None:
|
||||||
""" 基数排序 """
|
"""基数排序"""
|
||||||
# 获取数组的最大元素,用于判断最大位数
|
# 获取数组的最大元素,用于判断最大位数
|
||||||
m = max(nums)
|
m = max(nums)
|
||||||
# 按照从低位到高位的顺序遍历
|
# 按照从低位到高位的顺序遍历
|
||||||
@ -47,10 +49,21 @@ def radix_sort(nums: list[int]) -> None:
|
|||||||
counting_sort_digit(nums, exp)
|
counting_sort_digit(nums, exp)
|
||||||
exp *= 10
|
exp *= 10
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
# 基数排序
|
# 基数排序
|
||||||
nums = [10546151, 35663510, 42865989, 34862445, 81883077,
|
nums = [
|
||||||
88906420, 72429244, 30524779, 82060337, 63832996]
|
10546151,
|
||||||
|
35663510,
|
||||||
|
42865989,
|
||||||
|
34862445,
|
||||||
|
81883077,
|
||||||
|
88906420,
|
||||||
|
72429244,
|
||||||
|
30524779,
|
||||||
|
82060337,
|
||||||
|
63832996,
|
||||||
|
]
|
||||||
radix_sort(nums)
|
radix_sort(nums)
|
||||||
print("基数排序完成后 nums =", nums)
|
print("基数排序完成后 nums =", nums)
|
||||||
|
@ -4,35 +4,37 @@ Created Time: 2023-03-01
|
|||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ArrayDeque:
|
class ArrayDeque:
|
||||||
""" 基于环形数组实现的双向队列 """
|
"""基于环形数组实现的双向队列"""
|
||||||
|
|
||||||
def __init__(self, capacity: int) -> None:
|
def __init__(self, capacity: int) -> None:
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.__nums: list[int] = [0] * capacity
|
self.__nums: list[int] = [0] * capacity
|
||||||
self.__front: int = 0
|
self.__front: int = 0
|
||||||
self.__size: int = 0
|
self.__size: int = 0
|
||||||
|
|
||||||
def capacity(self) -> int:
|
def capacity(self) -> int:
|
||||||
""" 获取双向队列的容量 """
|
"""获取双向队列的容量"""
|
||||||
return len(self.__nums)
|
return len(self.__nums)
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取双向队列的长度 """
|
"""获取双向队列的长度"""
|
||||||
return self.__size
|
return self.__size
|
||||||
|
|
||||||
def is_empty(self) -> bool:
|
def is_empty(self) -> bool:
|
||||||
""" 判断双向队列是否为空 """
|
"""判断双向队列是否为空"""
|
||||||
return self.__size == 0
|
return self.__size == 0
|
||||||
|
|
||||||
def index(self, i: int) -> int:
|
def index(self, i: int) -> int:
|
||||||
""" 计算环形数组索引 """
|
"""计算环形数组索引"""
|
||||||
# 通过取余操作实现数组首尾相连
|
# 通过取余操作实现数组首尾相连
|
||||||
# 当 i 越过数组尾部后,回到头部
|
# 当 i 越过数组尾部后,回到头部
|
||||||
# 当 i 越过数组头部后,回到尾部
|
# 当 i 越过数组头部后,回到尾部
|
||||||
return (i + self.capacity()) % self.capacity()
|
return (i + self.capacity()) % self.capacity()
|
||||||
|
|
||||||
def push_first(self, num: int) -> None:
|
def push_first(self, num: int) -> None:
|
||||||
""" 队首入队 """
|
"""队首入队"""
|
||||||
if self.__size == self.capacity():
|
if self.__size == self.capacity():
|
||||||
print("双向队列已满")
|
print("双向队列已满")
|
||||||
return
|
return
|
||||||
@ -44,7 +46,7 @@ class ArrayDeque:
|
|||||||
self.__size += 1
|
self.__size += 1
|
||||||
|
|
||||||
def push_last(self, num: int) -> None:
|
def push_last(self, num: int) -> None:
|
||||||
""" 队尾入队 """
|
"""队尾入队"""
|
||||||
if self.__size == self.capacity():
|
if self.__size == self.capacity():
|
||||||
print("双向队列已满")
|
print("双向队列已满")
|
||||||
return
|
return
|
||||||
@ -55,7 +57,7 @@ class ArrayDeque:
|
|||||||
self.__size += 1
|
self.__size += 1
|
||||||
|
|
||||||
def pop_first(self) -> int:
|
def pop_first(self) -> int:
|
||||||
""" 队首出队 """
|
"""队首出队"""
|
||||||
num = self.peek_first()
|
num = self.peek_first()
|
||||||
# 队首指针向后移动一位
|
# 队首指针向后移动一位
|
||||||
self.__front = self.index(self.__front + 1)
|
self.__front = self.index(self.__front + 1)
|
||||||
@ -63,25 +65,25 @@ class ArrayDeque:
|
|||||||
return num
|
return num
|
||||||
|
|
||||||
def pop_last(self) -> int:
|
def pop_last(self) -> int:
|
||||||
""" 队尾出队 """
|
"""队尾出队"""
|
||||||
num = self.peek_last()
|
num = self.peek_last()
|
||||||
self.__size -= 1
|
self.__size -= 1
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def peek_first(self) -> int:
|
def peek_first(self) -> int:
|
||||||
""" 访问队首元素 """
|
"""访问队首元素"""
|
||||||
assert not self.is_empty(), "双向队列为空"
|
assert not self.is_empty(), "双向队列为空"
|
||||||
return self.__nums[self.__front]
|
return self.__nums[self.__front]
|
||||||
|
|
||||||
def peek_last(self) -> int:
|
def peek_last(self) -> int:
|
||||||
""" 访问队尾元素 """
|
"""访问队尾元素"""
|
||||||
assert not self.is_empty(), "双向队列为空"
|
assert not self.is_empty(), "双向队列为空"
|
||||||
# 计算尾元素索引
|
# 计算尾元素索引
|
||||||
last = self.index(self.__front + self.__size - 1)
|
last = self.index(self.__front + self.__size - 1)
|
||||||
return self.__nums[last]
|
return self.__nums[last]
|
||||||
|
|
||||||
def to_array(self) -> list[int]:
|
def to_array(self) -> list[int]:
|
||||||
""" 返回数组用于打印 """
|
"""返回数组用于打印"""
|
||||||
# 仅转换有效长度范围内的列表元素
|
# 仅转换有效长度范围内的列表元素
|
||||||
res = []
|
res = []
|
||||||
for i in range(self.__size):
|
for i in range(self.__size):
|
||||||
@ -91,35 +93,35 @@ class ArrayDeque:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化双向队列 """
|
# 初始化双向队列
|
||||||
deque = ArrayDeque(10)
|
deque = ArrayDeque(10)
|
||||||
deque.push_last(3)
|
deque.push_last(3)
|
||||||
deque.push_last(2)
|
deque.push_last(2)
|
||||||
deque.push_last(5)
|
deque.push_last(5)
|
||||||
print("双向队列 deque =", deque.to_array())
|
print("双向队列 deque =", deque.to_array())
|
||||||
|
|
||||||
""" 访问元素 """
|
# 访问元素
|
||||||
peek_first: int = deque.peek_first()
|
peek_first: int = deque.peek_first()
|
||||||
print("队首元素 peek_first =", peek_first)
|
print("队首元素 peek_first =", peek_first)
|
||||||
peek_last: int = deque.peek_last()
|
peek_last: int = deque.peek_last()
|
||||||
print("队尾元素 peek_last =", peek_last)
|
print("队尾元素 peek_last =", peek_last)
|
||||||
|
|
||||||
""" 元素入队 """
|
# 元素入队
|
||||||
deque.push_last(4)
|
deque.push_last(4)
|
||||||
print("元素 4 队尾入队后 deque =", deque.to_array())
|
print("元素 4 队尾入队后 deque =", deque.to_array())
|
||||||
deque.push_first(1)
|
deque.push_first(1)
|
||||||
print("元素 1 队首入队后 deque =", deque.to_array())
|
print("元素 1 队首入队后 deque =", deque.to_array())
|
||||||
|
|
||||||
""" 元素出队 """
|
# 元素出队
|
||||||
pop_last: int = deque.pop_last()
|
pop_last: int = deque.pop_last()
|
||||||
print("队尾出队元素 =", pop_last, ",队尾出队后 deque =", deque.to_array())
|
print("队尾出队元素 =", pop_last, ",队尾出队后 deque =", deque.to_array())
|
||||||
pop_first: int = deque.pop_first()
|
pop_first: int = deque.pop_first()
|
||||||
print("队首出队元素 =", pop_first, ",队首出队后 deque =", deque.to_array())
|
print("队首出队元素 =", pop_first, ",队首出队后 deque =", deque.to_array())
|
||||||
|
|
||||||
""" 获取双向队列的长度 """
|
# 获取双向队列的长度
|
||||||
size: int = deque.size()
|
size: int = deque.size()
|
||||||
print("双向队列长度 size =", size)
|
print("双向队列长度 size =", size)
|
||||||
|
|
||||||
""" 判断双向队列是否为空 """
|
# 判断双向队列是否为空
|
||||||
is_empty: bool = deque.is_empty()
|
is_empty: bool = deque.is_empty()
|
||||||
print("双向队列是否为空 =", is_empty)
|
print("双向队列是否为空 =", is_empty)
|
||||||
|
@ -4,28 +4,30 @@ Created Time: 2022-12-01
|
|||||||
Author: Peng Chen (pengchzn@gmail.com)
|
Author: Peng Chen (pengchzn@gmail.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ArrayQueue:
|
class ArrayQueue:
|
||||||
""" 基于环形数组实现的队列 """
|
"""基于环形数组实现的队列"""
|
||||||
|
|
||||||
def __init__(self, size: int) -> None:
|
def __init__(self, size: int) -> None:
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.__nums: list[int] = [0] * size # 用于存储队列元素的数组
|
self.__nums: list[int] = [0] * size # 用于存储队列元素的数组
|
||||||
self.__front: int = 0 # 队首指针,指向队首元素
|
self.__front: int = 0 # 队首指针,指向队首元素
|
||||||
self.__size: int = 0 # 队列长度
|
self.__size: int = 0 # 队列长度
|
||||||
|
|
||||||
def capacity(self) -> int:
|
def capacity(self) -> int:
|
||||||
""" 获取队列的容量 """
|
"""获取队列的容量"""
|
||||||
return len(self.__nums)
|
return len(self.__nums)
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取队列的长度 """
|
"""获取队列的长度"""
|
||||||
return self.__size
|
return self.__size
|
||||||
|
|
||||||
def is_empty(self) -> bool:
|
def is_empty(self) -> bool:
|
||||||
""" 判断队列是否为空 """
|
"""判断队列是否为空"""
|
||||||
return self.__size == 0
|
return self.__size == 0
|
||||||
|
|
||||||
def push(self, num: int) -> None:
|
def push(self, num: int) -> None:
|
||||||
""" 入队 """
|
"""入队"""
|
||||||
assert self.__size < self.capacity(), "队列已满"
|
assert self.__size < self.capacity(), "队列已满"
|
||||||
# 计算尾指针,指向队尾索引 + 1
|
# 计算尾指针,指向队尾索引 + 1
|
||||||
# 通过取余操作,实现 rear 越过数组尾部后回到头部
|
# 通过取余操作,实现 rear 越过数组尾部后回到头部
|
||||||
@ -35,7 +37,7 @@ class ArrayQueue:
|
|||||||
self.__size += 1
|
self.__size += 1
|
||||||
|
|
||||||
def pop(self) -> int:
|
def pop(self) -> int:
|
||||||
""" 出队 """
|
"""出队"""
|
||||||
num: int = self.peek()
|
num: int = self.peek()
|
||||||
# 队首指针向后移动一位,若越过尾部则返回到数组头部
|
# 队首指针向后移动一位,若越过尾部则返回到数组头部
|
||||||
self.__front = (self.__front + 1) % self.capacity()
|
self.__front = (self.__front + 1) % self.capacity()
|
||||||
@ -43,12 +45,12 @@ class ArrayQueue:
|
|||||||
return num
|
return num
|
||||||
|
|
||||||
def peek(self) -> int:
|
def peek(self) -> int:
|
||||||
""" 访问队首元素 """
|
"""访问队首元素"""
|
||||||
assert not self.is_empty(), "队列为空"
|
assert not self.is_empty(), "队列为空"
|
||||||
return self.__nums[self.__front]
|
return self.__nums[self.__front]
|
||||||
|
|
||||||
def to_list(self) -> list[int]:
|
def to_list(self) -> list[int]:
|
||||||
""" 返回列表用于打印 """
|
"""返回列表用于打印"""
|
||||||
res: list[int] = [0] * self.size()
|
res: list[int] = [0] * self.size()
|
||||||
j: int = self.__front
|
j: int = self.__front
|
||||||
for i in range(self.size()):
|
for i in range(self.size()):
|
||||||
@ -59,10 +61,10 @@ class ArrayQueue:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化队列 """
|
# 初始化队列
|
||||||
queue = ArrayQueue(10)
|
queue = ArrayQueue(10)
|
||||||
|
|
||||||
""" 元素入队 """
|
# 元素入队
|
||||||
queue.push(1)
|
queue.push(1)
|
||||||
queue.push(3)
|
queue.push(3)
|
||||||
queue.push(2)
|
queue.push(2)
|
||||||
@ -70,24 +72,24 @@ if __name__ == "__main__":
|
|||||||
queue.push(4)
|
queue.push(4)
|
||||||
print("队列 queue =", queue.to_list())
|
print("队列 queue =", queue.to_list())
|
||||||
|
|
||||||
""" 访问队首元素 """
|
# 访问队首元素
|
||||||
peek: int = queue.peek()
|
peek: int = queue.peek()
|
||||||
print("队首元素 peek =", peek)
|
print("队首元素 peek =", peek)
|
||||||
|
|
||||||
""" 元素出队 """
|
# 元素出队
|
||||||
pop: int = queue.pop()
|
pop: int = queue.pop()
|
||||||
print("出队元素 pop =", pop)
|
print("出队元素 pop =", pop)
|
||||||
print("出队后 queue =", queue.to_list())
|
print("出队后 queue =", queue.to_list())
|
||||||
|
|
||||||
""" 获取队列的长度 """
|
# 获取队列的长度
|
||||||
size: int = queue.size()
|
size: int = queue.size()
|
||||||
print("队列长度 size =", size)
|
print("队列长度 size =", size)
|
||||||
|
|
||||||
""" 判断队列是否为空 """
|
# 判断队列是否为空
|
||||||
is_empty: bool = queue.is_empty()
|
is_empty: bool = queue.is_empty()
|
||||||
print("队列是否为空 =", is_empty)
|
print("队列是否为空 =", is_empty)
|
||||||
|
|
||||||
""" 测试环形数组 """
|
# 测试环形数组
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
queue.push(i)
|
queue.push(i)
|
||||||
queue.pop()
|
queue.pop()
|
||||||
|
@ -4,45 +4,47 @@ Created Time: 2022-11-29
|
|||||||
Author: Peng Chen (pengchzn@gmail.com)
|
Author: Peng Chen (pengchzn@gmail.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ArrayStack:
|
class ArrayStack:
|
||||||
""" 基于数组实现的栈 """
|
"""基于数组实现的栈"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.__stack: list[int] = []
|
self.__stack: list[int] = []
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取栈的长度 """
|
"""获取栈的长度"""
|
||||||
return len(self.__stack)
|
return len(self.__stack)
|
||||||
|
|
||||||
def is_empty(self) -> bool:
|
def is_empty(self) -> bool:
|
||||||
""" 判断栈是否为空 """
|
"""判断栈是否为空"""
|
||||||
return self.__stack == []
|
return self.__stack == []
|
||||||
|
|
||||||
def push(self, item: int) -> None:
|
def push(self, item: int) -> None:
|
||||||
""" 入栈 """
|
"""入栈"""
|
||||||
self.__stack.append(item)
|
self.__stack.append(item)
|
||||||
|
|
||||||
def pop(self) -> int:
|
def pop(self) -> int:
|
||||||
""" 出栈 """
|
"""出栈"""
|
||||||
assert not self.is_empty(), "栈为空"
|
assert not self.is_empty(), "栈为空"
|
||||||
return self.__stack.pop()
|
return self.__stack.pop()
|
||||||
|
|
||||||
def peek(self) -> int:
|
def peek(self) -> int:
|
||||||
""" 访问栈顶元素 """
|
"""访问栈顶元素"""
|
||||||
assert not self.is_empty(), "栈为空"
|
assert not self.is_empty(), "栈为空"
|
||||||
return self.__stack[-1]
|
return self.__stack[-1]
|
||||||
|
|
||||||
def to_list(self) -> list[int]:
|
def to_list(self) -> list[int]:
|
||||||
""" 返回列表用于打印 """
|
"""返回列表用于打印"""
|
||||||
return self.__stack
|
return self.__stack
|
||||||
|
|
||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化栈 """
|
# 初始化栈
|
||||||
stack = ArrayStack()
|
stack = ArrayStack()
|
||||||
|
|
||||||
""" 元素入栈 """
|
# 元素入栈
|
||||||
stack.push(1)
|
stack.push(1)
|
||||||
stack.push(3)
|
stack.push(3)
|
||||||
stack.push(2)
|
stack.push(2)
|
||||||
@ -50,19 +52,19 @@ if __name__ == "__main__":
|
|||||||
stack.push(4)
|
stack.push(4)
|
||||||
print("栈 stack =", stack.to_list())
|
print("栈 stack =", stack.to_list())
|
||||||
|
|
||||||
""" 访问栈顶元素 """
|
# 访问栈顶元素
|
||||||
peek: int = stack.peek()
|
peek: int = stack.peek()
|
||||||
print("栈顶元素 peek =", peek)
|
print("栈顶元素 peek =", peek)
|
||||||
|
|
||||||
""" 元素出栈 """
|
# 元素出栈
|
||||||
pop: int = stack.pop()
|
pop: int = stack.pop()
|
||||||
print("出栈元素 pop =", pop)
|
print("出栈元素 pop =", pop)
|
||||||
print("出栈后 stack =", stack.to_list())
|
print("出栈后 stack =", stack.to_list())
|
||||||
|
|
||||||
""" 获取栈的长度 """
|
# 获取栈的长度
|
||||||
size: int = stack.size()
|
size: int = stack.size()
|
||||||
print("栈的长度 size =", size)
|
print("栈的长度 size =", size)
|
||||||
|
|
||||||
""" 判断是否为空 """
|
# 判断是否为空
|
||||||
is_empty: bool = stack.is_empty()
|
is_empty: bool = stack.is_empty()
|
||||||
print("栈是否为空 =", is_empty)
|
print("栈是否为空 =", is_empty)
|
||||||
|
@ -8,35 +8,35 @@ from collections import deque
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化双向队列 """
|
# 初始化双向队列
|
||||||
deq: deque[int] = deque()
|
deq: deque[int] = deque()
|
||||||
|
|
||||||
""" 元素入队 """
|
# 元素入队
|
||||||
deq.append(2) # 添加至队尾
|
deq.append(2) # 添加至队尾
|
||||||
deq.append(5)
|
deq.append(5)
|
||||||
deq.append(4)
|
deq.append(4)
|
||||||
deq.appendleft(3) # 添加至队首
|
deq.appendleft(3) # 添加至队首
|
||||||
deq.appendleft(1)
|
deq.appendleft(1)
|
||||||
print("双向队列 deque =", deq)
|
print("双向队列 deque =", deq)
|
||||||
|
|
||||||
""" 访问元素 """
|
# 访问元素
|
||||||
front: int = deq[0] # 队首元素
|
front: int = deq[0] # 队首元素
|
||||||
print("队首元素 front =", front)
|
print("队首元素 front =", front)
|
||||||
rear: int = deq[-1] # 队尾元素
|
rear: int = deq[-1] # 队尾元素
|
||||||
print("队尾元素 rear =", rear)
|
print("队尾元素 rear =", rear)
|
||||||
|
|
||||||
""" 元素出队 """
|
# 元素出队
|
||||||
pop_front: int = deq.popleft() # 队首元素出队
|
pop_front: int = deq.popleft() # 队首元素出队
|
||||||
print("队首出队元素 pop_front =", pop_front)
|
print("队首出队元素 pop_front =", pop_front)
|
||||||
print("队首出队后 deque =", deq)
|
print("队首出队后 deque =", deq)
|
||||||
pop_rear: int = deq.pop() # 队尾元素出队
|
pop_rear: int = deq.pop() # 队尾元素出队
|
||||||
print("队尾出队元素 pop_rear =", pop_rear)
|
print("队尾出队元素 pop_rear =", pop_rear)
|
||||||
print("队尾出队后 deque =", deq)
|
print("队尾出队后 deque =", deq)
|
||||||
|
|
||||||
""" 获取双向队列的长度 """
|
# 获取双向队列的长度
|
||||||
size: int = len(deq)
|
size: int = len(deq)
|
||||||
print("双向队列长度 size =", size)
|
print("双向队列长度 size =", size)
|
||||||
|
|
||||||
""" 判断双向队列是否为空 """
|
# 判断双向队列是否为空
|
||||||
is_empty: bool = len(deq) == 0
|
is_empty: bool = len(deq) == 0
|
||||||
print("双向队列是否为空 =", is_empty)
|
print("双向队列是否为空 =", is_empty)
|
||||||
|
@ -4,32 +4,36 @@ Created Time: 2023-03-01
|
|||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ListNode:
|
class ListNode:
|
||||||
""" 双向链表节点 """
|
"""双向链表节点"""
|
||||||
|
|
||||||
def __init__(self, val: int) -> None:
|
def __init__(self, val: int) -> None:
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.val: int = val
|
self.val: int = val
|
||||||
self.next: ListNode | None = None # 后继节点引用(指针)
|
self.next: ListNode | None = None # 后继节点引用(指针)
|
||||||
self.prev: ListNode | None = None # 前驱节点引用(指针)
|
self.prev: ListNode | None = None # 前驱节点引用(指针)
|
||||||
|
|
||||||
|
|
||||||
class LinkedListDeque:
|
class LinkedListDeque:
|
||||||
""" 基于双向链表实现的双向队列 """
|
"""基于双向链表实现的双向队列"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.front: ListNode | None = None # 头节点 front
|
self.front: ListNode | None = None # 头节点 front
|
||||||
self.rear: ListNode | None = None # 尾节点 rear
|
self.rear: ListNode | None = None # 尾节点 rear
|
||||||
self.__size: int = 0 # 双向队列的长度
|
self.__size: int = 0 # 双向队列的长度
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取双向队列的长度 """
|
"""获取双向队列的长度"""
|
||||||
return self.__size
|
return self.__size
|
||||||
|
|
||||||
def is_empty(self) -> bool:
|
def is_empty(self) -> bool:
|
||||||
""" 判断双向队列是否为空 """
|
"""判断双向队列是否为空"""
|
||||||
return self.size() == 0
|
return self.size() == 0
|
||||||
|
|
||||||
def push(self, num: int, is_front: bool) -> None:
|
def push(self, num: int, is_front: bool) -> None:
|
||||||
""" 入队操作 """
|
"""入队操作"""
|
||||||
node = ListNode(num)
|
node = ListNode(num)
|
||||||
# 若链表为空,则令 front, rear 都指向 node
|
# 若链表为空,则令 front, rear 都指向 node
|
||||||
if self.is_empty():
|
if self.is_empty():
|
||||||
@ -49,15 +53,15 @@ class LinkedListDeque:
|
|||||||
self.__size += 1 # 更新队列长度
|
self.__size += 1 # 更新队列长度
|
||||||
|
|
||||||
def push_first(self, num: int) -> None:
|
def push_first(self, num: int) -> None:
|
||||||
""" 队首入队 """
|
"""队首入队"""
|
||||||
self.push(num, True)
|
self.push(num, True)
|
||||||
|
|
||||||
def push_last(self, num: int) -> None:
|
def push_last(self, num: int) -> None:
|
||||||
""" 队尾入队 """
|
"""队尾入队"""
|
||||||
self.push(num, False)
|
self.push(num, False)
|
||||||
|
|
||||||
def pop(self, is_front: bool) -> int:
|
def pop(self, is_front: bool) -> int:
|
||||||
""" 出队操作 """
|
"""出队操作"""
|
||||||
# 若队列为空,直接返回 None
|
# 若队列为空,直接返回 None
|
||||||
if self.is_empty():
|
if self.is_empty():
|
||||||
return None
|
return None
|
||||||
@ -83,23 +87,23 @@ class LinkedListDeque:
|
|||||||
return val
|
return val
|
||||||
|
|
||||||
def pop_first(self) -> int:
|
def pop_first(self) -> int:
|
||||||
""" 队首出队 """
|
"""队首出队"""
|
||||||
return self.pop(True)
|
return self.pop(True)
|
||||||
|
|
||||||
def pop_last(self) -> int:
|
def pop_last(self) -> int:
|
||||||
""" 队尾出队 """
|
"""队尾出队"""
|
||||||
return self.pop(False)
|
return self.pop(False)
|
||||||
|
|
||||||
def peek_first(self) -> int:
|
def peek_first(self) -> int:
|
||||||
""" 访问队首元素 """
|
"""访问队首元素"""
|
||||||
return None if self.is_empty() else self.front.val
|
return None if self.is_empty() else self.front.val
|
||||||
|
|
||||||
def peek_last(self) -> int:
|
def peek_last(self) -> int:
|
||||||
""" 访问队尾元素 """
|
"""访问队尾元素"""
|
||||||
return None if self.is_empty() else self.rear.val
|
return None if self.is_empty() else self.rear.val
|
||||||
|
|
||||||
def to_array(self) -> list[int]:
|
def to_array(self) -> list[int]:
|
||||||
""" 返回数组用于打印 """
|
"""返回数组用于打印"""
|
||||||
node: ListNode | None = self.front
|
node: ListNode | None = self.front
|
||||||
res: list[int] = [0] * self.size()
|
res: list[int] = [0] * self.size()
|
||||||
for i in range(self.size()):
|
for i in range(self.size()):
|
||||||
@ -110,35 +114,35 @@ class LinkedListDeque:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化双向队列 """
|
# 初始化双向队列
|
||||||
deque = LinkedListDeque()
|
deque = LinkedListDeque()
|
||||||
deque.push_last(3)
|
deque.push_last(3)
|
||||||
deque.push_last(2)
|
deque.push_last(2)
|
||||||
deque.push_last(5)
|
deque.push_last(5)
|
||||||
print("双向队列 deque =", deque.to_array())
|
print("双向队列 deque =", deque.to_array())
|
||||||
|
|
||||||
""" 访问元素 """
|
# 访问元素
|
||||||
peek_first: int = deque.peek_first()
|
peek_first: int = deque.peek_first()
|
||||||
print("队首元素 peek_first =", peek_first)
|
print("队首元素 peek_first =", peek_first)
|
||||||
peek_last: int = deque.peek_last()
|
peek_last: int = deque.peek_last()
|
||||||
print("队尾元素 peek_last =", peek_last)
|
print("队尾元素 peek_last =", peek_last)
|
||||||
|
|
||||||
""" 元素入队 """
|
# 元素入队
|
||||||
deque.push_last(4)
|
deque.push_last(4)
|
||||||
print("元素 4 队尾入队后 deque =", deque.to_array())
|
print("元素 4 队尾入队后 deque =", deque.to_array())
|
||||||
deque.push_first(1)
|
deque.push_first(1)
|
||||||
print("元素 1 队首入队后 deque =", deque.to_array())
|
print("元素 1 队首入队后 deque =", deque.to_array())
|
||||||
|
|
||||||
""" 元素出队 """
|
# 元素出队
|
||||||
pop_last: int = deque.pop_last()
|
pop_last: int = deque.pop_last()
|
||||||
print("队尾出队元素 =", pop_last, ",队尾出队后 deque =", deque.to_array())
|
print("队尾出队元素 =", pop_last, ",队尾出队后 deque =", deque.to_array())
|
||||||
pop_first: int = deque.pop_first()
|
pop_first: int = deque.pop_first()
|
||||||
print("队首出队元素 =", pop_first, ",队首出队后 deque =", deque.to_array())
|
print("队首出队元素 =", pop_first, ",队首出队后 deque =", deque.to_array())
|
||||||
|
|
||||||
""" 获取双向队列的长度 """
|
# 获取双向队列的长度
|
||||||
size: int = deque.size()
|
size: int = deque.size()
|
||||||
print("双向队列长度 size =", size)
|
print("双向队列长度 size =", size)
|
||||||
|
|
||||||
""" 判断双向队列是否为空 """
|
# 判断双向队列是否为空
|
||||||
is_empty: bool = deque.is_empty()
|
is_empty: bool = deque.is_empty()
|
||||||
print("双向队列是否为空 =", is_empty)
|
print("双向队列是否为空 =", is_empty)
|
||||||
|
@ -5,27 +5,30 @@ Author: Peng Chen (pengchzn@gmail.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
class LinkedListQueue:
|
class LinkedListQueue:
|
||||||
""" 基于链表实现的队列 """
|
"""基于链表实现的队列"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.__front: ListNode | None = None # 头节点 front
|
self.__front: ListNode | None = None # 头节点 front
|
||||||
self.__rear: ListNode | None = None # 尾节点 rear
|
self.__rear: ListNode | None = None # 尾节点 rear
|
||||||
self.__size: int = 0
|
self.__size: int = 0
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取队列的长度 """
|
"""获取队列的长度"""
|
||||||
return self.__size
|
return self.__size
|
||||||
|
|
||||||
def is_empty(self) -> bool:
|
def is_empty(self) -> bool:
|
||||||
""" 判断队列是否为空 """
|
"""判断队列是否为空"""
|
||||||
return not self.__front
|
return not self.__front
|
||||||
|
|
||||||
def push(self, num: int) -> None:
|
def push(self, num: int) -> None:
|
||||||
""" 入队 """
|
"""入队"""
|
||||||
# 尾节点后添加 num
|
# 尾节点后添加 num
|
||||||
node = ListNode(num)
|
node = ListNode(num)
|
||||||
# 如果队列为空,则令头、尾节点都指向该节点
|
# 如果队列为空,则令头、尾节点都指向该节点
|
||||||
@ -39,7 +42,7 @@ class LinkedListQueue:
|
|||||||
self.__size += 1
|
self.__size += 1
|
||||||
|
|
||||||
def pop(self) -> int:
|
def pop(self) -> int:
|
||||||
""" 出队 """
|
"""出队"""
|
||||||
num = self.peek()
|
num = self.peek()
|
||||||
# 删除头节点
|
# 删除头节点
|
||||||
self.__front = self.__front.next
|
self.__front = self.__front.next
|
||||||
@ -47,14 +50,14 @@ class LinkedListQueue:
|
|||||||
return num
|
return num
|
||||||
|
|
||||||
def peek(self) -> int:
|
def peek(self) -> int:
|
||||||
""" 访问队首元素 """
|
"""访问队首元素"""
|
||||||
if self.size() == 0:
|
if self.size() == 0:
|
||||||
print("队列为空")
|
print("队列为空")
|
||||||
return False
|
return False
|
||||||
return self.__front.val
|
return self.__front.val
|
||||||
|
|
||||||
def to_list(self) -> list[int]:
|
def to_list(self) -> list[int]:
|
||||||
""" 转化为列表用于打印 """
|
"""转化为列表用于打印"""
|
||||||
queue = []
|
queue = []
|
||||||
temp = self.__front
|
temp = self.__front
|
||||||
while temp:
|
while temp:
|
||||||
@ -65,10 +68,10 @@ class LinkedListQueue:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化队列 """
|
# 初始化队列
|
||||||
queue = LinkedListQueue()
|
queue = LinkedListQueue()
|
||||||
|
|
||||||
""" 元素入队 """
|
# 元素入队
|
||||||
queue.push(1)
|
queue.push(1)
|
||||||
queue.push(3)
|
queue.push(3)
|
||||||
queue.push(2)
|
queue.push(2)
|
||||||
@ -76,19 +79,19 @@ if __name__ == "__main__":
|
|||||||
queue.push(4)
|
queue.push(4)
|
||||||
print("队列 queue =", queue.to_list())
|
print("队列 queue =", queue.to_list())
|
||||||
|
|
||||||
""" 访问队首元素 """
|
# 访问队首元素
|
||||||
peek: int = queue.peek()
|
peek: int = queue.peek()
|
||||||
print("队首元素 front =", peek)
|
print("队首元素 front =", peek)
|
||||||
|
|
||||||
""" 元素出队 """
|
# 元素出队
|
||||||
pop_front: int = queue.pop()
|
pop_front: int = queue.pop()
|
||||||
print("出队元素 pop =", pop_front)
|
print("出队元素 pop =", pop_front)
|
||||||
print("出队后 queue =", queue.to_list())
|
print("出队后 queue =", queue.to_list())
|
||||||
|
|
||||||
""" 获取队列的长度 """
|
# 获取队列的长度
|
||||||
size: int = queue.size()
|
size: int = queue.size()
|
||||||
print("队列长度 size =", size)
|
print("队列长度 size =", size)
|
||||||
|
|
||||||
""" 判断队列是否为空 """
|
# 判断队列是否为空
|
||||||
is_empty: bool = queue.is_empty()
|
is_empty: bool = queue.is_empty()
|
||||||
print("队列是否为空 =", is_empty)
|
print("队列是否为空 =", is_empty)
|
||||||
|
@ -5,46 +5,50 @@ Author: Peng Chen (pengchzn@gmail.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
class LinkedListStack:
|
class LinkedListStack:
|
||||||
""" 基于链表实现的栈 """
|
"""基于链表实现的栈"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.__peek: ListNode | None = None
|
self.__peek: ListNode | None = None
|
||||||
self.__size: int = 0
|
self.__size: int = 0
|
||||||
|
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
""" 获取栈的长度 """
|
"""获取栈的长度"""
|
||||||
return self.__size
|
return self.__size
|
||||||
|
|
||||||
def is_empty(self) -> bool:
|
def is_empty(self) -> bool:
|
||||||
""" 判断栈是否为空 """
|
"""判断栈是否为空"""
|
||||||
return not self.__peek
|
return not self.__peek
|
||||||
|
|
||||||
def push(self, val: int) -> None:
|
def push(self, val: int) -> None:
|
||||||
""" 入栈 """
|
"""入栈"""
|
||||||
node = ListNode(val)
|
node = ListNode(val)
|
||||||
node.next = self.__peek
|
node.next = self.__peek
|
||||||
self.__peek = node
|
self.__peek = node
|
||||||
self.__size += 1
|
self.__size += 1
|
||||||
|
|
||||||
def pop(self) -> int:
|
def pop(self) -> int:
|
||||||
""" 出栈 """
|
"""出栈"""
|
||||||
num: int = self.peek()
|
num: int = self.peek()
|
||||||
self.__peek = self.__peek.next
|
self.__peek = self.__peek.next
|
||||||
self.__size -= 1
|
self.__size -= 1
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def peek(self) -> int:
|
def peek(self) -> int:
|
||||||
""" 访问栈顶元素 """
|
"""访问栈顶元素"""
|
||||||
# 判空处理
|
# 判空处理
|
||||||
if not self.__peek: return None
|
if not self.__peek:
|
||||||
|
return None
|
||||||
return self.__peek.val
|
return self.__peek.val
|
||||||
|
|
||||||
def to_list(self) -> list[int]:
|
def to_list(self) -> list[int]:
|
||||||
""" 转化为列表用于打印 """
|
"""转化为列表用于打印"""
|
||||||
arr: list[int] = []
|
arr: list[int] = []
|
||||||
node = self.__peek
|
node = self.__peek
|
||||||
while node:
|
while node:
|
||||||
@ -56,10 +60,10 @@ class LinkedListStack:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化栈 """
|
# 初始化栈
|
||||||
stack = LinkedListStack()
|
stack = LinkedListStack()
|
||||||
|
|
||||||
""" 元素入栈 """
|
# 元素入栈
|
||||||
stack.push(1)
|
stack.push(1)
|
||||||
stack.push(3)
|
stack.push(3)
|
||||||
stack.push(2)
|
stack.push(2)
|
||||||
@ -67,19 +71,19 @@ if __name__ == "__main__":
|
|||||||
stack.push(4)
|
stack.push(4)
|
||||||
print("栈 stack =", stack.to_list())
|
print("栈 stack =", stack.to_list())
|
||||||
|
|
||||||
""" 访问栈顶元素 """
|
# 访问栈顶元素
|
||||||
peek: int = stack.peek()
|
peek: int = stack.peek()
|
||||||
print("栈顶元素 peek =", peek)
|
print("栈顶元素 peek =", peek)
|
||||||
|
|
||||||
""" 元素出栈 """
|
# 元素出栈
|
||||||
pop: int = stack.pop()
|
pop: int = stack.pop()
|
||||||
print("出栈元素 pop =", pop)
|
print("出栈元素 pop =", pop)
|
||||||
print("出栈后 stack =", stack.to_list())
|
print("出栈后 stack =", stack.to_list())
|
||||||
|
|
||||||
""" 获取栈的长度 """
|
# 获取栈的长度
|
||||||
size: int = stack.size()
|
size: int = stack.size()
|
||||||
print("栈的长度 size =", size)
|
print("栈的长度 size =", size)
|
||||||
|
|
||||||
""" 判断是否为空 """
|
# 判断是否为空
|
||||||
is_empty: bool = stack.is_empty()
|
is_empty: bool = stack.is_empty()
|
||||||
print("栈是否为空 =", is_empty)
|
print("栈是否为空 =", is_empty)
|
||||||
|
@ -8,13 +8,12 @@ from collections import deque
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
# 初始化队列
|
||||||
""" 初始化队列 """
|
|
||||||
# 在 Python 中,我们一般将双向队列类 deque 看作队列使用
|
# 在 Python 中,我们一般将双向队列类 deque 看作队列使用
|
||||||
# 虽然 queue.Queue() 是纯正的队列类,但不太好用
|
# 虽然 queue.Queue() 是纯正的队列类,但不太好用
|
||||||
que: deque[int] = deque()
|
que: deque[int] = deque()
|
||||||
|
|
||||||
""" 元素入队 """
|
# 元素入队
|
||||||
que.append(1)
|
que.append(1)
|
||||||
que.append(3)
|
que.append(3)
|
||||||
que.append(2)
|
que.append(2)
|
||||||
@ -22,19 +21,19 @@ if __name__ == "__main__":
|
|||||||
que.append(4)
|
que.append(4)
|
||||||
print("队列 que =", que)
|
print("队列 que =", que)
|
||||||
|
|
||||||
""" 访问队首元素 """
|
# 访问队首元素
|
||||||
front: int = que[0]
|
front: int = que[0]
|
||||||
print("队首元素 front =", front)
|
print("队首元素 front =", front)
|
||||||
|
|
||||||
""" 元素出队 """
|
# 元素出队
|
||||||
pop: int = que.popleft()
|
pop: int = que.popleft()
|
||||||
print("出队元素 pop =", pop)
|
print("出队元素 pop =", pop)
|
||||||
print("出队后 que =", que)
|
print("出队后 que =", que)
|
||||||
|
|
||||||
""" 获取队列的长度 """
|
# 获取队列的长度
|
||||||
size: int = len(que)
|
size: int = len(que)
|
||||||
print("队列长度 size =", size)
|
print("队列长度 size =", size)
|
||||||
|
|
||||||
""" 判断队列是否为空 """
|
# 判断队列是否为空
|
||||||
is_empty: bool = len(que) == 0
|
is_empty: bool = len(que) == 0
|
||||||
print("队列是否为空 =", is_empty)
|
print("队列是否为空 =", is_empty)
|
||||||
|
@ -6,11 +6,11 @@ Author: Peng Chen (pengchzn@gmail.com)
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化栈 """
|
# 初始化栈
|
||||||
# Python 没有内置的栈类,可以把 list 当作栈来使用
|
# Python 没有内置的栈类,可以把 list 当作栈来使用
|
||||||
stack: list[int] = []
|
stack: list[int] = []
|
||||||
|
|
||||||
""" 元素入栈 """
|
# 元素入栈
|
||||||
stack.append(1)
|
stack.append(1)
|
||||||
stack.append(3)
|
stack.append(3)
|
||||||
stack.append(2)
|
stack.append(2)
|
||||||
@ -18,19 +18,19 @@ if __name__ == "__main__":
|
|||||||
stack.append(4)
|
stack.append(4)
|
||||||
print("栈 stack =", stack)
|
print("栈 stack =", stack)
|
||||||
|
|
||||||
""" 访问栈顶元素 """
|
# 访问栈顶元素
|
||||||
peek: int = stack[-1]
|
peek: int = stack[-1]
|
||||||
print("栈顶元素 peek =", peek)
|
print("栈顶元素 peek =", peek)
|
||||||
|
|
||||||
""" 元素出栈 """
|
# 元素出栈
|
||||||
pop: int = stack.pop()
|
pop: int = stack.pop()
|
||||||
print("出栈元素 pop =", pop)
|
print("出栈元素 pop =", pop)
|
||||||
print("出栈后 stack =", stack)
|
print("出栈后 stack =", stack)
|
||||||
|
|
||||||
""" 获取栈的长度 """
|
# 获取栈的长度
|
||||||
size: int = len(stack)
|
size: int = len(stack)
|
||||||
print("栈的长度 size =", size)
|
print("栈的长度 size =", size)
|
||||||
|
|
||||||
""" 判断是否为空 """
|
# 判断是否为空
|
||||||
is_empty: bool = len(stack) == 0
|
is_empty: bool = len(stack) == 0
|
||||||
print("栈是否为空 =", is_empty)
|
print("栈是否为空 =", is_empty)
|
||||||
|
@ -5,13 +5,16 @@ Author: a16su (lpluls001@gmail.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
class AVLTree:
|
class AVLTree:
|
||||||
""" AVL 树 """
|
"""AVL 树"""
|
||||||
|
|
||||||
def __init__(self, root: TreeNode | None = None):
|
def __init__(self, root: TreeNode | None = None):
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
self.__root = root
|
self.__root = root
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -19,19 +22,19 @@ class AVLTree:
|
|||||||
return self.__root
|
return self.__root
|
||||||
|
|
||||||
def height(self, node: TreeNode | None) -> int:
|
def height(self, node: TreeNode | None) -> int:
|
||||||
""" 获取节点高度 """
|
"""获取节点高度"""
|
||||||
# 空节点高度为 -1 ,叶节点高度为 0
|
# 空节点高度为 -1 ,叶节点高度为 0
|
||||||
if node is not None:
|
if node is not None:
|
||||||
return node.height
|
return node.height
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
def __update_height(self, node: TreeNode | None):
|
def __update_height(self, node: TreeNode | None):
|
||||||
""" 更新节点高度 """
|
"""更新节点高度"""
|
||||||
# 节点高度等于最高子树高度 + 1
|
# 节点高度等于最高子树高度 + 1
|
||||||
node.height = max([self.height(node.left), self.height(node.right)]) + 1
|
node.height = max([self.height(node.left), self.height(node.right)]) + 1
|
||||||
|
|
||||||
def balance_factor(self, node: TreeNode | None) -> int:
|
def balance_factor(self, node: TreeNode | None) -> int:
|
||||||
""" 获取平衡因子 """
|
"""获取平衡因子"""
|
||||||
# 空节点平衡因子为 0
|
# 空节点平衡因子为 0
|
||||||
if node is None:
|
if node is None:
|
||||||
return 0
|
return 0
|
||||||
@ -39,7 +42,7 @@ class AVLTree:
|
|||||||
return self.height(node.left) - self.height(node.right)
|
return self.height(node.left) - self.height(node.right)
|
||||||
|
|
||||||
def __right_rotate(self, node: TreeNode | None) -> TreeNode | None:
|
def __right_rotate(self, node: TreeNode | None) -> TreeNode | None:
|
||||||
""" 右旋操作 """
|
"""右旋操作"""
|
||||||
child = node.left
|
child = node.left
|
||||||
grand_child = child.right
|
grand_child = child.right
|
||||||
# 以 child 为原点,将 node 向右旋转
|
# 以 child 为原点,将 node 向右旋转
|
||||||
@ -52,7 +55,7 @@ class AVLTree:
|
|||||||
return child
|
return child
|
||||||
|
|
||||||
def __left_rotate(self, node: TreeNode | None) -> TreeNode | None:
|
def __left_rotate(self, node: TreeNode | None) -> TreeNode | None:
|
||||||
""" 左旋操作 """
|
"""左旋操作"""
|
||||||
child = node.right
|
child = node.right
|
||||||
grand_child = child.left
|
grand_child = child.left
|
||||||
# 以 child 为原点,将 node 向左旋转
|
# 以 child 为原点,将 node 向左旋转
|
||||||
@ -65,7 +68,7 @@ class AVLTree:
|
|||||||
return child
|
return child
|
||||||
|
|
||||||
def __rotate(self, node: TreeNode | None) -> TreeNode | None:
|
def __rotate(self, node: TreeNode | None) -> TreeNode | None:
|
||||||
""" 执行旋转操作,使该子树重新恢复平衡 """
|
"""执行旋转操作,使该子树重新恢复平衡"""
|
||||||
# 获取节点 node 的平衡因子
|
# 获取节点 node 的平衡因子
|
||||||
balance_factor = self.balance_factor(node)
|
balance_factor = self.balance_factor(node)
|
||||||
# 左偏树
|
# 左偏树
|
||||||
@ -90,12 +93,12 @@ class AVLTree:
|
|||||||
return node
|
return node
|
||||||
|
|
||||||
def insert(self, val) -> TreeNode:
|
def insert(self, val) -> TreeNode:
|
||||||
""" 插入节点 """
|
"""插入节点"""
|
||||||
self.__root = self.__insert_helper(self.__root, val)
|
self.__root = self.__insert_helper(self.__root, val)
|
||||||
return self.__root
|
return self.__root
|
||||||
|
|
||||||
def __insert_helper(self, node: TreeNode | None, val: int) -> TreeNode:
|
def __insert_helper(self, node: TreeNode | None, val: int) -> TreeNode:
|
||||||
""" 递归插入节点(辅助方法)"""
|
"""递归插入节点(辅助方法)"""
|
||||||
if node is None:
|
if node is None:
|
||||||
return TreeNode(val)
|
return TreeNode(val)
|
||||||
# 1. 查找插入位置,并插入节点
|
# 1. 查找插入位置,并插入节点
|
||||||
@ -112,12 +115,12 @@ class AVLTree:
|
|||||||
return self.__rotate(node)
|
return self.__rotate(node)
|
||||||
|
|
||||||
def remove(self, val: int) -> TreeNode | None:
|
def remove(self, val: int) -> TreeNode | None:
|
||||||
""" 删除节点 """
|
"""删除节点"""
|
||||||
self.__root = self.__remove_helper(self.__root, val)
|
self.__root = self.__remove_helper(self.__root, val)
|
||||||
return self.__root
|
return self.__root
|
||||||
|
|
||||||
def __remove_helper(self, node: TreeNode | None, val: int) -> TreeNode | None:
|
def __remove_helper(self, node: TreeNode | None, val: int) -> TreeNode | None:
|
||||||
""" 递归删除节点(辅助方法) """
|
"""递归删除节点(辅助方法)"""
|
||||||
if node is None:
|
if node is None:
|
||||||
return None
|
return None
|
||||||
# 1. 查找节点,并删除之
|
# 1. 查找节点,并删除之
|
||||||
@ -144,7 +147,7 @@ class AVLTree:
|
|||||||
return self.__rotate(node)
|
return self.__rotate(node)
|
||||||
|
|
||||||
def __get_inorder_next(self, node: TreeNode | None) -> TreeNode | None:
|
def __get_inorder_next(self, node: TreeNode | None) -> TreeNode | None:
|
||||||
""" 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) """
|
"""获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况)"""
|
||||||
if node is None:
|
if node is None:
|
||||||
return None
|
return None
|
||||||
# 循环访问左子节点,直到叶节点时为最小节点,跳出
|
# 循环访问左子节点,直到叶节点时为最小节点,跳出
|
||||||
@ -153,7 +156,7 @@ class AVLTree:
|
|||||||
return node
|
return node
|
||||||
|
|
||||||
def search(self, val: int) -> TreeNode | None:
|
def search(self, val: int) -> TreeNode | None:
|
||||||
""" 查找节点 """
|
"""查找节点"""
|
||||||
cur = self.__root
|
cur = self.__root
|
||||||
# 循环查找,越过叶节点后跳出
|
# 循环查找,越过叶节点后跳出
|
||||||
while cur is not None:
|
while cur is not None:
|
||||||
@ -172,6 +175,7 @@ class AVLTree:
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
def test_insert(tree: AVLTree, val: int):
|
def test_insert(tree: AVLTree, val: int):
|
||||||
tree.insert(val)
|
tree.insert(val)
|
||||||
print("\n插入节点 {} 后,AVL 树为".format(val))
|
print("\n插入节点 {} 后,AVL 树为".format(val))
|
||||||
|
@ -5,19 +5,23 @@ Author: a16su (lpluls001@gmail.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
class BinarySearchTree:
|
class BinarySearchTree:
|
||||||
""" 二叉搜索树 """
|
"""二叉搜索树"""
|
||||||
|
|
||||||
def __init__(self, nums: list[int]) -> None:
|
def __init__(self, nums: list[int]) -> None:
|
||||||
""" 构造方法 """
|
"""构造方法"""
|
||||||
nums.sort()
|
nums.sort()
|
||||||
self.__root = self.build_tree(nums, 0, len(nums) - 1)
|
self.__root = self.build_tree(nums, 0, len(nums) - 1)
|
||||||
|
|
||||||
def build_tree(self, nums: list[int], start_index: int, end_index: int) -> TreeNode | None:
|
def build_tree(
|
||||||
""" 构建二叉搜索树 """
|
self, nums: list[int], start_index: int, end_index: int
|
||||||
|
) -> TreeNode | None:
|
||||||
|
"""构建二叉搜索树"""
|
||||||
if start_index > end_index:
|
if start_index > end_index:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -25,8 +29,12 @@ class BinarySearchTree:
|
|||||||
mid: int = (start_index + end_index) // 2
|
mid: int = (start_index + end_index) // 2
|
||||||
root = TreeNode(nums[mid])
|
root = TreeNode(nums[mid])
|
||||||
# 递归建立左子树和右子树
|
# 递归建立左子树和右子树
|
||||||
root.left = self.build_tree(nums=nums, start_index=start_index, end_index=mid - 1)
|
root.left = self.build_tree(
|
||||||
root.right = self.build_tree(nums=nums, start_index=mid + 1, end_index=end_index)
|
nums=nums, start_index=start_index, end_index=mid - 1
|
||||||
|
)
|
||||||
|
root.right = self.build_tree(
|
||||||
|
nums=nums, start_index=mid + 1, end_index=end_index
|
||||||
|
)
|
||||||
return root
|
return root
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -34,7 +42,7 @@ class BinarySearchTree:
|
|||||||
return self.__root
|
return self.__root
|
||||||
|
|
||||||
def search(self, num: int) -> TreeNode | None:
|
def search(self, num: int) -> TreeNode | None:
|
||||||
""" 查找节点 """
|
"""查找节点"""
|
||||||
cur: TreeNode | None = self.__root
|
cur: TreeNode | None = self.__root
|
||||||
# 循环查找,越过叶节点后跳出
|
# 循环查找,越过叶节点后跳出
|
||||||
while cur is not None:
|
while cur is not None:
|
||||||
@ -50,11 +58,11 @@ class BinarySearchTree:
|
|||||||
return cur
|
return cur
|
||||||
|
|
||||||
def insert(self, num: int) -> TreeNode | None:
|
def insert(self, num: int) -> TreeNode | None:
|
||||||
""" 插入节点 """
|
"""插入节点"""
|
||||||
# 若树为空,直接提前返回
|
# 若树为空,直接提前返回
|
||||||
if self.__root is None:
|
if self.__root is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# 循环查找,越过叶节点后跳出
|
# 循环查找,越过叶节点后跳出
|
||||||
cur, pre = self.__root, None
|
cur, pre = self.__root, None
|
||||||
while cur is not None:
|
while cur is not None:
|
||||||
@ -78,7 +86,7 @@ class BinarySearchTree:
|
|||||||
return node
|
return node
|
||||||
|
|
||||||
def remove(self, num: int) -> TreeNode | None:
|
def remove(self, num: int) -> TreeNode | None:
|
||||||
""" 删除节点 """
|
"""删除节点"""
|
||||||
# 若树为空,直接提前返回
|
# 若树为空,直接提前返回
|
||||||
if self.__root is None:
|
if self.__root is None:
|
||||||
return None
|
return None
|
||||||
@ -119,7 +127,7 @@ class BinarySearchTree:
|
|||||||
return cur
|
return cur
|
||||||
|
|
||||||
def get_inorder_next(self, root: TreeNode | None) -> TreeNode | None:
|
def get_inorder_next(self, root: TreeNode | None) -> TreeNode | None:
|
||||||
""" 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) """
|
"""获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况)"""
|
||||||
if root is None:
|
if root is None:
|
||||||
return root
|
return root
|
||||||
# 循环访问左子节点,直到叶节点时为最小节点,跳出
|
# 循环访问左子节点,直到叶节点时为最小节点,跳出
|
||||||
@ -131,7 +139,7 @@ class BinarySearchTree:
|
|||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# 初始化二叉搜索树
|
# 初始化二叉搜索树
|
||||||
nums = list(range(1, 16)) # [1, 2, ..., 15]
|
nums = list(range(1, 16)) # [1, 2, ..., 15]
|
||||||
bst = BinarySearchTree(nums=nums)
|
bst = BinarySearchTree(nums=nums)
|
||||||
print("\n初始化的二叉树为\n")
|
print("\n初始化的二叉树为\n")
|
||||||
print_tree(bst.root)
|
print_tree(bst.root)
|
||||||
|
@ -12,7 +12,7 @@ from modules import *
|
|||||||
|
|
||||||
""" Driver Code """
|
""" Driver Code """
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
""" 初始化二叉树 """
|
# 初始化二叉树
|
||||||
# 初始化节点
|
# 初始化节点
|
||||||
n1 = TreeNode(val=1)
|
n1 = TreeNode(val=1)
|
||||||
n2 = TreeNode(val=2)
|
n2 = TreeNode(val=2)
|
||||||
@ -27,7 +27,7 @@ if __name__ == "__main__":
|
|||||||
print("\n初始化二叉树\n")
|
print("\n初始化二叉树\n")
|
||||||
print_tree(n1)
|
print_tree(n1)
|
||||||
|
|
||||||
""" 插入与删除节点 """
|
# 插入与删除节点
|
||||||
P = TreeNode(0)
|
P = TreeNode(0)
|
||||||
# 在 n1 -> n2 中间插入节点 P
|
# 在 n1 -> n2 中间插入节点 P
|
||||||
n1.left = P
|
n1.left = P
|
||||||
|
@ -5,24 +5,26 @@ Author: a16su (lpluls001@gmail.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
|
||||||
|
|
||||||
def level_order(root: TreeNode | None) -> list[int]:
|
def level_order(root: TreeNode | None) -> list[int]:
|
||||||
""" 层序遍历 """
|
"""层序遍历"""
|
||||||
# 初始化队列,加入根节点
|
# 初始化队列,加入根节点
|
||||||
queue: deque[TreeNode] = deque()
|
queue: deque[TreeNode] = deque()
|
||||||
queue.append(root)
|
queue.append(root)
|
||||||
# 初始化一个列表,用于保存遍历序列
|
# 初始化一个列表,用于保存遍历序列
|
||||||
res: list[int] = []
|
res: list[int] = []
|
||||||
while queue:
|
while queue:
|
||||||
node: TreeNode = queue.popleft() # 队列出队
|
node: TreeNode = queue.popleft() # 队列出队
|
||||||
res.append(node.val) # 保存节点值
|
res.append(node.val) # 保存节点值
|
||||||
if node.left is not None:
|
if node.left is not None:
|
||||||
queue.append(node.left) # 左子节点入队
|
queue.append(node.left) # 左子节点入队
|
||||||
if node.right is not None:
|
if node.right is not None:
|
||||||
queue.append(node.right) # 右子节点入队
|
queue.append(node.right) # 右子节点入队
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,11 +5,13 @@ Author: a16su (lpluls001@gmail.com)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys, os.path as osp
|
import sys, os.path as osp
|
||||||
|
|
||||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||||
from modules import *
|
from modules import *
|
||||||
|
|
||||||
|
|
||||||
def pre_order(root: TreeNode | None) -> None:
|
def pre_order(root: TreeNode | None) -> None:
|
||||||
""" 前序遍历 """
|
"""前序遍历"""
|
||||||
if root is None:
|
if root is None:
|
||||||
return
|
return
|
||||||
# 访问优先级:根节点 -> 左子树 -> 右子树
|
# 访问优先级:根节点 -> 左子树 -> 右子树
|
||||||
@ -17,8 +19,9 @@ def pre_order(root: TreeNode | None) -> None:
|
|||||||
pre_order(root=root.left)
|
pre_order(root=root.left)
|
||||||
pre_order(root=root.right)
|
pre_order(root=root.right)
|
||||||
|
|
||||||
|
|
||||||
def in_order(root: TreeNode | None) -> None:
|
def in_order(root: TreeNode | None) -> None:
|
||||||
""" 中序遍历 """
|
"""中序遍历"""
|
||||||
if root is None:
|
if root is None:
|
||||||
return
|
return
|
||||||
# 访问优先级:左子树 -> 根节点 -> 右子树
|
# 访问优先级:左子树 -> 根节点 -> 右子树
|
||||||
@ -26,8 +29,9 @@ def in_order(root: TreeNode | None) -> None:
|
|||||||
res.append(root.val)
|
res.append(root.val)
|
||||||
in_order(root=root.right)
|
in_order(root=root.right)
|
||||||
|
|
||||||
|
|
||||||
def post_order(root: TreeNode | None) -> None:
|
def post_order(root: TreeNode | None) -> None:
|
||||||
""" 后序遍历 """
|
"""后序遍历"""
|
||||||
if root is None:
|
if root is None:
|
||||||
return
|
return
|
||||||
# 访问优先级:左子树 -> 右子树 -> 根节点
|
# 访问优先级:左子树 -> 右子树 -> 根节点
|
||||||
|
@ -1,8 +1,20 @@
|
|||||||
# Follow the PEP 585 – Type Hinting Generics In Standard Collections
|
# Follow the PEP 585 – Type Hinting Generics In Standard Collections
|
||||||
# https://peps.python.org/pep-0585/
|
# https://peps.python.org/pep-0585/
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
# Import common libs here to simplify the codes by `from module import *`
|
# Import common libs here to simplify the codes by `from module import *`
|
||||||
from .linked_list import ListNode, list_to_linked_list, linked_list_to_list, get_list_node
|
from .linked_list import (
|
||||||
|
ListNode,
|
||||||
|
list_to_linked_list,
|
||||||
|
linked_list_to_list,
|
||||||
|
get_list_node,
|
||||||
|
)
|
||||||
from .binary_tree import TreeNode, list_to_tree, tree_to_list, get_tree_node
|
from .binary_tree import TreeNode, list_to_tree, tree_to_list, get_tree_node
|
||||||
from .vertex import Vertex, vals_to_vets, vets_to_vals
|
from .vertex import Vertex, vals_to_vets, vets_to_vals
|
||||||
from .print_util import print_matrix, print_linked_list, print_tree, print_dict, print_heap
|
from .print_util import (
|
||||||
|
print_matrix,
|
||||||
|
print_linked_list,
|
||||||
|
print_tree,
|
||||||
|
print_dict,
|
||||||
|
print_heap,
|
||||||
|
)
|
||||||
|
@ -6,40 +6,47 @@ Author: Krahets (krahets@163.com)
|
|||||||
|
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
|
||||||
|
|
||||||
class TreeNode:
|
class TreeNode:
|
||||||
""" Definition for a binary tree node """
|
"""Definition for a binary tree node"""
|
||||||
|
|
||||||
def __init__(self, val: int = 0):
|
def __init__(self, val: int = 0):
|
||||||
self.val: int = val # 节点值
|
self.val: int = val # 节点值
|
||||||
self.height: int = 0 # 节点高度
|
self.height: int = 0 # 节点高度
|
||||||
self.left: TreeNode | None = None # 左子节点引用
|
self.left: TreeNode | None = None # 左子节点引用
|
||||||
self.right: TreeNode | None = None # 右子节点引用
|
self.right: TreeNode | None = None # 右子节点引用
|
||||||
|
|
||||||
|
|
||||||
def list_to_tree(arr: list[int]) -> TreeNode | None:
|
def list_to_tree(arr: list[int]) -> TreeNode | None:
|
||||||
""" Generate a binary tree with a list """
|
"""Generate a binary tree with a list"""
|
||||||
if not arr:
|
if not arr:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
i: int = 0
|
i: int = 0
|
||||||
root = TreeNode(arr[0])
|
root = TreeNode(arr[0])
|
||||||
queue: deque[TreeNode] = deque([root])
|
queue: deque[TreeNode] = deque([root])
|
||||||
while queue:
|
while queue:
|
||||||
node: TreeNode = queue.popleft()
|
node: TreeNode = queue.popleft()
|
||||||
i += 1
|
i += 1
|
||||||
if i >= len(arr): break
|
if i >= len(arr):
|
||||||
|
break
|
||||||
if arr[i] != None:
|
if arr[i] != None:
|
||||||
node.left = TreeNode(arr[i])
|
node.left = TreeNode(arr[i])
|
||||||
queue.append(node.left)
|
queue.append(node.left)
|
||||||
i += 1
|
i += 1
|
||||||
if i >= len(arr): break
|
if i >= len(arr):
|
||||||
|
break
|
||||||
if arr[i] != None:
|
if arr[i] != None:
|
||||||
node.right = TreeNode(arr[i])
|
node.right = TreeNode(arr[i])
|
||||||
queue.append(node.right)
|
queue.append(node.right)
|
||||||
|
|
||||||
return root
|
return root
|
||||||
|
|
||||||
|
|
||||||
def tree_to_list(root: TreeNode | None) -> list[int]:
|
def tree_to_list(root: TreeNode | None) -> list[int]:
|
||||||
""" Serialize a tree into an array """
|
"""Serialize a tree into an array"""
|
||||||
if not root: return []
|
if not root:
|
||||||
|
return []
|
||||||
queue: deque[TreeNode] = deque()
|
queue: deque[TreeNode] = deque()
|
||||||
queue.append(root)
|
queue.append(root)
|
||||||
res: list[int] = []
|
res: list[int] = []
|
||||||
@ -49,11 +56,13 @@ def tree_to_list(root: TreeNode | None) -> list[int]:
|
|||||||
res.append(node.val)
|
res.append(node.val)
|
||||||
queue.append(node.left)
|
queue.append(node.left)
|
||||||
queue.append(node.right)
|
queue.append(node.right)
|
||||||
else: res.append(None)
|
else:
|
||||||
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def get_tree_node(root: TreeNode | None, val: int) -> TreeNode | None:
|
def get_tree_node(root: TreeNode | None, val: int) -> TreeNode | None:
|
||||||
""" Get a tree node with specific value in a binary tree """
|
"""Get a tree node with specific value in a binary tree"""
|
||||||
if not root:
|
if not root:
|
||||||
return
|
return
|
||||||
if root.val == val:
|
if root.val == val:
|
||||||
|
@ -4,14 +4,17 @@ Created Time: 2021-12-11
|
|||||||
Author: Krahets (krahets@163.com)
|
Author: Krahets (krahets@163.com)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ListNode:
|
class ListNode:
|
||||||
""" Definition for a singly-linked list node """
|
"""Definition for a singly-linked list node"""
|
||||||
|
|
||||||
def __init__(self, val: int):
|
def __init__(self, val: int):
|
||||||
self.val: int = val # 节点值
|
self.val: int = val # 节点值
|
||||||
self.next: ListNode | None = None # 后继节点引用
|
self.next: ListNode | None = None # 后继节点引用
|
||||||
|
|
||||||
|
|
||||||
def list_to_linked_list(arr: list[int]) -> ListNode | None:
|
def list_to_linked_list(arr: list[int]) -> ListNode | None:
|
||||||
""" Generate a linked list with a list """
|
"""Generate a linked list with a list"""
|
||||||
dum = head = ListNode(0)
|
dum = head = ListNode(0)
|
||||||
for a in arr:
|
for a in arr:
|
||||||
node = ListNode(a)
|
node = ListNode(a)
|
||||||
@ -19,16 +22,18 @@ def list_to_linked_list(arr: list[int]) -> ListNode | None:
|
|||||||
head = head.next
|
head = head.next
|
||||||
return dum.next
|
return dum.next
|
||||||
|
|
||||||
|
|
||||||
def linked_list_to_list(head: ListNode | None) -> list[int]:
|
def linked_list_to_list(head: ListNode | None) -> list[int]:
|
||||||
""" Serialize a linked list into an array """
|
"""Serialize a linked list into an array"""
|
||||||
arr: list[int] = []
|
arr: list[int] = []
|
||||||
while head:
|
while head:
|
||||||
arr.append(head.val)
|
arr.append(head.val)
|
||||||
head = head.next
|
head = head.next
|
||||||
return arr
|
return arr
|
||||||
|
|
||||||
|
|
||||||
def get_list_node(head: ListNode | None, val: int) -> ListNode | None:
|
def get_list_node(head: ListNode | None, val: int) -> ListNode | None:
|
||||||
""" Get a list node with specific value from a linked list """
|
"""Get a list node with specific value from a linked list"""
|
||||||
while head and head.val != val:
|
while head and head.val != val:
|
||||||
head = head.next
|
head = head.next
|
||||||
return head
|
return head
|
||||||
|
@ -7,31 +7,38 @@ Author: Krahets (krahets@163.com), msk397 (machangxinq@gmail.com)
|
|||||||
from .binary_tree import TreeNode, list_to_tree
|
from .binary_tree import TreeNode, list_to_tree
|
||||||
from .linked_list import ListNode, linked_list_to_list
|
from .linked_list import ListNode, linked_list_to_list
|
||||||
|
|
||||||
|
|
||||||
def print_matrix(mat: list[list[int]]) -> None:
|
def print_matrix(mat: list[list[int]]) -> None:
|
||||||
""" Print a matrix """
|
"""Print a matrix"""
|
||||||
s: list[str] = []
|
s: list[str] = []
|
||||||
for arr in mat:
|
for arr in mat:
|
||||||
s.append(' ' + str(arr))
|
s.append(" " + str(arr))
|
||||||
|
|
||||||
|
print("[\n" + ",\n".join(s) + "\n]")
|
||||||
|
|
||||||
print('[\n' + ',\n'.join(s) + '\n]')
|
|
||||||
|
|
||||||
def print_linked_list(head: ListNode | None) -> None:
|
def print_linked_list(head: ListNode | None) -> None:
|
||||||
""" Print a linked list """
|
"""Print a linked list"""
|
||||||
arr: list[int] = linked_list_to_list(head)
|
arr: list[int] = linked_list_to_list(head)
|
||||||
print(' -> '.join([str(a) for a in arr]))
|
print(" -> ".join([str(a) for a in arr]))
|
||||||
|
|
||||||
|
|
||||||
class Trunk:
|
class Trunk:
|
||||||
def __init__(self, prev, string: str | None = None) -> None:
|
def __init__(self, prev, string: str | None = None) -> None:
|
||||||
self.prev = prev
|
self.prev = prev
|
||||||
self.str = string
|
self.str = string
|
||||||
|
|
||||||
|
|
||||||
def show_trunks(p: Trunk | None) -> None:
|
def show_trunks(p: Trunk | None) -> None:
|
||||||
if p is None:
|
if p is None:
|
||||||
return
|
return
|
||||||
show_trunks(p.prev)
|
show_trunks(p.prev)
|
||||||
print(p.str, end='')
|
print(p.str, end="")
|
||||||
|
|
||||||
def print_tree(root: TreeNode | None, prev: Trunk | None = None, is_left: bool = False) -> None:
|
|
||||||
|
def print_tree(
|
||||||
|
root: TreeNode | None, prev: Trunk | None = None, is_left: bool = False
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Print a binary tree
|
Print a binary tree
|
||||||
This tree printer is borrowed from TECHIE DELIGHT
|
This tree printer is borrowed from TECHIE DELIGHT
|
||||||
@ -40,33 +47,35 @@ def print_tree(root: TreeNode | None, prev: Trunk | None = None, is_left: bool =
|
|||||||
if root is None:
|
if root is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
prev_str: str = ' '
|
prev_str: str = " "
|
||||||
trunk = Trunk(prev, prev_str)
|
trunk = Trunk(prev, prev_str)
|
||||||
print_tree(root.right, trunk, True)
|
print_tree(root.right, trunk, True)
|
||||||
|
|
||||||
if prev is None:
|
if prev is None:
|
||||||
trunk.str = '———'
|
trunk.str = "———"
|
||||||
elif is_left:
|
elif is_left:
|
||||||
trunk.str = '/———'
|
trunk.str = "/———"
|
||||||
prev_str = ' |'
|
prev_str = " |"
|
||||||
else:
|
else:
|
||||||
trunk.str = '\———'
|
trunk.str = "\———"
|
||||||
prev.str = prev_str
|
prev.str = prev_str
|
||||||
|
|
||||||
show_trunks(trunk)
|
show_trunks(trunk)
|
||||||
print(' ' + str(root.val))
|
print(" " + str(root.val))
|
||||||
if prev:
|
if prev:
|
||||||
prev.str = prev_str
|
prev.str = prev_str
|
||||||
trunk.str = ' |'
|
trunk.str = " |"
|
||||||
print_tree(root.left, trunk, False)
|
print_tree(root.left, trunk, False)
|
||||||
|
|
||||||
|
|
||||||
def print_dict(mapp: dict) -> None:
|
def print_dict(mapp: dict) -> None:
|
||||||
""" Print a dict """
|
"""Print a dict"""
|
||||||
for key, value in mapp.items():
|
for key, value in mapp.items():
|
||||||
print(key, '->', value)
|
print(key, "->", value)
|
||||||
|
|
||||||
|
|
||||||
def print_heap(heap: list[int]) -> None:
|
def print_heap(heap: list[int]) -> None:
|
||||||
""" Print a heap both in array and tree representations """
|
"""Print a heap both in array and tree representations"""
|
||||||
print("堆的数组表示:", heap)
|
print("堆的数组表示:", heap)
|
||||||
print("堆的树状表示:")
|
print("堆的树状表示:")
|
||||||
root: TreeNode | None = list_to_tree(heap)
|
root: TreeNode | None = list_to_tree(heap)
|
||||||
|
@ -2,15 +2,19 @@
|
|||||||
# Created Time: 2023-02-23
|
# Created Time: 2023-02-23
|
||||||
# Author: Krahets (krahets@163.com)
|
# Author: Krahets (krahets@163.com)
|
||||||
|
|
||||||
|
|
||||||
class Vertex:
|
class Vertex:
|
||||||
""" 顶点类 """
|
"""顶点类"""
|
||||||
|
|
||||||
def __init__(self, val: int) -> None:
|
def __init__(self, val: int) -> None:
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def vals_to_vets(vals: list[int]) -> list['Vertex']:
|
|
||||||
""" 输入值列表 vals ,返回顶点列表 vets """
|
def vals_to_vets(vals: list[int]) -> list["Vertex"]:
|
||||||
|
"""输入值列表 vals ,返回顶点列表 vets"""
|
||||||
return [Vertex(val) for val in vals]
|
return [Vertex(val) for val in vals]
|
||||||
|
|
||||||
def vets_to_vals(vets: list['Vertex']) -> list[int]:
|
|
||||||
""" 输入顶点列表 vets ,返回值列表 vals """
|
def vets_to_vals(vets: list["Vertex"]) -> list[int]:
|
||||||
|
"""输入顶点列表 vets ,返回值列表 vals"""
|
||||||
return [vet.val for vet in vets]
|
return [vet.val for vet in vets]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user