Update code style for Python

This commit is contained in:
krahets 2023-03-03 03:07:22 +08:00
parent 7e9e6b000c
commit 7c501140f0
45 changed files with 274 additions and 266 deletions

View file

@ -132,19 +132,19 @@ class QuickSortTailCall {
/* Driver Code */ /* Driver Code */
/* 快速排序 */ /* 快速排序 */
const nums = [4, 1, 3, 1, 5, 2]; const nums = [2, 4, 1, 0, 3, 5];
const quickSort = new QuickSort(); const quickSort = new QuickSort();
quickSort.quickSort(nums, 0, nums.length - 1); quickSort.quickSort(nums, 0, nums.length - 1);
console.log('快速排序完成后 nums =', nums); console.log('快速排序完成后 nums =', nums);
/* 快速排序(中位基准数优化) */ /* 快速排序(中位基准数优化) */
const nums1 = [4, 1, 3, 1, 5, 2]; const nums1 = [2, 4, 1, 0, 3, 5];
const quickSortMedian = new QuickSort(); const quickSortMedian = new QuickSort();
quickSortMedian.quickSort(nums1, 0, nums1.length - 1); quickSortMedian.quickSort(nums1, 0, nums1.length - 1);
console.log('快速排序(中位基准数优化)完成后 nums =', nums1); console.log('快速排序(中位基准数优化)完成后 nums =', nums1);
/* 快速排序(尾递归优化) */ /* 快速排序(尾递归优化) */
const nums2 = [4, 1, 3, 1, 5, 2]; const nums2 = [2, 4, 1, 0, 3, 5];
const quickSortTailCall = new QuickSort(); const quickSortTailCall = new QuickSort();
quickSortTailCall.quickSort(nums2, 0, nums2.length - 1); quickSortTailCall.quickSort(nums2, 0, nums2.length - 1);
console.log('快速排序(尾递归优化)完成后 nums =', nums2); console.log('快速排序(尾递归优化)完成后 nums =', nums2);

View file

@ -6,20 +6,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 include import * from modules import *
""" 随机访问元素 """
def random_access(nums): def random_access(nums):
""" 随机访问元素 """
# 在区间 [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, enlarge): def extend(nums, enlarge):
""" 扩展数组长度 """
# 初始化一个扩展长度后的数组 # 初始化一个扩展长度后的数组
res = [0] * (len(nums) + enlarge) res = [0] * (len(nums) + enlarge)
# 将原数组中的所有元素复制到新数组 # 将原数组中的所有元素复制到新数组
@ -28,22 +28,22 @@ def extend(nums, enlarge):
# 返回扩展后的新数组 # 返回扩展后的新数组
return res return res
""" 在数组的索引 index 处插入元素 num """
def insert(nums, num, index): def insert(nums, num, index):
""" 在数组的索引 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
""" 删除索引 index 处元素 """
def remove(nums, index): def remove(nums, 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): def traverse(nums):
""" 遍历数组 """
count = 0 count = 0
# 通过索引遍历数组 # 通过索引遍历数组
for i in range(len(nums)): for i in range(len(nums)):
@ -52,8 +52,8 @@ def traverse(nums):
for num in nums: for num in nums:
count += 1 count += 1
""" 在数组中查找指定元素 """
def find(nums, target): def find(nums, target):
""" 在数组中查找指定元素 """
for i in range(len(nums)): for i in range(len(nums)):
if nums[i] == target: if nums[i] == target:
return i return i

View file

@ -6,16 +6,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 include import * from modules import *
""" 在链表的结点 n0 之后插入结点 P """
def insert(n0, P): def insert(n0, P):
""" 在链表的结点 n0 之后插入结点 P """
n1 = n0.next n1 = n0.next
P.next = n1 P.next = n1
n0.next = P n0.next = P
""" 删除链表的结点 n0 之后的首个结点 """
def remove(n0): def remove(n0):
""" 删除链表的结点 n0 之后的首个结点 """
if not n0.next: if not n0.next:
return return
# n0 -> P -> n1 # n0 -> P -> n1
@ -23,16 +23,16 @@ def remove(n0):
n1 = P.next n1 = P.next
n0.next = n1 n0.next = n1
""" 访问链表中索引为 index 的结点 """
def access(head, index): def access(head, 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
""" 在链表中查找值为 target 的首个结点 """
def find(head, target): def find(head, target):
""" 在链表中查找值为 target 的首个结点 """
index = 0 index = 0
while head: while head:
if head.val == target: if head.val == target:

View file

@ -6,7 +6,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 include import * from modules import *
""" Driver Code """ """ Driver Code """

View file

@ -6,42 +6,47 @@ 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 include import * from modules import *
""" 列表类简易实现 """
class MyList: class MyList:
""" 构造方法 """ """ 列表类简易实现 """
def __init__(self): def __init__(self):
""" 构造方法 """
self.__capacity = 10 # 列表容量 self.__capacity = 10 # 列表容量
self.__nums = [0] * self.__capacity # 数组(存储列表元素) self.__nums = [0] * self.__capacity # 数组(存储列表元素)
self.__size = 0 # 列表长度(即当前元素数量) self.__size = 0 # 列表长度(即当前元素数量)
self.__extend_ratio = 2 # 每次列表扩容的倍数 self.__extend_ratio = 2 # 每次列表扩容的倍数
""" 获取列表长度(即当前元素数量) """
def size(self): def size(self):
""" 获取列表长度(即当前元素数量) """
return self.__size return self.__size
""" 获取列表容量 """
def capacity(self): def capacity(self):
""" 获取列表容量 """
return self.__capacity return self.__capacity
""" 访问元素 """
def get(self, index): def get(self, index):
""" 访问元素 """
# 索引如果越界则抛出异常,下同 # 索引如果越界则抛出异常,下同
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, index): def set(self, num, index):
""" 更新元素 """
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):
""" 尾部添加元素 """
# 元素数量超出容量时,触发扩容机制
if self.size() == self.capacity():
self.extend_capacity();
self.__nums[self.__size] = num
self.__size += 1
""" 中间插入(尾部添加)元素 """ def insert(self, num, index):
def add(self, num, index=-1): """ 中间插入元素 """
assert index >= 0 and index < self.__size, "索引越界" assert index >= 0 and index < self.__size, "索引越界"
# 若不指定索引 index ,则向数组尾部添加元素
if index == -1:
index = self.__size
# 元素数量超出容量时,触发扩容机制 # 元素数量超出容量时,触发扩容机制
if self.__size == self.capacity(): if self.__size == self.capacity():
self.extend_capacity() self.extend_capacity()
@ -52,10 +57,10 @@ class MyList:
# 更新元素数量 # 更新元素数量
self.__size += 1 self.__size += 1
""" 删除元素 """
def remove(self, index): def remove(self, index):
""" 删除元素 """
assert index >= 0 and index < self.__size, "索引越界" assert index >= 0 and index < self.__size, "索引越界"
num = self.nums[index] num = self.__nums[index]
# 索引 i 之后的元素都向前移动一位 # 索引 i 之后的元素都向前移动一位
for j in range(index, self.__size - 1): for j in range(index, self.__size - 1):
self.__nums[j] = self.__nums[j + 1] self.__nums[j] = self.__nums[j + 1]
@ -64,15 +69,15 @@ class MyList:
# 返回被删除元素 # 返回被删除元素
return num return num
""" 列表扩容 """
def extend_capacity(self): def extend_capacity(self):
""" 列表扩容 """
# 新建一个长度为 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): def to_array(self):
""" 返回有效长度的列表 """
return self.__nums[:self.__size] return self.__nums[:self.__size]
@ -90,7 +95,7 @@ if __name__ == "__main__":
.format(list.to_array(), list.capacity(), list.size())) .format(list.to_array(), list.capacity(), list.size()))
""" 中间插入元素 """ """ 中间插入元素 """
list.add(num=6, index=3) list.insert(6, index=3)
print("在索引 3 处插入数字 6 ,得到 list =", list.to_array()) print("在索引 3 处插入数字 6 ,得到 list =", list.to_array())
""" 删除元素 """ """ 删除元素 """

View file

@ -6,10 +6,10 @@ 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 include import * from modules import *
""" 方法一:暴力枚举 """
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)):
@ -17,8 +17,8 @@ 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)

View file

@ -6,15 +6,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 include import * from modules import *
""" 函数 """
def function(): def function():
""" 函数 """
# do something # do something
return 0 return 0
""" 常数阶 """
def constant(n): def constant(n):
""" 常数阶 """
# 常量、变量、对象占用 O(1) 空间 # 常量、变量、对象占用 O(1) 空间
a = 0 a = 0
nums = [0] * 10000 nums = [0] * 10000
@ -26,8 +26,8 @@ def constant(n):
for _ in range(n): for _ in range(n):
function() function()
""" 线性阶 """
def linear(n): def linear(n):
""" 线性阶 """
# 长度为 n 的列表占用 O(n) 空间 # 长度为 n 的列表占用 O(n) 空间
nums = [0] * n nums = [0] * n
# 长度为 n 的哈希表占用 O(n) 空间 # 长度为 n 的哈希表占用 O(n) 空间
@ -35,26 +35,26 @@ def linear(n):
for i in range(n): for i in range(n):
mapp[i] = str(i) mapp[i] = str(i)
""" 线性阶(递归实现) """
def linear_recur(n): def linear_recur(n):
""" 线性阶(递归实现) """
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): def quadratic(n):
""" 平方阶 """
# 二维列表占用 O(n^2) 空间 # 二维列表占用 O(n^2) 空间
num_matrix = [[0] * n for _ in range(n)] num_matrix = [[0] * n for _ in range(n)]
""" 平方阶(递归实现) """
def quadratic_recur(n): def quadratic_recur(n):
""" 平方阶(递归实现) """
if n <= 0: return 0 if n <= 0: return 0
# 数组 nums 长度为 n, n-1, ..., 2, 1 # 数组 nums 长度为 n, n-1, ..., 2, 1
nums = [0] * n nums = [0] * n
return quadratic_recur(n - 1) return quadratic_recur(n - 1)
""" 指数阶(建立满二叉树) """
def build_tree(n): def build_tree(n):
""" 指数阶(建立满二叉树) """
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)

View file

@ -6,33 +6,33 @@ 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 include import * from modules import *
""" 常数阶 """
def constant(n): def constant(n):
""" 常数阶 """
count = 0 count = 0
size = 100000 size = 100000
for _ in range(size): for _ in range(size):
count += 1 count += 1
return count return count
""" 线性阶 """
def linear(n): def linear(n):
""" 线性阶 """
count = 0 count = 0
for _ in range(n): for _ in range(n):
count += 1 count += 1
return count return count
""" 线性阶(遍历数组)"""
def array_traversal(nums): def array_traversal(nums):
""" 线性阶(遍历数组)"""
count = 0 count = 0
# 循环次数与数组长度成正比 # 循环次数与数组长度成正比
for num in nums: for num in nums:
count += 1 count += 1
return count return count
""" 平方阶 """
def quadratic(n): def quadratic(n):
""" 平方阶 """
count = 0 count = 0
# 循环次数与数组长度成平方关系 # 循环次数与数组长度成平方关系
for i in range(n): for i in range(n):
@ -40,8 +40,8 @@ def quadratic(n):
count += 1 count += 1
return count return count
""" 平方阶(冒泡排序)"""
def bubble_sort(nums): def bubble_sort(nums):
""" 平方阶(冒泡排序)"""
count = 0 # 计数器 count = 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):
@ -55,8 +55,8 @@ def bubble_sort(nums):
count += 3 # 元素交换包含 3 个单元操作 count += 3 # 元素交换包含 3 个单元操作
return count return count
""" 指数阶(循环实现)"""
def exponential(n): def exponential(n):
""" 指数阶(循环实现)"""
count, base = 0, 1 count, base = 0, 1
# cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1) # cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for _ in range(n): for _ in range(n):
@ -66,26 +66,26 @@ def exponential(n):
# 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): def exp_recur(n):
""" 指数阶(递归实现)"""
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): def logarithmic(n):
""" 对数阶(循环实现)"""
count = 0 count = 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): def log_recur(n):
""" 对数阶(递归实现)"""
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): def linear_log_recur(n):
""" 线性对数阶 """
if n <= 1: return 1 if n <= 1: return 1
count = linear_log_recur(n // 2) + \ count = linear_log_recur(n // 2) + \
linear_log_recur(n // 2) linear_log_recur(n // 2)
@ -93,8 +93,8 @@ def linear_log_recur(n):
count += 1 count += 1
return count return count
""" 阶乘阶(递归实现)"""
def factorial_recur(n): def factorial_recur(n):
""" 阶乘阶(递归实现)"""
if n == 0: return 1 if n == 0: return 1
count = 0 count = 0
# 从 1 个分裂出 n 个 # 从 1 个分裂出 n 个

View file

@ -6,18 +6,18 @@ 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 include import * from modules import *
""" 生成一个数组,元素为: 1, 2, ..., n ,顺序被打乱 """
def random_numbers(n): def random_numbers(n):
""" 生成一个数组,元素为: 1, 2, ..., n ,顺序被打乱 """
# 生成数组 nums =: 1, 2, 3, ..., n # 生成数组 nums =: 1, 2, 3, ..., n
nums = [i for i in range(1, n + 1)] nums = [i for i in range(1, n + 1)]
# 随机打乱数组元素 # 随机打乱数组元素
random.shuffle(nums) random.shuffle(nums)
return nums return nums
""" 查找数组 nums 中数字 1 所在索引 """
def find_one(nums): def find_one(nums):
""" 查找数组 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)

