from house_operation import * from datetime import datetime # v1 def get_next_house_id(): houses = read_houses() if not houses: return 1 max_id = max(house["id"] for house in houses) return max_id + 1 def add_house(address, price, area, house_type): if not address or not house_type: print("错误:地址和户型不能为空!") return False if not isinstance(price, (int, float)) or price <= 0: print("错误:租金必须是正数!") return False if not isinstance(area, (int, float)) or area <= 0: print("错误:面积必须是正数!") return False new_house = { "id": get_next_house_id(), "address": address, "price": price, "area": area, "house_type": house_type } houses = read_houses() houses.append(new_house) write_houses(houses) print(f"房源新增成功!房源ID:{new_house['id']}") return True def delete_house(house_id): houses = read_houses() for index, house in enumerate(houses): if house["id"] == house_id: del houses[index] write_houses(houses) print(f"房源ID {house_id} 删除成功!") return True print(f"错误:未找到房源ID {house_id}!") return False def update_house(house_id, new_info): houses = read_houses() for house in houses: if house["id"] == house_id: for key, value in new_info.items(): if key in ["address", "price", "area", "house_type"]: if key in ["price", "area"]: if not isinstance(value, (int, float)) or value <= 0: print(f"错误:{key}必须是正数!") return False house[key] = value write_houses(houses) print(f"房源ID {house_id} 修改成功!") return True print(f"错误:未找到房源ID {house_id}!") return False def query_house(condition_type, condition_value): houses = read_houses() result = [] for house in houses: if condition_type == "id": if house["id"] == int(condition_value): result.append(house) elif condition_type == "address": if condition_value in house["address"]: result.append(house) elif condition_type == "house_type": if house["house_type"] == condition_value: result.append(house) elif condition_type == "price": if house["price"] == float(condition_value): result.append(house) else: print("错误:不支持的查询条件类型!") return [] return result # v2 MAX_STACK_LENGTH = 100 def push_operation_stack(operation_info): time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S") full_info = f"[{time_str}] {operation_info}" stack = read_stack("operation") stack.append(full_info) if len(stack) > MAX_STACK_LENGTH: stack.pop(0) write_stack("operation", stack) def push_browse_stack(house_id): stack = read_stack("browse") if stack and stack[-1] == house_id: return stack.append(house_id) if len(stack) > MAX_STACK_LENGTH: stack.pop(0) write_stack("browse", stack) def pop_operation_stack(): stack = read_stack("operation") if not stack: return None latest_op = stack.pop() write_stack("operation", stack) return latest_op def pop_browse_stack(): stack = read_stack("browse") if not stack: return None latest_hid = stack.pop() write_stack("browse", stack) return latest_hid def get_recent_records(stack_type, limit=10): stack = read_stack(stack_type) return stack[-limit:][::-1] def clear_stack(stack_type): write_stack(stack_type, []) print(f"{stack_type}记录已清空!") #v3 def parse_address_string(full_address): """解析完整地址字符串:拆分省、市、区、小区""" parts = full_address.split("市") province_city = parts[0] + "市" if "市" in full_address else parts[0] if "省" in province_city: province, city = province_city.split("省") province += "省" city += "市" else: province = "未知省份" city = province_city if len(parts) > 1: district_part = parts[1] if "区" in district_part or "县" in district_part: district, community = district_part.split("区") if "区" in district_part else district_part.split("县") district += "区" if "区" in district_part else "县" else: district = "未知区县" community = district_part else: district = "未知区县" community = "未知小区" return { "province": province, "city": city, "district": district, "community": community } def fuzzy_query_by_district(keyword): """根据区域关键词模糊匹配所有房源""" houses = read_houses() result = [] for house in houses: addr_info = parse_address_string(house["address"]) if keyword in addr_info["district"] or keyword in addr_info["community"]: result.append(house) return result def init_community_matrix(community_name_list): """初始化小区距离邻接矩阵""" INF = float("inf") n = len(community_name_list) distance_matrix = [[INF] * n for _ in range(n)] for i in range(n): distance_matrix[i][i] = 0 matrix_data = { "community_list": community_name_list, "distance_matrix": distance_matrix } write_matrix_data(matrix_data) print("邻接矩阵初始化完成!") def update_matrix_distance(community_a, community_b, distance): """更新两个小区之间的距离""" matrix_data = read_matrix_data() community_list = matrix_data["community_list"] distance_matrix = matrix_data["distance_matrix"] try: idx_a = community_list.index(community_a) idx_b = community_list.index(community_b) distance_matrix[idx_a][idx_b] = distance distance_matrix[idx_b][idx_a] = distance write_matrix_data(matrix_data) print(f"{community_a} <-> {community_b} 距离更新成功!") except ValueError: print("小区名称不存在!") #v4 class HouseBSTNode: """ 二叉查找树节点:按指定字段(租金/面积)作为键值 """ def __init__(self, house_data, key_field="price"): self.key = house_data[key_field] # 排序键(租金/面积) self.house = house_data # 房源完整数据 self.left = None # 左子节点(键值更小) self.right = None # 右子节点(键值更大) # V4.0 新增:二叉查找树核心操作 def build_house_bst(houses, key_field="price"): """ 构建房源二叉查找树(按租金/面积) 时间复杂度:O(n log n)(最优/平均),O(n²)(最坏,有序数据) """ if not houses: return None # 选第一个元素作为根节点 root = HouseBSTNode(houses[0], key_field) # 逐个插入剩余节点 for house in houses[1:]: insert_bst_node(root, house, key_field) return root def insert_bst_node(root, house_data, key_field="price"): """ 向二叉查找树插入节点 时间复杂度:O(log n)(平均),O(n)(最坏) """ current = root while True: # 键值小于当前节点,走左子树 if house_data[key_field] < current.key: if current.left is None: current.left = HouseBSTNode(house_data, key_field) break else: current = current.left # 键值大于等于当前节点,走右子树 else: if current.right is None: current.right = HouseBSTNode(house_data, key_field) break else: current = current.right def inorder_bst_traversal(root, result_list): """ 二叉查找树中序遍历(输出有序列表) 时间复杂度:O(n)(遍历所有节点) """ if root is not None: inorder_bst_traversal(root.left, result_list) result_list.append(root.house) inorder_bst_traversal(root.right, result_list) def search_bst_range(root, min_val, max_val, key_field="price", result_list=None): """ 二叉查找树范围查询(如:租金5000-8000) 时间复杂度:O(log n + k)(k为符合条件的节点数) """ if result_list is None: result_list = [] if root is None: return result_list # 若当前键值大于最小值,遍历左子树 if root.key > min_val: search_bst_range(root.left, min_val, max_val, key_field, result_list) # 若当前键值在范围内,加入结果 if min_val <= root.key <= max_val: result_list.append(root.house) # 若当前键值小于最大值,遍历右子树 if root.key < max_val: search_bst_range(root.right, min_val, max_val, key_field, result_list) return result_list def bubble_sort_houses(houses, sort_field="price", reverse=False): """ V4.0新增 排序知识点 冒泡排序:按指定字段(租金/面积)排序 时间复杂度:O(n²)(稳定排序) """ n = len(houses) # 深拷贝避免修改原列表 sorted_houses = [h.copy() for h in houses] for i in range(n): swapped = False for j in range(0, n - i - 1): if sorted_houses[j][sort_field] > sorted_houses[j + 1][sort_field]: # 交换元素 sorted_houses[j], sorted_houses[j + 1] = sorted_houses[j + 1], sorted_houses[j] swapped = True # 无交换则提前退出 if not swapped: break # 降序反转 if reverse: sorted_houses = sorted_houses[::-1] return sorted_houses def quick_sort_houses(houses, sort_field="price", reverse=False): """ V4新增 排序知识点 快速排序:按指定字段(租金/面积)排序 时间复杂度:O(n log n)(平均),O(n²)(最坏) """ if len(houses) <= 1: return houses # 深拷贝避免修改原列表 sorted_houses = [h.copy() for h in houses] # 选第一个元素作为基准 pivot = sorted_houses[0][sort_field] left = [h for h in sorted_houses[1:] if h[sort_field] <= pivot] right = [h for h in sorted_houses[1:] if h[sort_field] > pivot] # 递归排序 result = quick_sort_houses(left, sort_field) + [sorted_houses[0]] + quick_sort_houses(right, sort_field) # 降序反转 if reverse: result = result[::-1] return result #V5 def print_community_graph(): """ 文本形式可视化小区图(邻接矩阵) 时间复杂度:O(n²),n为小区数量 """ matrix_data = read_matrix_data() community_list = matrix_data["community_list"] distance_matrix = matrix_data["distance_matrix"] if not community_list: print("暂无小区图数据!请先初始化邻接矩阵。") return # 打印表头 print("\n===== 小区距离图(邻接矩阵) =====") print(" " + " ".join([c[:4].ljust(4) for c in community_list])) # 打印每行数据 for i, community in enumerate(community_list): row_str = community[:4].ljust(4) for j in range(len(community_list)): val = distance_matrix[i][j] if val == float("inf"): row_str += " ∞ " else: row_str += f"{val:5.1f}" print(row_str) def dijkstra_shortest_path(start_community, end_community): """ Dijkstra算法:计算两个小区间的最短路径 时间复杂度:O(n²)(邻接矩阵实现),n为小区数量 return: (最短距离, 路径列表) """ matrix_data = read_matrix_data() community_list = matrix_data["community_list"] distance_matrix = matrix_data["distance_matrix"] # 校验小区是否存在 if start_community not in community_list or end_community not in community_list: print("起始/目标小区不存在!") return (None, None) n = len(community_list) start_idx = community_list.index(start_community) end_idx = community_list.index(end_community) # 初始化距离数组和前驱节点数组 INF = float("inf") dist = [INF] * n # 各节点到起点的距离 visited = [False] * n # 节点是否已访问 prev = [-1] * n # 前驱节点索引 dist[start_idx] = 0 # 起点到自己的距离为0 # 核心Dijkstra循环 for _ in range(n): # 找到未访问的距离最小节点 min_dist = INF u = -1 for i in range(n): if not visited[i] and dist[i] < min_dist: min_dist = dist[i] u = i if u == -1 or dist[u] == INF: break # 无可达路径 visited[u] = True # 松弛操作:更新邻接节点的距离 for v in range(n): if not visited[v] and distance_matrix[u][v] != INF: if dist[v] > dist[u] + distance_matrix[u][v]: dist[v] = dist[u] + distance_matrix[u][v] prev[v] = u # 回溯路径 if dist[end_idx] == INF: print(f"{start_community} 到 {end_community} 无可达路径!") return (None, None) # 从终点回溯到起点 path = [] current = end_idx while current != -1: path.append(community_list[current]) current = prev[current] path.reverse() # 反转得到正序路径 return (dist[end_idx], path) def recommend_houses_by_path(target_community, max_distance): """ 推荐目标小区最短距离≤max_distance的周边房源 """ matrix_data = read_matrix_data() community_list = matrix_data["community_list"] if target_community not in community_list: print("目标小区不存在!") return [] # 计算目标小区到所有小区的最短路径 recommend_communities = [] for comm in community_list: dist, _ = dijkstra_shortest_path(target_community, comm) if dist is not None and dist <= max_distance: recommend_communities.append(comm) # 查询这些小区的房源 all_houses = read_houses() recommend_houses = [] for house in all_houses: addr_info = parse_address_string(house["address"]) if addr_info["community"] in recommend_communities: recommend_houses.append(house) return recommend_houses