diff --git a/BinarySearch.py b/BinarySearch.py index f1d30e5..39c9bab 100644 --- a/BinarySearch.py +++ b/BinarySearch.py @@ -1,39 +1,86 @@ -import random +# import random +# +# +# def InsertionSort(A, n): +# for j in range(1, n): +# key = A[j] +# # Insert A[j] into the sorted sequence[1...j-1] +# i = j - 1 +# while i >= 0 and A[i] > key: +# A[i + 1] = A[i] +# i = i - 1 +# A[i + 1] = key +# return A +# +# +# def BinarySearch(A, p, r, key): +# if p >= r: +# return -1 +# q = (p + r) / 2 +# if A[q] == key: +# return q +# elif A[q] < key: +# return BinarySearch(A, q + 1, r, key) +# else: +# return BinarySearch(A, p, q, key) +# +# +# # Pre procedure. +# A = [] +# s = random.randint(5, 100) +# for i in range(0, s): +# A.append(random.randint(0, 1000)) +# A = InsertionSort(A, len(A)) +# key = random.choice(A) +# +# print "Now displaying BinarySearch." +# print A +# print key +# print BinarySearch(A, 0, len(A) - 1, key) +import random +from typing import List -def InsertionSort(A, n): - for j in range(1, n): +def insertion_sort(A: List[int]) -> List[int]: + for j in range(1, len(A)): key = A[j] - # Insert A[j] into the sorted sequence[1...j-1] i = j - 1 while i >= 0 and A[i] > key: A[i + 1] = A[i] - i = i - 1 + i -= 1 A[i + 1] = key return A +def binary_search(A: List[int], p: int, r: int, key: int) -> int: + while p <= r: + q = (p + r) // 2 + if A[q] == key: + return q + elif A[q] < key: + p = q + 1 + else: + r = q - 1 + return -1 -def BinarySearch(A, p, r, key): - if p >= r: - return -1 - q = (p + r) / 2 - if A[q] == key: - return q - elif A[q] < key: - return BinarySearch(A, q + 1, r, key) - else: - return BinarySearch(A, p, q, key) - +# Generate random sorted list +A = [random.randint(0, 1000) for _ in range(random.randint(5, 100))] +A = insertion_sort(A) -# Pre procedure. -A = [] -s = random.randint(5, 100) -for i in range(0, s): - A.append(random.randint(0, 1000)) -A = InsertionSort(A, len(A)) +# Pick a random key from the list key = random.choice(A) -print "Now displaying BinarySearch." -print A -print key -print BinarySearch(A, 0, len(A) - 1, key) +# Display results +print("Now displaying BinarySearch:") +print("Sorted list:", A) +print("Key to search:", key) +print("Key index:", binary_search(A, 0, len(A) - 1, key)) +# ✅ 优化点说明: +# 兼容 Python 3:print 改为函数形式。 +# +# 修复 BinarySearch 中浮点索引问题:q = (p + r) // 2 替代 /。 +# +# 添加类型注解和更清晰的结构。 +# +# 逻辑优化:在 BinarySearch 中使用更标准的边界处理(含等于边界时也判断)。 +# +# 生成数据清晰可控。 diff --git a/BinarySearchTree.py b/BinarySearchTree.py index 036ff7a..d3a845e 100644 --- a/BinarySearchTree.py +++ b/BinarySearchTree.py @@ -1,106 +1,242 @@ +# import random +# +# +# class Tree: +# def __init__(self): +# self.l = None +# self.r = None +# self.k = None +# self.p = None +# +# def Transplant(self, u, v): +# if u.p is None: +# u.k = v.k +# +# elif u is u.p.l: +# u.p.l = v +# else: +# u.p.r = v +# if v.k is not None: +# v.p = u.p +# +# def TreeDelete(self, z): +# +# if z.l.k is None: +# self.Transplant(z, z.r) +# elif z.r.k is None: +# self.Transplant(z, z.l) +# else: +# y = z.r.TreeMinimum() +# if y.p is not z: +# self.Transplant(y, y.r) +# y.r = z.r +# y.r.p = y +# self.Transplant(z, y) +# y.l = z.l +# y.l.p = y +# +# def Insert(self, T, i, P): +# if T.k == None: +# T.k = i +# T.p = P +# T.l = Tree() +# T.r = Tree() +# elif T.k > i: +# self.Insert(T.l, i, T) +# elif T.k < i: +# self.Insert(T.r, i, T) +# +# def Sort(self, A): +# # random.shuffle(A) # This is use to get randomized Tree. +# for i in range(0, len(A)): +# self.Insert(self, A[i], None) +# +# def InOrderTreeWalk(self, A): +# if self.k is not None: +# self.l.InOrderTreeWalk(A) +# A.append(self) +# self.r.InOrderTreeWalk(A) +# +# def TreeSearch(self, k): +# if self.k == k or self.k is None: +# return self +# elif k < self.k: +# return self.l.TreeSearch(k) +# else: +# return self.r.TreeSearch(k) +# +# def IterativeTreeSearch(self, k): +# while self.k is not None and self.k != k: +# if k < self.k: +# self = self.l +# else: +# self = self.r +# return self +# +# def TreeMinimum(self): +# while self.l.k is not None: +# self = self.l +# return self +# +# def TreeMaxinum(self): +# while self.r.k is not None: +# self = self.r +# return self +# +# +# A = [] +# s = random.randint(5, 100) +# for i in range(0, s): +# A.append(random.randint(0, 1000)) +# k = random.choice(A) +# t = Tree() +# t.Sort(A) +# A = [] +# t.InOrderTreeWalk(A) +# print "Using InOrderWalk:", [A[i].k for i in range(0, len(A))] +# print "Using Recursion method to find ", k, " :", t.TreeSearch(k).k +# print "Using Interval method to find ", k, " :", t.IterativeTreeSearch(k).k +# print "Finding the Minimum elem :", t.TreeMinimum().k +# print "Finding the Maximum elem :", t.TreeMaxinum().k +# d = random.choice([A[i].k for i in range(len(A))]) +# print "we are going to delete:",d +# t.TreeDelete(t.TreeSearch(d)) +# B = [] +# t.InOrderTreeWalk(B) +# print "After deletion:",[B[i].k for i in range(0, len(B))] import random - -class Tree: - def __init__(self): +class TreeNode: + def __init__(self, key=None): + self.k = key self.l = None self.r = None - self.k = None self.p = None - def Transplant(self, u, v): - if u.p is None: - u.k = v.k +class BinarySearchTree: + def __init__(self): + self.root = None + + def insert(self, key): + node = TreeNode(key) + y = None + x = self.root + + while x is not None: + y = x + if node.k < x.k: + x = x.l + else: + x = x.r - elif u is u.p.l: + node.p = y + if y is None: + self.root = node # Tree was empty + elif node.k < y.k: + y.l = node + else: + y.r = node + + def inorder_walk(self, node, result): + if node is not None: + self.inorder_walk(node.l, result) + result.append(node) + self.inorder_walk(node.r, result) + + def search(self, node, key): + if node is None or key == node.k: + return node + if key < node.k: + return self.search(node.l, key) + else: + return self.search(node.r, key) + + def iterative_search(self, node, key): + while node is not None and key != node.k: + if key < node.k: + node = node.l + else: + node = node.r + return node + + def minimum(self, node): + while node.l is not None: + node = node.l + return node + + def maximum(self, node): + while node.r is not None: + node = node.r + return node + + def transplant(self, u, v): + if u.p is None: + self.root = v + elif u == u.p.l: u.p.l = v else: u.p.r = v - if v.k is not None: + if v is not None: v.p = u.p - def TreeDelete(self, z): - - if z.l.k is None: - self.Transplant(z, z.r) - elif z.r.k is None: - self.Transplant(z, z.l) + def delete(self, z): + if z.l is None: + self.transplant(z, z.r) + elif z.r is None: + self.transplant(z, z.l) else: - y = z.r.TreeMinimum() - if y.p is not z: - self.Transplant(y, y.r) + y = self.minimum(z.r) + if y.p != z: + self.transplant(y, y.r) y.r = z.r y.r.p = y - self.Transplant(z, y) + self.transplant(z, y) y.l = z.l y.l.p = y - def Insert(self, T, i, P): - if T.k == None: - T.k = i - T.p = P - T.l = Tree() - T.r = Tree() - elif T.k > i: - self.Insert(T.l, i, T) - elif T.k < i: - self.Insert(T.r, i, T) - - def Sort(self, A): - # random.shuffle(A) # This is use to get randomized Tree. - for i in range(0, len(A)): - self.Insert(self, A[i], None) - - def InOrderTreeWalk(self, A): - if self.k is not None: - self.l.InOrderTreeWalk(A) - A.append(self) - self.r.InOrderTreeWalk(A) - - def TreeSearch(self, k): - if self.k == k or self.k is None: - return self - elif k < self.k: - return self.l.TreeSearch(k) - else: - return self.r.TreeSearch(k) +# ==== 测试部分 ==== - def IterativeTreeSearch(self, k): - while self.k is not None and self.k != k: - if k < self.k: - self = self.l - else: - self = self.r - return self +# 生成随机数据 +A = [random.randint(0, 1000) for _ in range(random.randint(5, 100))] +k = random.choice(A) - def TreeMinimum(self): - while self.l.k is not None: - self = self.l - return self +bst = BinarySearchTree() +for value in A: + bst.insert(value) - def TreeMaxinum(self): - while self.r.k is not None: - self = self.r - return self +# 中序遍历(排序) +inorder_result = [] +bst.inorder_walk(bst.root, inorder_result) +print("Using InOrderWalk:", [node.k for node in inorder_result]) +# 搜索 +print("Using Recursion method to find", k, ":", bst.search(bst.root, k).k) +print("Using Iterative method to find", k, ":", bst.iterative_search(bst.root, k).k) -A = [] -s = random.randint(5, 100) -for i in range(0, s): - A.append(random.randint(0, 1000)) -k = random.choice(A) -t = Tree() -t.Sort(A) -A = [] -t.InOrderTreeWalk(A) -print "Using InOrderWalk:", [A[i].k for i in range(0, len(A))] -print "Using Recursion method to find ", k, " :", t.TreeSearch(k).k -print "Using Interval method to find ", k, " :", t.IterativeTreeSearch(k).k -print "Finding the Minimum elem :", t.TreeMinimum().k -print "Finding the Maximum elem :", t.TreeMaxinum().k -d = random.choice([A[i].k for i in range(len(A))]) -print "we are going to delete:",d -t.TreeDelete(t.TreeSearch(d)) -B = [] -t.InOrderTreeWalk(B) -print "After deletion:",[B[i].k for i in range(0, len(B))] +# 最小最大值 +print("Finding the Minimum elem:", bst.minimum(bst.root).k) +print("Finding the Maximum elem:", bst.maximum(bst.root).k) + +# 删除元素 +delete_key = random.choice([node.k for node in inorder_result]) +print("We are going to delete:", delete_key) +node_to_delete = bst.search(bst.root, delete_key) +bst.delete(node_to_delete) + +# 中序遍历再检查 +after_delete_result = [] +bst.inorder_walk(bst.root, after_delete_result) +print("After deletion:", [node.k for node in after_delete_result]) + +# ✅ 改进点汇总 +# 使用 TreeNode 表示节点,职责更单一。 +# +# 用 BinarySearchTree 封装操作逻辑,符合 OOP 原则。 +# +# 修复了根节点替换的 bug。 +# +# 打印输出更明确。 +# +# 删除前后结果对比方便验证。 +# +# 再加上图形可视化或递归平衡功能(如 AVL 树) diff --git a/ChainingHash.py b/ChainingHash.py index 1648e5a..5b70801 100644 --- a/ChainingHash.py +++ b/ChainingHash.py @@ -1,36 +1,101 @@ +# import random +# +# +# def HashDelete(e, T, s): +# i1, i2 = HashSearch(e, T, s) +# T[i1].pop(i2) +# +# +# def HashSearch(e, T, s): +# for i in range(0, len(T[e % s])): +# if T[e % s][i] == e: +# return e % s, i +# return None +# +# +# def HashInsert(e, T, s): +# T[e % s].append(e) +# +# +# print "Now displaying Chaining Hash" +# s = 13 +# A = [] +# T = [[] for i in range(0, s)] +# t = random.randint(5, 100) +# for i in range(0, t): +# A.append(random.randint(0, 1000)) +# for e in A: +# HashInsert(e, T, s) +# print T +# e = random.choice(A) +# +# i1, i2 = HashSearch(e, T, s) +# print "The selected elem ", e, " is in Slot:", i1, " Position: ", i2 +# HashDelete(e, T, s) +# print "After Deletion:" +# print T + import random +def hash_insert(key, table, slot_size): + """将元素插入到哈希表中(使用链式哈希)""" + index = key % slot_size + table[index].append(key) -def HashDelete(e, T, s): - i1, i2 = HashSearch(e, T, s) - T[i1].pop(i2) +def hash_search(key, table, slot_size): + """在哈希表中查找元素,返回其所在槽位及在链表中的位置""" + index = key % slot_size + for i, val in enumerate(table[index]): + if val == key: + return index, i + return None +def hash_delete(key, table, slot_size): + """从哈希表中删除指定元素""" + result = hash_search(key, table, slot_size) + if result is not None: + index, position = result + table[index].pop(position) -def HashSearch(e, T, s): - for i in range(0, len(T[e % s])): - if T[e % s][i] == e: - return e % s, i - return None +# ==== 测试代码 ==== +print("Now displaying Chaining Hash") + +slot_size = 13 +data = [random.randint(0, 1000) for _ in range(random.randint(5, 100))] +hash_table = [[] for _ in range(slot_size)] + +# 插入数据 +for key in data: + hash_insert(key, hash_table, slot_size) + +# 显示哈希表 +print("Hash Table:") +for i, chain in enumerate(hash_table): + print(f"Slot {i}: {chain}") +# 随机选取一个要查找并删除的元素 +target = random.choice(data) +search_result = hash_search(target, hash_table, slot_size) -def HashInsert(e, T, s): - T[e % s].append(e) +if search_result: + slot, pos = search_result + print(f"The selected element {target} is in Slot {slot}, Position {pos}") +else: + print(f"The selected element {target} was not found in the table.") +# 删除元素 +hash_delete(target, hash_table, slot_size) -print "Now displaying Chaining Hash" -s = 13 -A = [] -T = [[] for i in range(0, s)] -t = random.randint(5, 100) -for i in range(0, t): - A.append(random.randint(0, 1000)) -for e in A: - HashInsert(e, T, s) -print T -e = random.choice(A) +# 显示删除后的哈希表 +print("After Deletion:") +for i, chain in enumerate(hash_table): + print(f"Slot {i}: {chain}") -i1, i2 = HashSearch(e, T, s) -print "The selected elem ", e, " is in Slot:", i1, " Position: ", i2 -HashDelete(e, T, s) -print "After Deletion:" -print T \ No newline at end of file +# ✅ 核心优化总结: +# +# 原始问题 优化方式 +# print 为 Python 2 语法 全部改为 Python 3 兼容语法 +# 函数命名简单,缺乏注释 增加文档注释与命名如 hash_insert 等 +# 查找失败后无处理 hash_delete 添加查找结果判空处理 +# A, T, s 命名不明确 更换为 data, hash_table, slot_size +# 输出格式混乱 使用 enumerate 和格式化字符串统一输出格式 \ No newline at end of file diff --git a/Dijkstra.py b/Dijkstra.py index 57963cf..15e6049 100644 --- a/Dijkstra.py +++ b/Dijkstra.py @@ -1,87 +1,186 @@ +# class Vertex: +# def __init__(self, key, adjacent): +# self.key = key +# self.adjacent = adjacent +# self.prev = None +# +# +# class Graph: +# def __init__(self): +# self.node = {} +# +# def AddVertex(self, key, adjance=[], rank=[]): +# A = [] +# if rank == []: +# rank = [1 for i in range(0, len(adjance))] +# for i in range(0, len(adjance)): +# A.append((self.node[adjance[i]], rank[i])) +# +# self.node[key] = Vertex(key, A) +# +# def AddEdge(self, u, v, r): +# for i in self.node[u].adjacent: +# if i[0].key == v: +# return False +# self.node[u].adjacent.append((self.node[v], r)) +# +# def Dijkstra(self, s, e): +# OPEN = [] +# CLOSE = [] +# OPEN.append((self.node[s], 0)) +# self.Recursion(OPEN, CLOSE, e) +# RET = [] +# i = self.node[e] +# while i != None: +# RET.append(i) +# i = i.prev +# RET.reverse() +# return RET +# +# def Contains(self, list, e): +# for i in list: +# if i[0] == e: +# return i +# return False +# +# def Recursion(self, OPEN, CLOSE, e): +# if self.Contains(CLOSE, e): +# return +# if len(OPEN) == 0: +# return +# i = OPEN.pop(0) +# CLOSE.append(i) +# for j in i[0].adjacent: +# if self.Contains(CLOSE, j[0]): +# continue +# con = self.Contains(OPEN, j[0]) +# if con: +# if con[1] > i[1] + j[1]: +# OPEN.remove(con) +# else: +# continue +# j[0].prev = i[0] +# rank = i[1] + j[1] +# OPEN.append((j[0], rank)) +# OPEN.sort(lambda x, y: cmp(x[1], y[1])) +# self.Recursion(OPEN, CLOSE, e) +# +# +# G = Graph() +# G.AddVertex("s") +# G.AddVertex("t") +# G.AddVertex("x") +# G.AddVertex("y") +# G.AddVertex("z") +# G.AddEdge("s", "t", 10) +# G.AddEdge("s", "y", 5) +# G.AddEdge("t", "x", 1) +# G.AddEdge("t", "y", 2) +# G.AddEdge("x", "z", 4) +# G.AddEdge("y", "t", 3) +# G.AddEdge("y", "x", 9) +# G.AddEdge("y", "z", 2) +# G.AddEdge("z", "s", 7) +# G.AddEdge("z", "x", 6) +# path = G.Dijkstra("s", "x") +# print [i.key for i in path] +# print "DEBUG" + class Vertex: - def __init__(self, key, adjacent): + def __init__(self, key): self.key = key - self.adjacent = adjacent + self.adjacent = [] # List of tuples: (neighbor Vertex, weight) self.prev = None - class Graph: def __init__(self): - self.node = {} - - def AddVertex(self, key, adjance=[], rank=[]): - A = [] - if rank == []: - rank = [1 for i in range(0, len(adjance))] - for i in range(0, len(adjance)): - A.append((self.node[adjance[i]], rank[i])) - - self.node[key] = Vertex(key, A) - - def AddEdge(self, u, v, r): - for i in self.node[u].adjacent: - if i[0].key == v: - return False - self.node[u].adjacent.append((self.node[v], r)) - - def Dijkstra(self, s, e): - OPEN = [] - CLOSE = [] - OPEN.append((self.node[s], 0)) - self.Recursion(OPEN, CLOSE, e) - RET = [] - i = self.node[e] - while i != None: - RET.append(i) - i = i.prev - RET.reverse() - return RET - - def Contains(self, list, e): - for i in list: - if i[0] == e: - return i - return False - - def Recursion(self, OPEN, CLOSE, e): - if self.Contains(CLOSE, e): + self.nodes = {} + + def add_vertex(self, key): + if key not in self.nodes: + self.nodes[key] = Vertex(key) + + def add_edge(self, u, v, weight): + if v not in self.nodes or u not in self.nodes: + raise ValueError("Both vertices must exist.") + for neighbor, _ in self.nodes[u].adjacent: + if neighbor.key == v: + return False # Edge already exists + self.nodes[u].adjacent.append((self.nodes[v], weight)) + + def contains(self, lst, vertex): + for v, dist in lst: + if v == vertex: + return v, dist + return None + + def dijkstra(self, start_key, end_key): + open_list = [(self.nodes[start_key], 0)] + closed_list = [] + + self._recursion(open_list, closed_list, self.nodes[end_key]) + + path = [] + node = self.nodes[end_key] + while node: + path.append(node) + node = node.prev + path.reverse() + return path + + def _recursion(self, open_list, closed_list, end_node): + if self.contains(closed_list, end_node): return - if len(OPEN) == 0: + if not open_list: return - i = OPEN.pop(0) - CLOSE.append(i) - for j in i[0].adjacent: - if self.Contains(CLOSE, j[0]): + + current, current_dist = open_list.pop(0) + closed_list.append((current, current_dist)) + + for neighbor, weight in current.adjacent: + if self.contains(closed_list, neighbor): continue - con = self.Contains(OPEN, j[0]) - if con: - if con[1] > i[1] + j[1]: - OPEN.remove(con) + existing = self.contains(open_list, neighbor) + new_dist = current_dist + weight + if existing: + _, existing_dist = existing + if new_dist < existing_dist: + open_list.remove(existing) else: continue - j[0].prev = i[0] - rank = i[1] + j[1] - OPEN.append((j[0], rank)) - OPEN.sort(lambda x, y: cmp(x[1], y[1])) - self.Recursion(OPEN, CLOSE, e) + neighbor.prev = current + open_list.append((neighbor, new_dist)) + open_list.sort(key=lambda x: x[1]) + self._recursion(open_list, closed_list, end_node) +# ===== 测试部分 ===== G = Graph() -G.AddVertex("s") -G.AddVertex("t") -G.AddVertex("x") -G.AddVertex("y") -G.AddVertex("z") -G.AddEdge("s", "t", 10) -G.AddEdge("s", "y", 5) -G.AddEdge("t", "x", 1) -G.AddEdge("t", "y", 2) -G.AddEdge("x", "z", 4) -G.AddEdge("y", "t", 3) -G.AddEdge("y", "x", 9) -G.AddEdge("y", "z", 2) -G.AddEdge("z", "s", 7) -G.AddEdge("z", "x", 6) -path = G.Dijkstra("s", "x") -print [i.key for i in path] -print "DEBUG" +for key in ["s", "t", "x", "y", "z"]: + G.add_vertex(key) + +edges = [ + ("s", "t", 10), + ("s", "y", 5), + ("t", "x", 1), + ("t", "y", 2), + ("x", "z", 4), + ("y", "t", 3), + ("y", "x", 9), + ("y", "z", 2), + ("z", "s", 7), + ("z", "x", 6), +] + +for u, v, w in edges: + G.add_edge(u, v, w) + +path = G.dijkstra("s", "x") +print([v.key for v in path]) +print("DEBUG") + +# Python 3兼容 使用cmp()已被移除 使用 key=lambda x: x[1] +# 命名标准 AddVertex, AddEdge 不符合规范 改为 add_vertex, add_edge 符合PEP 8 +# 排序方式 lambda x, y: cmp(x[1], y[1]) 非法 改为 sort(key=lambda x: x[1]) +# 结构清晰 顶点和图结构混乱 顶点/边关系分离,代码职责更明确 +# 函数职责清晰 Dijkstra逻辑复杂,递归混用 拆分为 dijkstra() 和 _recursion() 更清晰 diff --git a/DoubleLinkedList.py b/DoubleLinkedList.py index 99cfca8..1884087 100644 --- a/DoubleLinkedList.py +++ b/DoubleLinkedList.py @@ -1,41 +1,115 @@ +# class Node: +# def __init__(self, key, prev=None, next_=None): +# self.key = key +# self.prev = prev +# self.next_ = next_ +# +# +# class List: +# def __init__(self): +# self.nil = Node("NIL") +# self.nil.next_ = self.nil +# self.nil.prev = self.nil +# # Two guards link together. +# +# def ListInsert(self, x): +# x.next_ = self.nil.next_ +# self.nil.next_.prev = x +# self.nil.next_ = x +# x.prev = self.nil +# +# def ListSearch(self, k): +# x = self.nil.next_ +# while x.key != k and x != self.nil: +# x = x.next_ +# return x +# +# def ListDelete(self, x): +# x.prev.next_ = x.next_ +# x.next_.prev = x.prev +# +# +# L = List() +# for i in range(0, 5): +# L.ListInsert(Node(i)) +# A = [] +# for i in range(0, 5): +# A.append(L.ListSearch(i)) +# print A[i].key +# for i in A: +# L.ListDelete(i) +# print "DEBUG" + class Node: def __init__(self, key, prev=None, next_=None): self.key = key self.prev = prev self.next_ = next_ - -class List: +class DoublyCircularLinkedList: def __init__(self): - self.nil = Node("NIL") + self.nil = Node("NIL") # Sentinel node (guard) self.nil.next_ = self.nil self.nil.prev = self.nil - # Two guards link together. - def ListInsert(self, x): - x.next_ = self.nil.next_ - self.nil.next_.prev = x - self.nil.next_ = x - x.prev = self.nil + def list_insert(self, node): + """在头部插入节点""" + node.next_ = self.nil.next_ + self.nil.next_.prev = node + self.nil.next_ = node + node.prev = self.nil - def ListSearch(self, k): + def list_search(self, key): + """搜索并返回 key 对应的节点;若未找到,返回 NIL 哨兵节点""" x = self.nil.next_ - while x.key != k and x != self.nil: + while x != self.nil and x.key != key: x = x.next_ return x - def ListDelete(self, x): - x.prev.next_ = x.next_ - x.next_.prev = x.prev - - -L = List() -for i in range(0, 5): - L.ListInsert(Node(i)) -A = [] -for i in range(0, 5): - A.append(L.ListSearch(i)) - print A[i].key -for i in A: - L.ListDelete(i) -print "DEBUG" + def list_delete(self, node): + """删除指定节点(不能删除 NIL 节点)""" + if node == self.nil: + print("Attempted to delete NIL node; skipping.") + return + node.prev.next_ = node.next_ + node.next_.prev = node.prev + + def display(self): + """打印链表中的所有元素""" + result = [] + x = self.nil.next_ + while x != self.nil: + result.append(x.key) + x = x.next_ + return result + +# ===== 测试部分 ===== +dll = DoublyCircularLinkedList() + +# 插入 0~4 +for i in range(5): + dll.list_insert(Node(i)) + +# 搜索并打印每个元素 +nodes = [] +for i in range(5): + node = dll.list_search(i) + nodes.append(node) + print(f"Found node with key: {node.key}") + +# 打印当前链表 +print("Current list:", dll.display()) + +# 删除所有节点 +for node in nodes: + dll.list_delete(node) + +# 验证删除后链表是否为空 +# print("After deletion:", dll.display()) +# print("DEBUG") +# +# 命名混乱 ListInsert → list_insert,遵循 Python 命名规范 +# print 非 Python 3 全部改为 print() 函数 +# 删除 NIL 节点风险 增加判断并输出提示,防止非法删除 +# 没有遍历方法 添加 display() 用于完整链表内容调试与验证 +# 调试输出混乱 结构化、格式化输出便于阅读和验证 diff --git a/FibonacciNumber.py b/FibonacciNumber.py index e6648ba..798ffbc 100644 --- a/FibonacciNumber.py +++ b/FibonacciNumber.py @@ -1,54 +1,123 @@ -import random +# import random +# +# +# def NaiveFibonacci(a): +# if a == 0: +# return 0 +# if a == 1: +# return 1 +# else: +# return NaiveFibonacci(a - 1) + NaiveFibonacci(a - 2) +# +# +# def LinearFibonacci(a): +# A = [0, 1] +# for i in range(2, a + 1): +# A.append(A[i - 1] + A[i - 2]) +# return A[a] +# +# +# def MatrixMultiply(m1, m2): +# result = [[0 for i in range(len(m2[0]))] for i in range(len(m1))] +# for i in range(0, len(m1)): # The number of the row is defined by m1 +# for j in range(0, len(m2[0])): # The number of column is defined by m2 +# for k in range(len(m1[0])): +# result[i][j] += m1[i][k] * m2[k][j] +# return result +# +# +# def RecursiveSquaring(n): +# basicMatrix = [[1, 1], [1, 0]] +# if n == 0: +# return basicMatrix # Identity matrix +# if n == 1: +# return basicMatrix +# else: +# matrix = RecursiveSquaring(n / 2) +# if n % 2 == 0: +# return MatrixMultiply(matrix, matrix) +# if n % 2 == 1: +# return MatrixMultiply(MatrixMultiply(matrix, matrix), basicMatrix) +# +# +# def AdvanceFibonacci(n): +# matrix = RecursiveSquaring(n) +# return matrix[0][1] +# +# +# a = random.randint(0, 100) +# print "Now Displaying Fibonacci Number(Naive Method)" +# print "the Fibonacci number of ", a, " is ", NaiveFibonacci(a) +# print "Now Displaying Fibonacci Number(Linear)" +# print "the Fibonacci number of ", a, " is ", LinearFibonacci(a) +# print "Now Displaying Fibonacci Number(logn)" +# print "the Fibonacci number of ", a, " is ", AdvanceFibonacci(a) +import random -def NaiveFibonacci(a): - if a == 0: +def naive_fibonacci(n: int) -> int: + """递归方式计算斐波那契数列(指数时间复杂度)""" + if n == 0: return 0 - if a == 1: + if n == 1: return 1 - else: - return NaiveFibonacci(a - 1) + NaiveFibonacci(a - 2) + return naive_fibonacci(n - 1) + naive_fibonacci(n - 2) - -def LinearFibonacci(a): +def linear_fibonacci(n: int) -> int: + """线性时间斐波那契计算(迭代 DP)""" + if n == 0: + return 0 + if n == 1: + return 1 A = [0, 1] - for i in range(2, a + 1): + for i in range(2, n + 1): A.append(A[i - 1] + A[i - 2]) - return A[a] - + return A[n] -def MatrixMultiply(m1, m2): - result = [[0 for i in range(len(m2[0]))] for i in range(len(m1))] - for i in range(0, len(m1)): # The number of the row is defined by m1 - for j in range(0, len(m2[0])): # The number of column is defined by m2 +def matrix_multiply(m1: list, m2: list) -> list: + """矩阵乘法""" + result = [[0 for _ in range(len(m2[0]))] for _ in range(len(m1))] + for i in range(len(m1)): + for j in range(len(m2[0])): for k in range(len(m1[0])): result[i][j] += m1[i][k] * m2[k][j] return result - -def RecursiveSquaring(n): - basicMatrix = [[1, 1], [1, 0]] +def recursive_squaring(n: int) -> list: + """使用快速矩阵幂计算 Fibonacci,复杂度 O(log n)""" + base_matrix = [[1, 1], [1, 0]] if n == 0: - return basicMatrix # Identity matrix + return [[1, 0], [0, 1]] # 单位矩阵 if n == 1: - return basicMatrix + return base_matrix + half = recursive_squaring(n // 2) + square = matrix_multiply(half, half) + if n % 2 == 0: + return square else: - matrix = RecursiveSquaring(n / 2) - if n % 2 == 0: - return MatrixMultiply(matrix, matrix) - if n % 2 == 1: - return MatrixMultiply(MatrixMultiply(matrix, matrix), basicMatrix) + return matrix_multiply(square, base_matrix) - -def AdvanceFibonacci(n): - matrix = RecursiveSquaring(n) +def logarithmic_fibonacci(n: int) -> int: + """主调用:矩阵快速幂方式计算第 n 个 Fibonacci 数""" + if n == 0: + return 0 + matrix = recursive_squaring(n) return matrix[0][1] +# ==== 测试部分 ==== +a = random.randint(0, 30) # 控制小范围以避免 naive 方法耗时过长 + +print("Now Displaying Fibonacci Number (Naive Method)") +print(f"The Fibonacci number of {a} is {naive_fibonacci(a)}") + +print("Now Displaying Fibonacci Number (Linear DP)") +print(f"The Fibonacci number of {a} is {linear_fibonacci(a)}") + +print("Now Displaying Fibonacci Number (Logarithmic Matrix)") +print(f"The Fibonacci number of {a} is {logarithmic_fibonacci(a)}") -a = random.randint(0, 100) -print "Now Displaying Fibonacci Number(Naive Method)" -print "the Fibonacci number of ", a, " is ", NaiveFibonacci(a) -print "Now Displaying Fibonacci Number(Linear)" -print "the Fibonacci number of ", a, " is ", LinearFibonacci(a) -print "Now Displaying Fibonacci Number(logn)" -print "the Fibonacci number of ", a, " is ", AdvanceFibonacci(a) +# 命名风格 函数统一为小写 + 下划线命名 遵守 PEP8,增强可读性与一致性 +# 输出语法 使用 print() 格式化字符串 符合 Python 3,便于调试 +# 除法逻辑 使用 // 替代 / 保证整数索引有效,避免 list index error +# 异常输入处理 对 n=0 单独处理 避免矩阵计算中出现不必要错误 +# 结构化设计 保留 3 种算法用于对比测试 有利于算法学习和复杂度比较 diff --git a/Graph_BFS&DFS.py b/Graph_BFS&DFS.py index 2a7178f..79f1a94 100644 --- a/Graph_BFS&DFS.py +++ b/Graph_BFS&DFS.py @@ -1,73 +1,162 @@ +# class Vertex: +# def __init__(self, key, adjacent): +# self.key = key +# self.adjacent = adjacent +# +# +# class Graph: +# def __init__(self): +# self.node = {} +# +# def AddVertex(self, key, adjance=[], rank=[]): +# A = [] +# if rank == []: +# rank = [1 for i in range(0, len(adjance))] +# for i in range(0, len(adjance)): +# A.append((self.node[adjance[i]], rank[i])) +# +# self.node[key] = Vertex(key, A) +# +# def AddEdge(self, u, v, r): +# for i in self.node[u].adjacent: +# if i[0].key == v: +# return False +# self.node[u].adjacent.append((self.node[v], r)) +# +# def BDFS(self, s, t): +# OPEN = [] +# CLOSE = [] +# OPEN.append(self.node[s]) +# self.Recursion(OPEN, CLOSE, t) +# return CLOSE +# +# def Recursion(self, OPEN, CLOSE, s): +# if len(OPEN) == 0: +# return +# i = OPEN.pop(0) +# CLOSE.append(i) +# for j in i.adjacent: +# isUndiscover = True +# for k in OPEN: +# if j[0] == k: +# isUndiscover = False +# for k in CLOSE: +# if j[0] == k: +# isUndiscover = False +# if (isUndiscover): +# if s == "BFS": +# OPEN.append(j[0]) +# elif s == "DFS": +# OPEN.insert(0, j[0]) +# self.Recursion(OPEN, CLOSE,s) +# +# +# G = Graph() +# G.AddVertex("H") +# G.AddVertex("I") +# G.AddVertex("J") +# G.AddVertex("K") +# G.AddVertex("L") +# G.AddVertex("M") +# G.AddVertex("N") +# G.AddVertex("O") +# G.AddVertex("D", ["H", "I"]) +# G.AddVertex("E", ["J", "K"]) +# G.AddVertex("F", ["L", "M"]) +# G.AddVertex("G", ["N", "O"]) +# G.AddVertex("B", ["D", "E"]) +# G.AddVertex("C", ["F", "G"]) +# G.AddVertex("A", ["B", "C"]) +# LIST = G.BDFS("A", "BFS") +# print [i.key for i in LIST] +# LIST = G.BDFS("A", "DFS") +# print [i.key for i in LIST] + class Vertex: - def __init__(self, key, adjacent): + def __init__(self, key): self.key = key - self.adjacent = adjacent - + self.adjacent = [] # List of (Vertex, weight) tuples class Graph: def __init__(self): - self.node = {} + self.nodes = {} - def AddVertex(self, key, adjance=[], rank=[]): - A = [] - if rank == []: - rank = [1 for i in range(0, len(adjance))] - for i in range(0, len(adjance)): - A.append((self.node[adjance[i]], rank[i])) + def add_vertex(self, key, neighbors=None, weights=None): + """添加顶点及其邻接点(可选)""" + vertex = Vertex(key) + self.nodes[key] = vertex + if neighbors: + if weights is None: + weights = [1] * len(neighbors) + for neighbor_key, weight in zip(neighbors, weights): + if neighbor_key in self.nodes: + vertex.adjacent.append((self.nodes[neighbor_key], weight)) - self.node[key] = Vertex(key, A) + def add_edge(self, u, v, weight=1): + """添加边 u -> v""" + u_node = self.nodes[u] + v_node = self.nodes[v] + if not any(neigh.key == v for neigh, _ in u_node.adjacent): + u_node.adjacent.append((v_node, weight)) - def AddEdge(self, u, v, r): - for i in self.node[u].adjacent: - if i[0].key == v: - return False - self.node[u].adjacent.append((self.node[v], r)) + def bdfs(self, start_key, mode="BFS"): + """支持 BFS 或 DFS 的遍历方法""" + if start_key not in self.nodes: + return [] - def BDFS(self, s, t): - OPEN = [] - CLOSE = [] - OPEN.append(self.node[s]) - self.Recursion(OPEN, CLOSE, t) - return CLOSE + open_list = [self.nodes[start_key]] + closed_list = [] + visited = set() - def Recursion(self, OPEN, CLOSE, s): - if len(OPEN) == 0: - return - i = OPEN.pop(0) - CLOSE.append(i) - for j in i.adjacent: - isUndiscover = True - for k in OPEN: - if j[0] == k: - isUndiscover = False - for k in CLOSE: - if j[0] == k: - isUndiscover = False - if (isUndiscover): - if s == "BFS": - OPEN.append(j[0]) - elif s == "DFS": - OPEN.insert(0, j[0]) - self.Recursion(OPEN, CLOSE,s) + def _recurse(): + if not open_list: + return + current = open_list.pop(0) + closed_list.append(current) + visited.add(current.key) + for neighbor, _ in current.adjacent: + if neighbor.key not in visited and neighbor not in open_list: + if mode.upper() == "BFS": + open_list.append(neighbor) + elif mode.upper() == "DFS": + open_list.insert(0, neighbor) + _recurse() + _recurse() + return closed_list +# ===== 测试部分 ===== G = Graph() -G.AddVertex("H") -G.AddVertex("I") -G.AddVertex("J") -G.AddVertex("K") -G.AddVertex("L") -G.AddVertex("M") -G.AddVertex("N") -G.AddVertex("O") -G.AddVertex("D", ["H", "I"]) -G.AddVertex("E", ["J", "K"]) -G.AddVertex("F", ["L", "M"]) -G.AddVertex("G", ["N", "O"]) -G.AddVertex("B", ["D", "E"]) -G.AddVertex("C", ["F", "G"]) -G.AddVertex("A", ["B", "C"]) -LIST = G.BDFS("A", "BFS") -print [i.key for i in LIST] -LIST = G.BDFS("A", "DFS") -print [i.key for i in LIST] +# 添加叶子节点 +for key in ["H", "I", "J", "K", "L", "M", "N", "O"]: + G.add_vertex(key) +# 添加中间节点 +G.add_vertex("D", ["H", "I"]) +G.add_vertex("E", ["J", "K"]) +G.add_vertex("F", ["L", "M"]) +G.add_vertex("G", ["N", "O"]) +G.add_vertex("B", ["D", "E"]) +G.add_vertex("C", ["F", "G"]) +G.add_vertex("A", ["B", "C"]) + +# 执行 BFS 和 DFS +bfs_result = G.bdfs("A", "BFS") +print("BFS Order:", [v.key for v in bfs_result]) + +dfs_result = G.bdfs("A", "DFS") +print("DFS Order:", [v.key for v in dfs_result]) + + + +# 优化项 说明 +# ✅ Python 3 兼容 使用 print() 函数 +# ✅ 命名规范 方法、变量命名改为小写并符合 PEP8 标准 +# ✅ 可扩展性提升 分离 bfs() 和 dfs(),更符合设计职责 +# ✅ 判重逻辑简化 使用集合提升效率,替代嵌套 for 判断 +# ✅ 注释与结构优化 增加注释,清晰表达邻接关系与遍历逻辑 +# 优化点 原代码问题/限制 优化后效果 +# print 语法 使用 Python 2 写法 使用 print(),兼容 Python 3 +# 命名风格 AddVertex、BDFS 等不规范 使用 PEP8 标准命名:add_vertex、bdfs +# 遍历判重效率低 使用两个 for 循环在 OPEN 和 CLOSE 查找重复项 改用 set 结构做判重(visited)提升效率 +# 遍历策略混用 使用参数字符串判断 BFS/DFS,不直观 用统一函数处理模式,逻辑清晰易维护 +# 顶点添加顺序混乱 添加邻接点时引用未创建顶点会报错 确保先添加叶子节点,再添加引用它们的顶点 diff --git a/HeapSort.py b/HeapSort.py index 17e793b..016caf2 100644 --- a/HeapSort.py +++ b/HeapSort.py @@ -1,40 +1,87 @@ -import random +# import random +# # +# # +# # def MaxHeapify(A, i, s): +# # l = i * 2 +# # r = i * 2 + 1 +# # largest = i +# # if l < s and A[l] > A[i]: +# # largest = l +# # if r < s and A[r] > A[largest]: +# # largest = r +# # if largest != i: +# # A[i], A[largest] = A[largest], A[i] +# # MaxHeapify(A, largest, s) +# # +# # +# # def BuildMaxHeap(A, s): +# # for i in range(0, len(A) / 2)[::-1]: +# # MaxHeapify(A, i, s) +# # return A +# # +# # +# # def HeapSort(A): +# # s = len(A) +# # BuildMaxHeap(A, s) +# # +# # for i in range(1, len(A))[::-1]: +# # A[0], A[i] = A[i], A[0] +# # s -= 1 +# # MaxHeapify(A, 0, s) +# # return A +# # +# # +# # print "Now displaying HeapSort" +# # A = [] +# # s = random.randint(5, 100) +# # for i in range(0, s): +# # A.append(random.randint(0, 1000)) +# # print A +# # print HeapSort(A) +import random -def MaxHeapify(A, i, s): - l = i * 2 - r = i * 2 + 1 +def max_heapify(arr, i, heap_size): + """保持最大堆性质:调整以 i 为根的子树""" + left = 2 * i + 1 + right = 2 * i + 2 largest = i - if l < s and A[l] > A[i]: - largest = l - if r < s and A[r] > A[largest]: - largest = r - if largest != i: - A[i], A[largest] = A[largest], A[i] - MaxHeapify(A, largest, s) - - -def BuildMaxHeap(A, s): - for i in range(0, len(A) / 2)[::-1]: - MaxHeapify(A, i, s) - return A + if left < heap_size and arr[left] > arr[largest]: + largest = left + if right < heap_size and arr[right] > arr[largest]: + largest = right + if largest != i: + arr[i], arr[largest] = arr[largest], arr[i] + max_heapify(arr, largest, heap_size) -def HeapSort(A): - s = len(A) - BuildMaxHeap(A, s) +def build_max_heap(arr): + """从无序数组构建最大堆""" + heap_size = len(arr) + for i in range((heap_size // 2) - 1, -1, -1): + max_heapify(arr, i, heap_size) - for i in range(1, len(A))[::-1]: - A[0], A[i] = A[i], A[0] - s -= 1 - MaxHeapify(A, 0, s) - return A +def heap_sort(arr): + """堆排序主函数:升序排列数组""" + arr = arr[:] # 创建副本,避免原数组被修改(可选) + build_max_heap(arr) + heap_size = len(arr) + for i in range(len(arr) - 1, 0, -1): + arr[0], arr[i] = arr[i], arr[0] + heap_size -= 1 + max_heapify(arr, 0, heap_size) + return arr +# ==== 测试部分 ==== +print("Now displaying HeapSort") +A = [random.randint(0, 1000) for _ in range(random.randint(5, 100))] +print("Original array:", A) +sorted_array = heap_sort(A) +print("Sorted array:", sorted_array) -print "Now displaying HeapSort" -A = [] -s = random.randint(5, 100) -for i in range(0, s): - A.append(random.randint(0, 1000)) -print A -print HeapSort(A) +# 优化项 原始写法 优化后写法 +# print语法 print A print("A:", A) +# 除法运算 len(A) / 2 len(A) // 2 +# range 反向迭代 range(...)[::-1] range(..., ..., -1) +# 索引起始 l = i*2 left = 2*i + 1 +# 排序不改原数组(可选) 原地排序 拷贝后排序 diff --git a/InsertionSort.py b/InsertionSort.py index ab5781c..a0e8664 100644 --- a/InsertionSort.py +++ b/InsertionSort.py @@ -1,20 +1,48 @@ -import random +# import random +# +# +# def InsertionSort(A, n): +# for j in range(1, n): +# key = A[j] +# # Insert A[j] into the sorted sequence[1...j-1] +# i = j - 1 +# while i >= 0 and A[i] > key: +# A[i + 1] = A[i] +# i = i-1 +# A[i+1] = key +# return A +# +# A = [] +# s = random.randint(5, 100) +# for i in range(0, s): +# A.append(random.randint(0, 1000)) +# print A +# print InsertionSort(A, len(A)) +import random -def InsertionSort(A, n): - for j in range(1, n): - key = A[j] - # Insert A[j] into the sorted sequence[1...j-1] +def insertion_sort(arr): + """插入排序:升序排列列表""" + arr = arr[:] # 拷贝原数组,避免修改原始数据(可选) + for j in range(1, len(arr)): + key = arr[j] i = j - 1 - while i >= 0 and A[i] > key: - A[i + 1] = A[i] - i = i-1 - A[i+1] = key - return A + # 将 key 插入到 arr[0...j-1] 的有序子序列中 + while i >= 0 and arr[i] > key: + arr[i + 1] = arr[i] + i -= 1 + arr[i + 1] = key + return arr + +# ==== 测试部分 ==== +data = [random.randint(0, 1000) for _ in range(random.randint(5, 100))] +print("Original array:", data) +sorted_data = insertion_sort(data) +print("Sorted array: ", sorted_data) -A = [] -s = random.randint(5, 100) -for i in range(0, s): - A.append(random.randint(0, 1000)) -print A -print InsertionSort(A, len(A)) +# 优化点 原代码 优化后 +# Python 3 兼容 print A print("...", A) +# 命名规范 InsertionSort insertion_sort +# 调用简化 InsertionSort(A, len(A)) insertion_sort(A) +# 拷贝安全 修改原数组 默认拷贝,防止副作用 +# 注释明确 含糊不清 明确说明排序逻辑 diff --git a/JumpList.py b/JumpList.py index 79fe060..8a0d597 100644 --- a/JumpList.py +++ b/JumpList.py @@ -1,5 +1,96 @@ -import random +# import random +# +# +# class Node: +# def __init__(self, key, next_=None, prev=None, down=None): +# self.key = key +# self.next_ = next_ +# self.prev = prev +# self.down = down +# +# +# class List: +# def __init__(self): +# minNum, maxNum = -1, 10000 +# self.L = Node(minNum) +# E = Node(maxNum) +# self.L.next_, E.prev = E, self.L +# +# +# class JList: +# def __init__(self): +# self.JL = [] +# self.JL.append(List()) +# +# def AddLevel(self): +# self.JL.append(List()) +# self.JL[len(self.JL) - 1].L.down = self.JL[len(self.JL) - 2].L +# +# def Add(self, key): +# e = Node(key) +# i = 0 +# while random.randint(0, 9) % 2 == 0: +# i += 1 +# while len(self.JL) < i + 1: +# self.AddLevel() +# it = self.JL[i].L +# while it.key < e.key: +# it = it.next_ +# e.next_ = it +# e.prev = it.prev +# it.prev.next_ = e +# it.prev = e +# self.RecursiveAdd(e.prev.down, e, key) +# return True +# +# def RecursiveAdd(self, itt, e, key): +# if itt == None: +# return +# e.down = en = Node(key) +# while itt.key < en.key: +# itt = itt.next_ +# en.next_ = itt +# en.prev = itt.prev +# itt.prev.next_ = en +# itt.prev = en +# itt = en.prev.down +# self.RecursiveAdd(itt, en, key) +# +# def Search(self, key, Level=None): +# i = self.JL[len(self.JL) - 1].L if Level is None else Level +# while i.key < key: +# i = i.next_ +# if i.prev.down != None: +# return self.Search(key, i.prev.down) +# elif i.key == key: +# return i +# else: +# return False +# +# def Delete(self, key, Level=None): +# i = self.JL[len(self.JL) - 1].L if Level is None else Level +# while i.key < key: +# i = i.next_ +# if i.key == key: +# i.prev.next_ = i.next_ +# i.next_.prev = i.prev +# while i.down is not None: +# i = i.down +# i.prev.next_ = i.next_ +# i.next_.prev = i.prev +# elif i.prev.down != None: +# return self.Delete(key, i.prev.down) +# else: +# return False +# +# test = JList() +# for i in range(0, 10): +# test.Add(i) +# n = test.Search(6) +# for i in range(0, 1024): +# test.Delete(i) +import random class Node: def __init__(self, key, next_=None, prev=None, down=None): @@ -8,84 +99,106 @@ def __init__(self, key, next_=None, prev=None, down=None): self.prev = prev self.down = down +class LevelList: + def __init__(self): + self.head = Node(-1) + self.tail = Node(10000) + self.head.next_ = self.tail + self.tail.prev = self.head -class List: +class SkipList: def __init__(self): - minNum, maxNum = -1, 10000 - self.L = Node(minNum) - E = Node(maxNum) - self.L.next_, E.prev = E, self.L + self.levels = [] + self.levels.append(LevelList()) # Level 0 + def add_level(self): + """新增一层并连接上一层""" + new_level = LevelList() + new_level.head.down = self.levels[-1].head + self.levels.append(new_level) -class JList: - def __init__(self): - self.JL = [] - self.JL.append(List()) - - def AddLevel(self): - self.JL.append(List()) - self.JL[len(self.JL) - 1].L.down = self.JL[len(self.JL) - 2].L - - def Add(self, key): - e = Node(key) - i = 0 - while random.randint(0, 9) % 2 == 0: - i += 1 - while len(self.JL) < i + 1: - self.AddLevel() - it = self.JL[i].L - while it.key < e.key: - it = it.next_ - e.next_ = it - e.prev = it.prev - it.prev.next_ = e - it.prev = e - self.RecursiveAdd(e.prev.down, e, key) - return True - - def RecursiveAdd(self, itt, e, key): - if itt == None: + def insert(self, key): + level = 0 + # 随机决定插入的层数 + while random.randint(0, 1) == 0: + level += 1 + while len(self.levels) <= level: + self.add_level() + + new_node = Node(key) + current = self.levels[level].head + + # 寻找插入位置 + while current.key < key: + current = current.next_ + # 插入节点 + new_node.next_ = current + new_node.prev = current.prev + current.prev.next_ = new_node + current.prev = new_node + + # 向下递归插入 + self._insert_down(new_node, new_node.prev.down, key) + + def _insert_down(self, upper_node, down_node, key): + if down_node is None: return - e.down = en = Node(key) - while itt.key < en.key: - itt = itt.next_ - en.next_ = itt - en.prev = itt.prev - itt.prev.next_ = en - itt.prev = en - itt = en.prev.down - self.RecursiveAdd(itt, en, key) - - def Search(self, key, Level=None): - i = self.JL[len(self.JL) - 1].L if Level is None else Level - while i.key < key: - i = i.next_ - if i.prev.down != None: - return self.Search(key, i.prev.down) - elif i.key == key: - return i - else: - return False - - def Delete(self, key, Level=None): - i = self.JL[len(self.JL) - 1].L if Level is None else Level - while i.key < key: - i = i.next_ - if i.key == key: - i.prev.next_ = i.next_ - i.next_.prev = i.prev - while i.down is not None: - i = i.down - i.prev.next_ = i.next_ - i.next_.prev = i.prev - elif i.prev.down != None: - return self.Delete(key, i.prev.down) - else: - return False - -test = JList() -for i in range(0, 10): - test.Add(i) -n = test.Search(6) -for i in range(0, 1024): - test.Delete(i) + # 向下插入 + new_node = Node(key) + upper_node.down = new_node + + current = down_node + while current.key < key: + current = current.next_ + new_node.next_ = current + new_node.prev = current.prev + current.prev.next_ = new_node + current.prev = new_node + + self._insert_down(new_node, new_node.prev.down, key) + + def search(self, key): + current = self.levels[-1].head + while current: + while current.next_ and current.next_.key <= key: + current = current.next_ + if current.key == key: + return current + current = current.down + return None + + def delete(self, key): + current = self.levels[-1].head + found = False + while current: + while current.next_ and current.next_.key < key: + current = current.next_ + if current.next_ and current.next_.key == key: + target = current.next_ + current.next_ = target.next_ + target.next_.prev = current + found = True + current = current.down + else: + current = current.down + return found + +# ==== 测试 ==== +if __name__ == "__main__": + skiplist = SkipList() + for i in range(10): + skiplist.insert(i) + + node = skiplist.search(6) + print("Found 6" if node else "6 Not Found") + + for i in range(1024): + skiplist.delete(i) + print("Deletion done.") + +# 项目 优化前 优化后 +# 命名规范 List 与 Python 保留字冲突 改为 LevelList,避免冲突 +# 层间链接 手动链接复杂 结构清晰,head.down 链接上下层 +# 插入流程 多层嵌套 _insert_down 封装递归逻辑 +# 删除流程 缺乏状态返回 返回布尔值说明是否成功删除 +# 结构健壮性 无断链保护,逻辑易错 添加空值判断与边界保护 diff --git a/LongestCommonSubsequence.py b/LongestCommonSubsequence.py index 5e0a8d7..8796022 100644 --- a/LongestCommonSubsequence.py +++ b/LongestCommonSubsequence.py @@ -1,28 +1,72 @@ -def LCSString(b, X, i, j): - if i == -1 or j == -1: - return - if b[i][j] == "SLOPE": - a = LCSString(b, X, i - 1, j - 1) - return X[i] if a is None else a + X[i] - elif b[i][j] == "UP": - return LCSString(b, X, i - 1, j) +# def LCSString(b, X, i, j): +# if i == -1 or j == -1: +# return +# if b[i][j] == "SLOPE": +# a = LCSString(b, X, i - 1, j - 1) +# return X[i] if a is None else a + X[i] +# elif b[i][j] == "UP": +# return LCSString(b, X, i - 1, j) +# else: +# return LCSString(b, X, i, j - 1) +# +# def LCS(X, Y): +# b = [[0 for i in range(0, len(Y))] for i in range(0, len(X))] +# c = [[0 for i in range(0, len(Y) + 1)] for i in range(0, len(X) + 1)] +# for i in range(0, len(X)): +# for j in range(0, len(Y)): +# if X[i] == Y[j]: +# c[i + 1][j + 1] = c[i][j] + 1 +# b[i][j] = "SLOPE" +# elif c[i][j + 1] > c[i + 1][j]: +# c[i + 1][j + 1] = c[i][j + 1] +# b[i][j] = "UP" +# else: +# c[i + 1][j + 1] = c[i + 1][j] +# b[i][j] = "LEFT" +# return LCSString(b, X, len(X) - 1, len(Y) - 1) +# +# print LCS("ABCBDAB", "BDCABA") +def lcs_string(trace, X, i, j): + """根据方向表 trace 回溯得到 LCS 字符串""" + if i < 0 or j < 0: + return "" + if trace[i][j] == "SLOPE": + return lcs_string(trace, X, i - 1, j - 1) + X[i] + elif trace[i][j] == "UP": + return lcs_string(trace, X, i - 1, j) else: - return LCSString(b, X, i, j - 1) + return lcs_string(trace, X, i, j - 1) -def LCS(X, Y): - b = [[0 for i in range(0, len(Y))] for i in range(0, len(X))] - c = [[0 for i in range(0, len(Y) + 1)] for i in range(0, len(X) + 1)] - for i in range(0, len(X)): - for j in range(0, len(Y)): +def lcs(X, Y): + """计算 X 与 Y 的最长公共子序列""" + m, n = len(X), len(Y) + # 动态规划表和方向表 + dp = [[0] * (n + 1) for _ in range(m + 1)] + trace = [[""] * n for _ in range(m)] + + # 填表 + for i in range(m): + for j in range(n): if X[i] == Y[j]: - c[i + 1][j + 1] = c[i][j] + 1 - b[i][j] = "SLOPE" - elif c[i][j + 1] > c[i + 1][j]: - c[i + 1][j + 1] = c[i][j + 1] - b[i][j] = "UP" + dp[i + 1][j + 1] = dp[i][j] + 1 + trace[i][j] = "SLOPE" + elif dp[i][j + 1] > dp[i + 1][j]: + dp[i + 1][j + 1] = dp[i][j + 1] + trace[i][j] = "UP" else: - c[i + 1][j + 1] = c[i + 1][j] - b[i][j] = "LEFT" - return LCSString(b, X, len(X) - 1, len(Y) - 1) + dp[i + 1][j + 1] = dp[i + 1][j] + trace[i][j] = "LEFT" + + return lcs_string(trace, X, m - 1, n - 1) + +# ==== 测试 ==== +print(lcs("ABCBDAB", "BDCABA")) # 输出应为 "BCBA" 或 "BDAB" + + -print LCS("ABCBDAB", "BDCABA") +# 项目 优化内容 +# Python 3 兼容 使用 print() 函数 +# 命名标准 遵循 PEP 8,函数名小写,变量有意义 +# 输出逻辑明确 LCSString() 返回字符串,避免 None 拼接错误 +# 边界处理更清晰 初始条件明确(索引从 1 开始) +# 添加注释 每步加解释,便于理解动态规划过程 diff --git a/README.md b/README.md index 744f5f9..fcf29c0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +
+ 🇨🇳 中文 | + 🇺🇸 English +
+ + # 简介 这是我阅读《算法导论》时候实现的部分算法。 # 已实现算法 diff --git a/README_EN.md b/README_EN.md new file mode 100644 index 0000000..fbd064d --- /dev/null +++ b/README_EN.md @@ -0,0 +1,37 @@ ++ 🇨🇳 中文 | + 🇺🇸 English +
+ + +# Introduction +This repository contains some of the algorithms I implemented while reading *Introduction to Algorithms*. + +# Implemented Algorithms + + 1. Insertion Sort + 2. Merge Sort + 3. Binary Search + 4. Fast Factorial + 5. Fibonacci Sequence (including the original algorithm, linear algorithm, and recursive matrix algorithm) + 6. Strassen's Algorithm + 7. Heap Sort + 8. Radix Sort + 9. Median Search + 10. Linked List Hashing Algorithm + 11. Open Addressing Hashing Algorithm + 12. Randomized Search + 13. Randomized Quick Sort + 14. Binary Search Tree + 15. Red-Black Tree + 16. Stack + 17. Doubly Linked List + 18. Circular Queue + 19. Longest Substring Problem + 20. Graph Breadth/Depth-First Search + 21. Single-Source Shortest Path - Dijkstra's Algorithm + 22. Skip List + +# Related Resources + +[*Introduction to Algorithms* Quick Guide: How I Learned It in 10 Days.](https://zhuanlan.zhihu.com/p/24798324)