View file

@ -6,16 +6,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 include import * from modules import *
""" 基于邻接表实现的无向图类 """
class GraphAdjList: class GraphAdjList:
""" 基于邻接表实现的无向图类 """
# 邻接表key: 顶点value该顶点的所有邻接顶点 # 邻接表key: 顶点value该顶点的所有邻接顶点
adj_list = {} adj_list = {}
""" 构造方法 """
def __init__(self, edges: List[List[Vertex]]) -> None: def __init__(self, edges: List[List[Vertex]]) -> None:
""" 构造方法 """
self.adj_list = {} self.adj_list = {}
# 添加所有顶点和边 # 添加所有顶点和边
for edge in edges: for edge in edges:
@ -23,35 +22,35 @@ class GraphAdjList:
self.add_vertex(edge[1]) self.add_vertex(edge[1])
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
self.adj_list[vet1].append(vet2) self.adj_list[vet1].append(vet2)
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
self.adj_list[vet1].remove(vet2) self.adj_list[vet1].remove(vet2)
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 对应的链表
@ -61,8 +60,8 @@ class GraphAdjList:
if vet in self.adj_list[vertex]: if vet in self.adj_list[vertex]:
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]]

View file

@ -6,18 +6,17 @@ 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 include import * from modules import *
""" 基于邻接矩阵实现的无向图类 """
class GraphAdjMat: class GraphAdjMat:
""" 基于邻接矩阵实现的无向图类 """
# 顶点列表,元素代表“顶点值”,索引代表“顶点索引” # 顶点列表,元素代表“顶点值”,索引代表“顶点索引”
vertices = [] vertices = []
# 邻接矩阵,行列索引对应“顶点索引” # 邻接矩阵,行列索引对应“顶点索引”
adj_mat = [] adj_mat = []
""" 构造方法 """
def __init__(self, vertices, edges): def __init__(self, vertices, edges):
""" 构造方法 """
self.vertices = [] self.vertices = []
self.adj_mat = [] self.adj_mat = []
# 添加顶点 # 添加顶点
@ -28,12 +27,12 @@ class GraphAdjMat:
for e in edges: for e in edges:
self.add_edge(e[0], e[1]) self.add_edge(e[0], e[1])
""" 获取顶点数量 """
def size(self): def size(self):
""" 获取顶点数量 """
return len(self.vertices) return len(self.vertices)
""" 添加顶点 """
def add_vertex(self, val): def add_vertex(self, val):
""" 添加顶点 """
n = self.size() n = self.size()
# 向顶点列表中添加新顶点的值 # 向顶点列表中添加新顶点的值
self.vertices.append(val) self.vertices.append(val)
@ -44,9 +43,8 @@ class GraphAdjMat:
for row in self.adj_mat: for row in self.adj_mat:
row.append(0) row.append(0)
""" 删除顶点 """
def remove_vertex(self, index): def remove_vertex(self, index):
""" 删除顶点 """
if index >= self.size(): if index >= self.size():
raise IndexError() raise IndexError()
# 在顶点列表中移除索引 index 的顶点 # 在顶点列表中移除索引 index 的顶点
@ -57,9 +55,9 @@ class GraphAdjMat:
for row in self.adj_mat: for row in self.adj_mat:
row.pop(index) row.pop(index)
""" 添加边 """
# 参数 i, j 对应 vertices 元素索引
def add_edge(self, i, j): def add_edge(self, i, j):
""" 添加边 """
# 参数 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:
raise IndexError() raise IndexError()
@ -67,17 +65,17 @@ class GraphAdjMat:
self.adj_mat[i][j] = 1 self.adj_mat[i][j] = 1
self.adj_mat[j][i] = 1 self.adj_mat[j][i] = 1
""" 删除边 """
# 参数 i, j 对应 vertices 元素索引
def remove_edge(self, i, j): def remove_edge(self, i, j):
""" 删除边 """
# 参数 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:
raise IndexError() raise IndexError()
self.adj_mat[i][j] = 0 self.adj_mat[i][j] = 0
self.adj_mat[j][i] = 0 self.adj_mat[j][i] = 0
""" 打印邻接矩阵 """
def print(self): def print(self):
""" 打印邻接矩阵 """
print("顶点列表 =", self.vertices) print("顶点列表 =", self.vertices)
print("邻接矩阵 =") print("邻接矩阵 =")
print_matrix(self.adj_mat) print_matrix(self.adj_mat)

View file

@ -6,12 +6,12 @@ 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 include import * from modules import *
from graph_adjacency_list import GraphAdjList from graph_adjacency_list import GraphAdjList
""" 广度优先遍历 BFS """
# 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> List[Vertex]: def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> List[Vertex]:
""" 广度优先遍历 BFS """
# 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
# 顶点遍历序列 # 顶点遍历序列
res = [] res = []
# 哈希表,用于记录已被访问过的顶点 # 哈希表,用于记录已被访问过的顶点
@ -32,6 +32,7 @@ def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> List[Vertex]:
return res return res
""" 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])
@ -45,4 +46,4 @@ if __name__ == "__main__":
"""广度优先遍历 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))

View file

@ -6,12 +6,11 @@ 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 include import * from modules import *
from graph_adjacency_list import GraphAdjList from graph_adjacency_list import GraphAdjList
""" 深度优先遍历 DFS 辅助函数 """
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 辅助函数 """
res.append(vet) # 记录访问顶点 res.append(vet) # 记录访问顶点
visited.add(vet) # 标记该顶点已被访问 visited.add(vet) # 标记该顶点已被访问
# 遍历该顶点的所有邻接顶点 # 遍历该顶点的所有邻接顶点
@ -21,9 +20,9 @@ def dfs(graph: GraphAdjList, visited: Set[Vertex], res: List[Vertex], vet: Verte
# 递归访问邻接顶点 # 递归访问邻接顶点
dfs(graph, visited, res, adjVet) dfs(graph, visited, res, adjVet)
""" 深度优先遍历 DFS """
# 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 # 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
def graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> List[Vertex]: def graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> List[Vertex]:
""" 深度优先遍历 DFS """
# 顶点遍历序列 # 顶点遍历序列
res = [] res = []
# 哈希表,用于记录已被访问过的顶点 # 哈希表,用于记录已被访问过的顶点

View file

@ -4,69 +4,70 @@ Created Time: 2022-12-14
Author: msk397 (machangxinq@gmail.com) Author: msk397 (machangxinq@gmail.com)
""" """
""" 键值对 int->String """
class Entry: class Entry:
""" 键值对 int->String """
def __init__(self, key, val): def __init__(self, key, val):
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.bucket = [None] * 100 self.bucket = [None] * 100
""" 哈希函数 """
def hash_func(self, key): def hash_func(self, key):
""" 哈希函数 """
index = key % 100 index = key % 100
return index return index
""" 查询操作 """
def get(self, key): def get(self, key):
""" 查询操作 """
index = self.hash_func(key) index = self.hash_func(key)
pair = self.bucket[index] pair = self.bucket[index]
if pair is None: if pair is None:
return None return None
return pair.val return pair.val
""" 添加操作 """
def put(self, key, val): def put(self, key, val):
""" 添加操作 """
pair = Entry(key, val) pair = Entry(key, val)
index = self.hash_func(key) index = self.hash_func(key)
self.bucket[index] = pair self.bucket[index] = pair
""" 删除操作 """
def remove(self, key): def remove(self, key):
""" 删除操作 """
index = self.hash_func(key) index = self.hash_func(key)
# 置为 None ,代表删除 # 置为 None ,代表删除
self.bucket[index] = None self.bucket[index] = None
""" 获取所有键值对 """
def entry_set(self): def entry_set(self):
""" 获取所有键值对 """
result = [] result = []
for pair in self.bucket: for pair in self.bucket:
if pair is not None: if pair is not None:
result.append(pair) result.append(pair)
return result return result
""" 获取所有键 """
def key_set(self): def key_set(self):
""" 获取所有键 """
result = [] result = []
for pair in self.bucket: for pair in self.bucket:
if pair is not None: if pair is not None:
result.append(pair.key) result.append(pair.key)
return result return result
""" 获取所有值 """
def value_set(self): def value_set(self):
""" 获取所有值 """
result = [] result = []
for pair in self.bucket: for pair in self.bucket:
if pair is not None: if pair is not None:
result.append(pair.val) result.append(pair.val)
return result return result
""" 打印哈希表 """
def print(self): def print(self):
""" 打印哈希表 """
for pair in self.bucket: for pair in self.bucket:
if pair is not None: if pair is not None:
print(pair.key, "->", pair.val) print(pair.key, "->", pair.val)

View file

@ -6,7 +6,7 @@ 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 include import * from modules import *
""" Driver Code """ """ Driver Code """

View file

@ -6,7 +6,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 include import * from modules import *
def test_push(heap, val, flag=1): def test_push(heap, val, flag=1):
heapq.heappush(heap, flag * val) # 元素入堆 heapq.heappush(heap, flag * val) # 元素入堆
@ -18,6 +18,7 @@ def test_pop(heap, flag=1):
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 """
if __name__ == "__main__": if __name__ == "__main__":
# 初始化小顶堆 # 初始化小顶堆
min_heap, flag = [], 1 min_heap, flag = [], 1

View file

@ -6,56 +6,56 @@ 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 include 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
# 堆化除叶结点以外的其他所有结点 # 堆化除叶结点以外的其他所有结点
for i in range(self.parent(self.size() - 1), -1, -1): for i in range(self.parent(self.size() - 1), -1, -1):
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)
""" 从结点 i 开始,从底至顶堆化 """
def sift_up(self, i: int): def sift_up(self, i: int):
""" 从结点 i 开始,从底至顶堆化 """
while True: while True:
# 获取结点 i 的父结点 # 获取结点 i 的父结点
p = self.parent(i) p = self.parent(i)
@ -67,8 +67,8 @@ class MaxHeap:
# 循环向上堆化 # 循环向上堆化
i = p i = p
""" 元素出堆 """
def poll(self) -> int: def poll(self) -> int:
""" 元素出堆 """
# 判空处理 # 判空处理
assert not self.is_empty() assert not self.is_empty()
# 交换根结点与最右叶结点(即交换首元素与尾元素) # 交换根结点与最右叶结点(即交换首元素与尾元素)
@ -80,8 +80,8 @@ class MaxHeap:
# 返回堆顶元素 # 返回堆顶元素
return val return val
""" 从结点 i 开始,从顶至底堆化 """
def sift_down(self, i: int): def sift_down(self, i: int):
""" 从结点 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
@ -97,8 +97,8 @@ class MaxHeap:
# 循环向下堆化 # 循环向下堆化
i = ma i = ma
""" 打印堆(二叉树) """
def print(self): def print(self):
""" 打印堆(二叉树) """
print_heap(self.max_heap) print_heap(self.max_heap)
@ -114,6 +114,7 @@ def test_poll(max_heap: MaxHeap):
max_heap.print() max_heap.print()
""" Driver Code """
if __name__ == "__main__": if __name__ == "__main__":
# 初始化大顶堆 # 初始化大顶堆
max_heap = MaxHeap([9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2]) max_heap = MaxHeap([9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2])

View file

@ -6,10 +6,10 @@ 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 include import * from modules import *
""" 二分查找(双闭区间) """
def binary_search(nums, target): def binary_search(nums, target):
""" 二分查找(双闭区间) """
# 初始化双闭区间 [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:
@ -23,8 +23,8 @@ def binary_search(nums, target):
return -1 # 未找到目标元素,返回 -1 return -1 # 未找到目标元素,返回 -1
""" 二分查找(左闭右开) """
def binary_search1(nums, target): def binary_search1(nums, target):
""" 二分查找(左闭右开) """
# 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 # 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
i, j = 0, len(nums) i, j = 0, len(nums)
# 循环,当搜索区间为空时跳出(当 i = j 时为空) # 循环,当搜索区间为空时跳出(当 i = j 时为空)

View file

@ -6,16 +6,16 @@ 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 include import * from modules import *
""" 哈希查找(数组) """
def hashing_search_array(mapp, target): def hashing_search_array(mapp, target):
""" 哈希查找(数组) """
# 哈希表的 key: 目标元素value: 索引 # 哈希表的 key: 目标元素value: 索引
# 若哈希表中无此 key ,返回 -1 # 若哈希表中无此 key ,返回 -1
return mapp.get(target, -1) return mapp.get(target, -1)
""" 哈希查找(链表) """
def hashing_search_linkedlist(mapp, target): def hashing_search_linkedlist(mapp, target):
""" 哈希查找(链表) """
# 哈希表的 key: 目标元素value: 结点对象 # 哈希表的 key: 目标元素value: 结点对象
# 若哈希表中无此 key ,返回 -1 # 若哈希表中无此 key ,返回 -1
return mapp.get(target, -1) return mapp.get(target, -1)

View file

@ -6,18 +6,18 @@ 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 include import * from modules import *
""" 线性查找(数组) """
def linear_search_array(nums, target): def linear_search_array(nums, target):
""" 线性查找(数组) """
# 遍历数组 # 遍历数组
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, target): def linear_search_linkedlist(head, target):
""" 线性查找(链表) """
# 遍历链表 # 遍历链表
while head: while head:
if head.val == target: # 找到目标结点,返回之 if head.val == target: # 找到目标结点,返回之

View file

@ -6,10 +6,10 @@ 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 include import * from modules import *
""" 冒泡排序 """
def bubble_sort(nums): def bubble_sort(nums):
""" 冒泡排序 """
n = len(nums) n = 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):
@ -19,8 +19,8 @@ def bubble_sort(nums):
# 交换 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): def bubble_sort_with_flag(nums):
""" 冒泡排序(标志优化) """
n = len(nums) n = 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):

View file

@ -6,11 +6,11 @@ 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 include import * from modules import *
""" 插入排序 """
def insertion_sort(nums): def insertion_sort(nums):
# 外循环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 = nums[i] base = nums[i]
j = i - 1 j = i - 1

View file

@ -6,13 +6,12 @@ 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 include import * from modules import *
""" 合并左子数组和右子数组 """
# 左子数组区间 [left, mid]
# 右子数组区间 [mid + 1, right]
def merge(nums, left, mid, right): def merge(nums, left, mid, right):
""" 合并左子数组和右子数组 """
# 左子数组区间 [left, mid]
# 右子数组区间 [mid + 1, right]
# 初始化辅助数组 借助 copy模块 # 初始化辅助数组 借助 copy模块
tmp = nums[left:right + 1] tmp = nums[left:right + 1]
# 左子数组的起始索引和结束索引 # 左子数组的起始索引和结束索引
@ -36,8 +35,8 @@ def merge(nums, left, mid, right):
nums[k] = tmp[j] nums[k] = tmp[j]
j += 1 j += 1
""" 归并排序 """
def merge_sort(nums, left, right): def merge_sort(nums, left, right):
""" 归并排序 """
# 终止条件 # 终止条件
if left >= right: if left >= right:
return # 当子数组长度为 1 时终止递归 return # 当子数组长度为 1 时终止递归

View file

@ -6,12 +6,12 @@ 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 include import * from modules import *
""" 快速排序类 """
class QuickSort: class QuickSort:
""" 哨兵划分 """ """ 快速排序类 """
def partition(self, nums, left, right): def partition(self, nums, left, right):
""" 哨兵划分 """
# 以 nums[left] 作为基准数 # 以 nums[left] 作为基准数
i, j = left, right i, j = left, right
while i < j: while i < j:
@ -25,8 +25,8 @@ class QuickSort:
nums[i], nums[left] = nums[left], nums[i] nums[i], nums[left] = nums[left], nums[i]
return i # 返回基准数的索引 return i # 返回基准数的索引
""" 快速排序 """
def quick_sort(self, nums, left, right): def quick_sort(self, nums, left, right):
""" 快速排序 """
# 子数组长度为 1 时终止递归 # 子数组长度为 1 时终止递归
if left >= right: if left >= right:
return return
@ -36,10 +36,10 @@ 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, left, mid, right): def median_three(self, nums, left, mid, right):
""" 选取三个元素的中位数 """
# 此处使用异或运算来简化代码 # 此处使用异或运算来简化代码
# 异或规则为 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]):
@ -48,8 +48,8 @@ class QuickSortMedian:
return mid return mid
return right return right
""" 哨兵划分(三数取中值) """
def partition(self, nums, left, right): def partition(self, nums, left, right):
""" 哨兵划分(三数取中值) """
# 以 nums[left] 作为基准数 # 以 nums[left] 作为基准数
med = self.median_three(nums, left, (left + right) // 2, right) med = self.median_three(nums, left, (left + right) // 2, right)
# 将中位数交换至数组最左端 # 将中位数交换至数组最左端
@ -67,8 +67,8 @@ class QuickSortMedian:
nums[i], nums[left] = nums[left], nums[i] nums[i], nums[left] = nums[left], nums[i]
return i # 返回基准数的索引 return i # 返回基准数的索引
""" 快速排序 """
def quick_sort(self, nums, left, right): def quick_sort(self, nums, left, right):
""" 快速排序 """
# 子数组长度为 1 时终止递归 # 子数组长度为 1 时终止递归
if left >= right: return if left >= right: return
# 哨兵划分 # 哨兵划分
@ -77,10 +77,10 @@ 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, left, right): def partition(self, nums, left, right):
""" 哨兵划分 """
# 以 nums[left] 作为基准数 # 以 nums[left] 作为基准数
i, j = left, right i, j = left, right
while i < j: while i < j:
@ -92,10 +92,10 @@ class QuickSortTailCall:
nums[i], nums[j] = nums[j], nums[i] nums[i], nums[j] = nums[j], nums[i]
# 将基准数交换至两子数组的分界线 # 将基准数交换至两子数组的分界线
nums[i], nums[left] = nums[left], nums[i] nums[i], nums[left] = nums[left], nums[i]
return i # 返回基准数的索引 return i # 返回基准数的索引
""" 快速排序(尾递归优化) """
def quick_sort(self, nums, left, right): def quick_sort(self, nums, left, right):
""" 快速排序(尾递归优化) """
# 子数组长度为 1 时终止 # 子数组长度为 1 时终止
while left < right: while left < right:
# 哨兵划分操作 # 哨兵划分操作
@ -112,16 +112,16 @@ class QuickSortTailCall:
""" Driver Code """ """ Driver Code """
if __name__ == '__main__': if __name__ == '__main__':
# 快速排序 # 快速排序
nums = [4, 1, 3, 1, 5, 2] nums = [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)
# 快速排序(中位基准数优化) # 快速排序(中位基准数优化)
nums1 = [4, 1, 3, 1, 5, 2] nums1 = [2, 4, 1, 0, 3, 5]
QuickSortMedian().quick_sort(nums1, 0, len(nums1) - 1) QuickSortMedian().quick_sort(nums1, 0, len(nums1) - 1)
print("快速排序(中位基准数优化)完成后 nums =", nums) print("快速排序(中位基准数优化)完成后 nums =", nums1)
# 快速排序(尾递归优化) # 快速排序(尾递归优化)
nums2 = [4, 1, 3, 1, 5, 2] nums2 = [2, 4, 1, 0, 3, 5]
QuickSortTailCall().quick_sort(nums, 0, len(nums2) - 1) QuickSortTailCall().quick_sort(nums2, 0, len(nums2) - 1)
print("快速排序(尾递归优化)完成后 nums =", nums) print("快速排序(尾递归优化)完成后 nums =", nums2)

View file

@ -8,37 +8,37 @@ import os.path as osp
import sys import sys
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import * from modules import *
""" 基于环形数组实现的双向队列 """
class ArrayDeque: class ArrayDeque:
""" 构造方法 """ """ 基于环形数组实现的双向队列 """
def __init__(self, capacity): def __init__(self, capacity):
""" 构造方法 """
self.nums = [0] * capacity self.nums = [0] * capacity
self.front = 0 self.front = 0
self.que_size = 0 self.que_size = 0
""" 获取双向队列的容量 """
def capacity(self): def capacity(self):
""" 获取双向队列的容量 """
return len(self.nums) return len(self.nums)
""" 获取双向队列的长度 """
def size(self): def size(self):
""" 获取双向队列的长度 """
return self.que_size return self.que_size
""" 判断双向队列是否为空 """
def is_empty(self): def is_empty(self):
""" 判断双向队列是否为空 """
return self.que_size == 0 return self.que_size == 0
""" 计算环形数组索引 """
def index(self, i): def index(self, i):
""" 计算环形数组索引 """
# 通过取余操作实现数组首尾相连 # 通过取余操作实现数组首尾相连
# 当 i 越过数组尾部后,回到头部 # 当 i 越过数组尾部后,回到头部
# 当 i 越过数组头部后,回到尾部 # 当 i 越过数组头部后,回到尾部
return (i + self.capacity()) % self.capacity() return (i + self.capacity()) % self.capacity()
""" 队首入队 """
def push_first(self, num): def push_first(self, num):
""" 队首入队 """
if self.que_size == self.capacity(): if self.que_size == self.capacity():
print("双向队列已满") print("双向队列已满")
return return
@ -49,8 +49,8 @@ class ArrayDeque:
self.nums[self.front] = num self.nums[self.front] = num
self.que_size += 1 self.que_size += 1
""" 队尾入队 """
def push_last(self, num): def push_last(self, num):
""" 队尾入队 """
if self.que_size == self.capacity(): if self.que_size == self.capacity():
print("双向队列已满") print("双向队列已满")
return return
@ -60,34 +60,34 @@ class ArrayDeque:
self.nums[rear] = num self.nums[rear] = num
self.que_size += 1 self.que_size += 1
""" 队首出队 """
def poll_first(self): def poll_first(self):
""" 队首出队 """
num = self.peek_first() num = self.peek_first()
# 队首指针向后移动一位 # 队首指针向后移动一位
self.front = self.index(self.front+1) self.front = self.index(self.front+1)
self.que_size -= 1 self.que_size -= 1
return num return num
""" 队尾出队 """
def poll_last(self): def poll_last(self):
""" 队尾出队 """
num = self.peek_last() num = self.peek_last()
self.que_size -= 1 self.que_size -= 1
return num return num
""" 访问队首元素 """
def peek_first(self): def peek_first(self):
""" 访问队首元素 """
assert not self.is_empty(), "双向队列为空" assert not self.is_empty(), "双向队列为空"
return self.nums[self.front] return self.nums[self.front]
""" 访问队尾元素 """
def peek_last(self): def peek_last(self):
""" 访问队尾元素 """
assert not self.is_empty(), "双向队列为空" assert not self.is_empty(), "双向队列为空"
# 计算尾元素索引 # 计算尾元素索引
last = self.index(self.front + self.que_size - 1) last = self.index(self.front + self.que_size - 1)
return self.nums[last] return self.nums[last]
""" 返回数组用于打印 """
def to_array(self): def to_array(self):
""" 返回数组用于打印 """
# 仅转换有效长度范围内的列表元素 # 仅转换有效长度范围内的列表元素
res = [] res = []
for i in range(self.que_size): for i in range(self.que_size):

View file

@ -8,29 +8,30 @@ import os.path as osp
import sys import sys
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import * from modules import *
""" 基于环形数组实现的队列 """
class ArrayQueue: class ArrayQueue:
""" 基于环形数组实现的队列 """
def __init__(self, size): def __init__(self, size):
""" 构造方法 """
self.__nums = [0] * size # 用于存储队列元素的数组 self.__nums = [0] * size # 用于存储队列元素的数组
self.__front = 0 # 队首指针,指向队首元素 self.__front = 0 # 队首指针,指向队首元素
self.__size = 0 # 队列长度 self.__size = 0 # 队列长度
""" 获取队列的容量 """
def capacity(self): def capacity(self):
""" 获取队列的容量 """
return len(self.__nums) return len(self.__nums)
""" 获取队列的长度 """
def size(self): def size(self):
""" 获取队列的长度 """
return self.__size return self.__size
""" 判断队列是否为空 """
def is_empty(self): def is_empty(self):
""" 判断队列是否为空 """
return self.__size == 0 return self.__size == 0
""" 入队 """
def push(self, num): def push(self, num):
""" 入队 """
assert self.__size < self.capacity(), "队列已满" assert self.__size < self.capacity(), "队列已满"
# 计算尾指针,指向队尾索引 + 1 # 计算尾指针,指向队尾索引 + 1
# 通过取余操作,实现 rear 越过数组尾部后回到头部 # 通过取余操作,实现 rear 越过数组尾部后回到头部
@ -39,21 +40,21 @@ class ArrayQueue:
self.__nums[rear] = num self.__nums[rear] = num
self.__size += 1 self.__size += 1
""" 出队 """
def poll(self): def poll(self):
""" 出队 """
num = self.peek() num = self.peek()
# 队首指针向后移动一位,若越过尾部则返回到数组头部 # 队首指针向后移动一位,若越过尾部则返回到数组头部
self.__front = (self.__front + 1) % self.capacity() self.__front = (self.__front + 1) % self.capacity()
self.__size -= 1 self.__size -= 1
return num return num
""" 访问队首元素 """
def peek(self): def peek(self):
""" 访问队首元素 """
assert not self.is_empty(), "队列为空" assert not self.is_empty(), "队列为空"
return self.__nums[self.__front] return self.__nums[self.__front]
""" 返回列表用于打印 """
def to_list(self): def to_list(self):
""" 返回列表用于打印 """
res = [0] * self.size() res = [0] * self.size()
j = self.__front j = self.__front
for i in range(self.size()): for i in range(self.size()):

View file

@ -6,37 +6,38 @@ 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 include import * from modules import *
""" 基于数组实现的栈 """
class ArrayStack: class ArrayStack:
""" 基于数组实现的栈 """
def __init__(self): def __init__(self):
""" 构造方法 """
self.__stack = [] self.__stack = []
""" 获取栈的长度 """
def size(self): def size(self):
""" 获取栈的长度 """
return len(self.__stack) return len(self.__stack)
""" 判断栈是否为空 """
def is_empty(self): def is_empty(self):
""" 判断栈是否为空 """
return self.__stack == [] return self.__stack == []
""" 入栈 """
def push(self, item): def push(self, item):
""" 入栈 """
self.__stack.append(item) self.__stack.append(item)
""" 出栈 """
def pop(self): def pop(self):
""" 出栈 """
assert not self.is_empty(), "栈为空" assert not self.is_empty(), "栈为空"
return self.__stack.pop() return self.__stack.pop()
""" 访问栈顶元素 """
def peek(self): def peek(self):
""" 访问栈顶元素 """
assert not self.is_empty(), "栈为空" assert not self.is_empty(), "栈为空"
return self.__stack[-1] return self.__stack[-1]
""" 返回列表用于打印 """
def to_list(self): def to_list(self):
""" 返回列表用于打印 """
return self.__stack return self.__stack

View file

@ -8,7 +8,7 @@ import os.path as osp
import sys import sys
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import * from modules import *
from collections import deque from collections import deque

View file

@ -8,32 +8,33 @@ import os.path as osp
import sys import sys
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import * from modules import *
""" 双向链表结点 """
class ListNode: class ListNode:
""" 双向链表结点 """
def __init__(self, val): def __init__(self, val):
""" 构造方法 """
self.val = val self.val = val
self.next = None # 后继结点引用(指针) self.next = None # 后继结点引用(指针)
self.prev = None # 前驱结点引用(指针) self.prev = None # 前驱结点引用(指针)
""" 基于双向链表实现的双向队列 """
class LinkedListDeque: class LinkedListDeque:
""" 构造方法 """ """ 基于双向链表实现的双向队列 """
def __init__(self): def __init__(self):
""" 构造方法 """
self.front, self.rear = None, None # 头结点 front ,尾结点 rear self.front, self.rear = None, None # 头结点 front ,尾结点 rear
self.__size = 0 # 双向队列的长度 self.__size = 0 # 双向队列的长度
""" 获取双向队列的长度 """
def size(self): def size(self):
""" 获取双向队列的长度 """
return self.__size return self.__size
""" 判断双向队列是否为空 """
def is_empty(self): def is_empty(self):
""" 判断双向队列是否为空 """
return self.size() == 0 return self.size() == 0
""" 入队操作 """
def push(self, num, is_front): def push(self, num, is_front):
""" 入队操作 """
node = ListNode(num) node = ListNode(num)
# 若链表为空,则令 front, rear 都指向 node # 若链表为空,则令 front, rear 都指向 node
if self.is_empty(): if self.is_empty():
@ -52,16 +53,16 @@ class LinkedListDeque:
self.rear = node # 更新尾结点 self.rear = node # 更新尾结点
self.__size += 1 # 更新队列长度 self.__size += 1 # 更新队列长度
""" 队首入队 """
def push_first(self, num): def push_first(self, num):
""" 队首入队 """
self.push(num, True) self.push(num, True)
""" 队尾入队 """
def push_last(self, num): def push_last(self, num):
""" 队尾入队 """
self.push(num, False) self.push(num, False)
""" 出队操作 """
def poll(self, is_front): def poll(self, is_front):
""" 出队操作 """
# 若队列为空,直接返回 None # 若队列为空,直接返回 None
if self.is_empty(): if self.is_empty():
return None return None
@ -86,24 +87,24 @@ class LinkedListDeque:
self.__size -= 1 # 更新队列长度 self.__size -= 1 # 更新队列长度
return val return val
""" 队首出队 """
def poll_first(self): def poll_first(self):
""" 队首出队 """
return self.poll(True) return self.poll(True)
""" 队尾出队 """
def poll_last(self): def poll_last(self):
""" 队尾出队 """
return self.poll(False) return self.poll(False)
""" 访问队首元素 """
def peek_first(self): def peek_first(self):
""" 访问队首元素 """
return None if self.is_empty() else self.front.val return None if self.is_empty() else self.front.val
""" 访问队尾元素 """
def peek_last(self): def peek_last(self):
""" 访问队尾元素 """
return None if self.is_empty() else self.rear.val return None if self.is_empty() else self.rear.val
""" 返回数组用于打印 """
def to_array(self): def to_array(self):
""" 返回数组用于打印 """
node = self.front node = self.front
res = [0] * self.size() res = [0] * self.size()
for i in range(self.size()): for i in range(self.size()):

View file

@ -8,25 +8,26 @@ import os.path as osp
import sys import sys
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import * from modules import *
""" 基于链表实现的队列 """
class LinkedListQueue: class LinkedListQueue:
""" 基于链表实现的队列 """
def __init__(self): def __init__(self):
""" 构造方法 """
self.__front = None # 头结点 front self.__front = None # 头结点 front
self.__rear = None # 尾结点 rear self.__rear = None # 尾结点 rear
self.__size = 0 self.__size = 0
""" 获取队列的长度 """
def size(self): def size(self):
""" 获取队列的长度 """
return self.__size return self.__size
""" 判断队列是否为空 """
def is_empty(self): def is_empty(self):
""" 判断队列是否为空 """
return not self.__front return not self.__front
""" 入队 """
def push(self, num): def push(self, num):
""" 入队 """
# 尾结点后添加 num # 尾结点后添加 num
node = ListNode(num) node = ListNode(num)
# 如果队列为空,则令头、尾结点都指向该结点 # 如果队列为空,则令头、尾结点都指向该结点
@ -39,23 +40,23 @@ class LinkedListQueue:
self.__rear = node self.__rear = node
self.__size += 1 self.__size += 1
""" 出队 """
def poll(self): def poll(self):
""" 出队 """
num = self.peek() num = self.peek()
# 删除头结点 # 删除头结点
self.__front = self.__front.next self.__front = self.__front.next
self.__size -= 1 self.__size -= 1
return num return num
""" 访问队首元素 """
def peek(self): def peek(self):
""" 访问队首元素 """
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): def to_list(self):
""" 转化为列表用于打印 """
queue = [] queue = []
temp = self.__front temp = self.__front
while temp: while temp:

View file

@ -6,44 +6,45 @@ 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 include import * from modules import *
""" 基于链表实现的栈 """
class LinkedListStack: class LinkedListStack:
""" 基于链表实现的栈 """
def __init__(self): def __init__(self):
""" 构造方法 """
self.__peek = None self.__peek = None
self.__size = 0 self.__size = 0
""" 获取栈的长度 """
def size(self): def size(self):
""" 获取栈的长度 """
return self.__size return self.__size
""" 判断栈是否为空 """
def is_empty(self): def is_empty(self):
""" 判断栈是否为空 """
return not self.__peek return not self.__peek
""" 入栈 """
def push(self, val): def push(self, val):
""" 入栈 """
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): def pop(self):
""" 出栈 """
num = self.peek() num = 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): def peek(self):
""" 访问栈顶元素 """
# 判空处理 # 判空处理
if not self.__peek: return None if not self.__peek: return None
return self.__peek.val return self.__peek.val
""" 转化为列表用于打印 """
def to_list(self): def to_list(self):
""" 转化为列表用于打印 """
arr = [] arr = []
node = self.__peek node = self.__peek
while node: while node:

View file

@ -8,7 +8,7 @@ import os.path as osp
import sys import sys
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from include import * from modules import *
""" Driver Code """ """ Driver Code """

View file

@ -6,7 +6,7 @@ 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 include import * from modules import *
""" Driver Code """ """ Driver Code """

View file

@ -6,35 +6,36 @@ 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 include import * from modules import *
""" AVL 树 """
class AVLTree: class AVLTree:
""" AVL 树 """
def __init__(self, root: Optional[TreeNode] = None): def __init__(self, root: Optional[TreeNode] = None):
""" 构造方法 """
self.root = root self.root = root
""" 获取结点高度 """
def height(self, node: Optional[TreeNode]) -> int: def height(self, node: Optional[TreeNode]) -> 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: Optional[TreeNode]): def __update_height(self, node: Optional[TreeNode]):
""" 更新结点高度 """
# 结点高度等于最高子树高度 + 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: Optional[TreeNode]) -> int: def balance_factor(self, node: Optional[TreeNode]) -> int:
""" 获取平衡因子 """
# 空结点平衡因子为 0 # 空结点平衡因子为 0
if node is None: if node is None:
return 0 return 0
# 结点平衡因子 = 左子树高度 - 右子树高度 # 结点平衡因子 = 左子树高度 - 右子树高度
return self.height(node.left) - self.height(node.right) return self.height(node.left) - self.height(node.right)
""" 右旋操作 """
def __right_rotate(self, node: Optional[TreeNode]) -> TreeNode: def __right_rotate(self, node: Optional[TreeNode]) -> TreeNode:
""" 右旋操作 """
child = node.left child = node.left
grand_child = child.right grand_child = child.right
# 以 child 为原点,将 node 向右旋转 # 以 child 为原点,将 node 向右旋转
@ -46,8 +47,8 @@ class AVLTree:
# 返回旋转后子树的根结点 # 返回旋转后子树的根结点
return child return child
""" 左旋操作 """
def __left_rotate(self, node: Optional[TreeNode]) -> TreeNode: def __left_rotate(self, node: Optional[TreeNode]) -> TreeNode:
""" 左旋操作 """
child = node.right child = node.right
grand_child = child.left grand_child = child.left
# 以 child 为原点,将 node 向左旋转 # 以 child 为原点,将 node 向左旋转
@ -59,8 +60,8 @@ class AVLTree:
# 返回旋转后子树的根结点 # 返回旋转后子树的根结点
return child return child
""" 执行旋转操作,使该子树重新恢复平衡 """
def __rotate(self, node: Optional[TreeNode]) -> TreeNode: def __rotate(self, node: Optional[TreeNode]) -> TreeNode:
""" 执行旋转操作,使该子树重新恢复平衡 """
# 获取结点 node 的平衡因子 # 获取结点 node 的平衡因子
balance_factor = self.balance_factor(node) balance_factor = self.balance_factor(node)
# 左偏树 # 左偏树
@ -84,13 +85,13 @@ 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: Optional[TreeNode], val: int) -> TreeNode: def __insert_helper(self, node: Optional[TreeNode], val: int) -> TreeNode:
""" 递归插入结点(辅助方法)"""
if node is None: if node is None:
return TreeNode(val) return TreeNode(val)
# 1. 查找插入位置,并插入结点 # 1. 查找插入位置,并插入结点
@ -106,13 +107,13 @@ class AVLTree:
# 2. 执行旋转操作,使该子树重新恢复平衡 # 2. 执行旋转操作,使该子树重新恢复平衡
return self.__rotate(node) return self.__rotate(node)
""" 删除结点 """
def remove(self, val: int): def remove(self, val: int):
""" 删除结点 """
root = self.__remove_helper(self.root, val) root = self.__remove_helper(self.root, val)
return root return root
""" 递归删除结点(辅助方法) """
def __remove_helper(self, node: Optional[TreeNode], val: int) -> Optional[TreeNode]: def __remove_helper(self, node: Optional[TreeNode], val: int) -> Optional[TreeNode]:
""" 递归删除结点(辅助方法) """
if node is None: if node is None:
return None return None
# 1. 查找结点,并删除之 # 1. 查找结点,并删除之
@ -138,8 +139,8 @@ class AVLTree:
# 2. 执行旋转操作,使该子树重新恢复平衡 # 2. 执行旋转操作,使该子树重新恢复平衡
return self.__rotate(node) return self.__rotate(node)
""" 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """
def __get_inorder_next(self, node: Optional[TreeNode]) -> Optional[TreeNode]: def __get_inorder_next(self, node: Optional[TreeNode]) -> Optional[TreeNode]:
""" 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """
if node is None: if node is None:
return None return None
# 循环访问左子结点,直到叶结点时为最小结点,跳出 # 循环访问左子结点,直到叶结点时为最小结点,跳出
@ -147,8 +148,8 @@ class AVLTree:
node = node.left node = node.left
return node return node
""" 查找结点 """
def search(self, val: int): def search(self, val: int):
""" 查找结点 """
cur = self.root cur = self.root
# 循环查找,越过叶结点后跳出 # 循环查找,越过叶结点后跳出
while cur is not None: while cur is not None:

View file

@ -6,17 +6,18 @@ 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 include 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) -> Optional[TreeNode]: def build_tree(self, nums: List[int], start_index: int, end_index: int) -> Optional[TreeNode]:
""" 构建二叉搜索树 """
if start_index > end_index: if start_index > end_index:
return None return None
@ -32,8 +33,8 @@ class BinarySearchTree:
def root(self) -> Optional[TreeNode]: def root(self) -> Optional[TreeNode]:
return self.__root return self.__root
""" 查找结点 """
def search(self, num: int) -> Optional[TreeNode]: def search(self, num: int) -> Optional[TreeNode]:
""" 查找结点 """
cur = self.root cur = self.root
# 循环查找,越过叶结点后跳出 # 循环查找,越过叶结点后跳出
while cur is not None: while cur is not None:
@ -48,8 +49,8 @@ class BinarySearchTree:
break break
return cur return cur
""" 插入结点 """
def insert(self, num: int) -> Optional[TreeNode]: def insert(self, num: int) -> Optional[TreeNode]:
""" 插入结点 """
root = self.root root = self.root
# 若树为空,直接提前返回 # 若树为空,直接提前返回
if root is None: if root is None:
@ -77,8 +78,8 @@ class BinarySearchTree:
pre.left = node pre.left = node
return node return node
""" 删除结点 """
def remove(self, num: int) -> Optional[TreeNode]: def remove(self, num: int) -> Optional[TreeNode]:
""" 删除结点 """
root = self.root root = self.root
# 若树为空,直接提前返回 # 若树为空,直接提前返回
if root is None: if root is None:
@ -119,8 +120,8 @@ class BinarySearchTree:
cur.val = tmp cur.val = tmp
return cur return cur
""" 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """
def get_inorder_next(self, root: Optional[TreeNode]) -> Optional[TreeNode]: def get_inorder_next(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
""" 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """
if root is None: if root is None:
return root return root
# 循环访问左子结点,直到叶结点时为最小结点,跳出 # 循环访问左子结点,直到叶结点时为最小结点,跳出

View file

@ -7,7 +7,7 @@ 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 include import * from modules import *
""" Driver Code """ """ Driver Code """

View file

@ -6,11 +6,11 @@ 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 include import * from modules import *
""" 层序遍历 """
def level_order(root: Optional[TreeNode]): def level_order(root: Optional[TreeNode]):
""" 层序遍历 """
# 初始化队列,加入根结点 # 初始化队列,加入根结点
queue = collections.deque() queue = collections.deque()
queue.append(root) queue.append(root)

View file

@ -6,13 +6,11 @@ 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 include import * from modules import *
res = []
""" 前序遍历 """
def pre_order(root: Optional[TreeNode]): def pre_order(root: Optional[TreeNode]):
""" 前序遍历 """
if root is None: if root is None:
return return
# 访问优先级:根结点 -> 左子树 -> 右子树 # 访问优先级:根结点 -> 左子树 -> 右子树
@ -20,8 +18,8 @@ def pre_order(root: Optional[TreeNode]):
pre_order(root=root.left) pre_order(root=root.left)
pre_order(root=root.right) pre_order(root=root.right)
""" 中序遍历 """
def in_order(root: Optional[TreeNode]): def in_order(root: Optional[TreeNode]):
""" 中序遍历 """
if root is None: if root is None:
return return
# 访问优先级:左子树 -> 根结点 -> 右子树 # 访问优先级:左子树 -> 根结点 -> 右子树
@ -29,8 +27,8 @@ def in_order(root: Optional[TreeNode]):
res.append(root.val) res.append(root.val)
in_order(root=root.right) in_order(root=root.right)
""" 后序遍历 """
def post_order(root: Optional[TreeNode]): def post_order(root: Optional[TreeNode]):
""" 后序遍历 """
if root is None: if root is None:
return return
# 访问优先级:左子树 -> 右子树 -> 根结点 # 访问优先级:左子树 -> 右子树 -> 根结点
@ -38,6 +36,7 @@ def post_order(root: Optional[TreeNode]):
post_order(root=root.right) post_order(root=root.right)
res.append(root.val) res.append(root.val)
res = []
""" Driver Code """ """ Driver Code """
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -4,8 +4,6 @@ Created Time: 2021-12-11
Author: Krahets (krahets@163.com), msk397 (machangxinq@gmail.com) Author: Krahets (krahets@163.com), msk397 (machangxinq@gmail.com)
""" """
import copy
import queue
from .binary_tree import TreeNode, tree_to_list, list_to_tree from .binary_tree import TreeNode, tree_to_list, list_to_tree
from .linked_list import ListNode, linked_list_to_list from .linked_list import ListNode, linked_list_to_list

View file

@ -4,15 +4,15 @@
from typing import List from typing import List
# 顶点类
class Vertex: class Vertex:
""" 顶点类 """
def __init__(self, val: int) -> None: def __init__(self, val: int) -> None:
self.val = val self.val = val
# 输入值列表 vals ,返回顶点列表 vets
def vals_to_vets(vals: List[int]) -> List['Vertex']: 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]
# 输入顶点列表 vets ,返回值列表 vals
def vets_to_vals(vets: List['Vertex']) -> List[int]: 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]

View file

@ -148,19 +148,19 @@ class QuickSortTailCall {
/* Driver Code */ /* Driver Code */
/* 快速排序 */ /* 快速排序 */
const nums = [4, 1, 3, 1, 5, 2]; const nums = [2, 4, 1, 0, 3, 5];
const quickSort = new QuickSort(); const quickSort = new QuickSort();
quickSort.quickSort(nums, 0, nums.length - 1); quickSort.quickSort(nums, 0, nums.length - 1);
console.log('快速排序完成后 nums =', nums); console.log('快速排序完成后 nums =', nums);
/* 快速排序(中位基准数优化) */ /* 快速排序(中位基准数优化) */
const nums1 = [4, 1, 3, 1, 5, 2]; const nums1 = [2, 4, 1, 0, 3, 5];
const quickSortMedian = new QuickSort(); const quickSortMedian = new QuickSort();
quickSortMedian.quickSort(nums1, 0, nums1.length - 1); quickSortMedian.quickSort(nums1, 0, nums1.length - 1);
console.log('快速排序(中位基准数优化)完成后 nums =', nums1); console.log('快速排序(中位基准数优化)完成后 nums =', nums1);
/* 快速排序(尾递归优化) */ /* 快速排序(尾递归优化) */
const nums2 = [4, 1, 3, 1, 5, 2]; const nums2 = [2, 4, 1, 0, 3, 5];
const quickSortTailCall = new QuickSort(); const quickSortTailCall = new QuickSort();
quickSortTailCall.quickSort(nums2, 0, nums2.length - 1); quickSortTailCall.quickSort(nums2, 0, nums2.length - 1);
console.log('快速排序(尾递归优化)完成后 nums =', nums2); console.log('快速排序(尾递归优化)完成后 nums =', nums2);

View file

@ -188,7 +188,7 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
```javascript title="avl_tree.js" ```javascript title="avl_tree.js"
[class]{AVLTree}-[func]{height} [class]{AVLTree}-[func]{height}
[class]{AVLTree}-[func]{updateHeight} [class]{AVLTree}-[func]{#updateHeight}
``` ```
=== "TypeScript" === "TypeScript"
@ -354,7 +354,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
=== "JavaScript" === "JavaScript"
```javascript title="avl_tree.js" ```javascript title="avl_tree.js"
[class]{AVLTree}-[func]{rightRotate} [class]{AVLTree}-[func]{#rightRotate}
``` ```
=== "TypeScript" === "TypeScript"
@ -426,7 +426,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
=== "JavaScript" === "JavaScript"
```javascript title="avl_tree.js" ```javascript title="avl_tree.js"
[class]{AVLTree}-[func]{leftRotate} [class]{AVLTree}-[func]{#leftRotate}
``` ```
=== "TypeScript" === "TypeScript"
@ -519,7 +519,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
=== "JavaScript" === "JavaScript"
```javascript title="avl_tree.js" ```javascript title="avl_tree.js"
[class]{AVLTree}-[func]{rotate} [class]{AVLTree}-[func]{#rotate}
``` ```
=== "TypeScript" === "TypeScript"
@ -595,7 +595,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
```javascript title="avl_tree.js" ```javascript title="avl_tree.js"
[class]{AVLTree}-[func]{insert} [class]{AVLTree}-[func]{insert}
[class]{AVLTree}-[func]{insertHelper} [class]{AVLTree}-[func]{#insertHelper}
``` ```
=== "TypeScript" === "TypeScript"
@ -687,9 +687,9 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
```javascript title="avl_tree.js" ```javascript title="avl_tree.js"
[class]{AVLTree}-[func]{remove} [class]{AVLTree}-[func]{remove}
[class]{AVLTree}-[func]{removeHelper} [class]{AVLTree}-[func]{#removeHelper}
[class]{AVLTree}-[func]{getInOrderNext} [class]{AVLTree}-[func]{#getInOrderNext}
``` ```
=== "TypeScript" === "TypeScript"