尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

深入解析:二叉树、动态规划与链表学习

深入解析:二叉树、动态规划与链表学习
📅 发布时间:2026/6/20 6:07:37

文章目录

    • 二叉树前序、中序、后序遍历相互求法
      • 前序遍历:
      • 前序遍历实现(Python)
        • 递归实现
        • 迭代实现
        • 使用示例
      • 中序遍历:
      • 中序遍历实现方法
        • 后序遍历:
      • 后序遍历实现
        • 递归实现
        • 非递归实现
        • 示例用法
    • python 输出数组中最长递增子序列
      • 最长递增子序列问题
        • 动态规划实现
        • 更高效的二分查找实现
        • 代码说明
        • 复杂度对比
    • python 反转单链表
      • 反转单链表的方法
        • 迭代法
        • 递归法
        • 复杂度分析

二叉树前序、中序、后序遍历相互求法

前序遍历:

1.访问根节点
2.前序遍历左子树
3.前序遍历右子树

前序遍历实现(Python)

前序遍历是二叉树遍历的一种方式,顺序为:根节点 -> 左子树 -> 右子树。以下是递归和迭代两种实现方法。

递归实现

递归方法简洁直观,适合理解前序遍历的逻辑。

class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def preorder_traversal(root):
result = []
def traverse(node):
if not node:
return
result.append(node.val)  # 访问根节点
traverse(node.left)      # 遍历左子树
traverse(node.right)     # 遍历右子树
traverse(root)
return result
迭代实现

迭代方法使用栈模拟递归调用,避免递归的深度限制。

def preorder_traversal_iterative(root):
if not root:
return []
stack, result = [root], []
while stack:
node = stack.pop()
result.append(node.val)
if node.right:  # 右子节点先入栈(后处理)
stack.append(node.right)
if node.left:   # 左子节点后入栈(先处理)
stack.append(node.left)
return result
使用示例
# 构建二叉树
#     1
#      \
#       2
#      /
#     3
root = TreeNode(1, None, TreeNode(2, TreeNode(3), None))
print("递归结果:", preorder_traversal(root))          # 输出: [1, 2, 3]
print("迭代结果:", preorder_traversal_iterative(root)) # 输出: [1, 2, 3]

中序遍历:

1.中序遍历左子树
2.访问根节点
3.中序遍历右子树

中序遍历实现方法

中序遍历是二叉树遍历的一种方式,顺序为:左子树、根节点、右子树。以下是Python实现方法:

递归实现

class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def inorderTraversal(root):
res = []
def inorder(node):
if not node:
return
inorder(node.left)
res.append(node.val)
inorder(node.right)
inorder(root)
return res

迭代实现(使用栈)

def inorderTraversal(root):
res = []
stack = []
curr = root
while curr or stack:
while curr:
stack.append(curr)
curr = curr.left
curr = stack.pop()
res.append(curr.val)
curr = curr.right
return res

二叉树构造示例

# 构建示例二叉树
#     1
#      \
#       2
#      /
#     3
root = TreeNode(1)
root.right = TreeNode(2)
root.right.left = TreeNode(3)
print(inorderTraversal(root))  # 输出: [1, 3, 2]
后序遍历:
1.后序遍历左子树
2.后序遍历右子树
3.访问根节点

后序遍历实现

后序遍历是二叉树遍历的一种方式,遍历顺序为左子树、右子树、根节点。以下是递归和非递归两种实现方法。

递归实现

递归方法是最直观的实现方式,直接按照左、右、根的顺序递归调用即可。

class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def postorder_traversal(root):
result = []
def traverse(node):
if node is None:
return
traverse(node.left)
traverse(node.right)
result.append(node.val)
traverse(root)
return result
非递归实现

非递归方法使用栈来模拟递归过程,需要注意访问节点的顺序和标记已处理节点的状态。

def postorder_traversal_iterative(root):
if not root:
return []
stack = []
result = []
last_visited = None
node = root
while stack or node:
if node:
stack.append(node)
node = node.left
else:
peek_node = stack[-1]
if peek_node.right and last_visited != peek_node.right:
node = peek_node.right
else:
result.append(peek_node.val)
last_visited = stack.pop()
return result
示例用法

以下是如何使用上述代码遍历一个简单的二叉树。

# 构建二叉树
#       1
#      / \
#     2   3
#    / \
#   4   5
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
print("递归后序遍历:", postorder_traversal(root))
print("非递归后序遍历:", postorder_traversal_iterative(root))

输出结果:

递归后序遍历: [4, 5, 2, 3, 1]
非递归后序遍历: [4, 5, 2, 3, 1]

python 输出数组中最长递增子序列

最长递增子序列问题

最长递增子序列(Longest Increasing Subsequence, LIS)是一个经典的动态规划问题。以下是一个Python实现,能够找到并输出数组中最长递增子序列的长度和具体序列。

动态规划实现

动态规划方法的时间复杂度为O(n²),适用于中等规模输入。

def longest_increasing_subsequence(nums):
if not nums:
return 0, []
n = len(nums)
dp = [1] * n
prev = [-1] * n
for i in range(1, n):
for j in range(i):
if nums[i] > nums[j] and dp[i] < dp[j] + 1:
dp[i] = dp[j] + 1
prev[i] = j
max_length = max(dp)
last_index = dp.index(max_length)
# 回溯构建最长子序列
lis = []
while last_index != -1:
lis.append(nums[last_index])
last_index = prev[last_index]
lis.reverse()
return max_length, lis
# 示例
nums = [10, 9, 2, 5, 3, 7, 101, 18]
length, sequence = longest_increasing_subsequence(nums)
print("Length of LIS:", length)
print("LIS sequence:", sequence)
更高效的二分查找实现

对于大规模数据,可以使用二分查找优化,时间复杂度降低到O(n log n)。

import bisect
def longest_increasing_subsequence_optimized(nums):
tails = []
prev_indices = [-1] * len(nums)
indices = []
for i, num in enumerate(nums):
idx = bisect.bisect_left(tails, num)
if idx == len(tails):
tails.append(num)
indices.append(i)
else:
tails[idx] = num
indices[idx] = i
if idx > 0:
prev_indices[i] = indices[idx - 1]
# 回溯重建序列
max_length = len(tails)
if max_length == 0:
return 0, []
lis = []
current = indices[-1]
while current != -1:
lis.append(nums[current])
current = prev_indices[current]
lis.reverse()
return max_length, lis
# 示例
nums = [10, 9, 2, 5, 3, 7, 101, 18]
length, sequence = longest_increasing_subsequence_optimized(nums)
print("Length of LIS:", length)
print("LIS sequence:", sequence)
代码说明
  1. 动态规划方法使用两个数组:dp存储以每个元素结尾的LIS长度,prev记录前驱索引以便重建序列。
  2. 优化方法维护一个tails数组,其中tails[i]表示长度为i+1的递增子序列的最小末尾元素。
  3. 两种方法都通过回溯前驱索引来重建实际的LIS序列。
复杂度对比
  • 动态规划:O(n²)时间,O(n)空间
  • 二分优化:O(n log n)时间,O(n)空间

对于大多数实际应用,二分查找优化版本是更好的选择,特别是当输入规模较大时。


python 反转单链表

单链表的实现
用一组地址任意的存储单元存放线性表中的数据元素。以元素(数据元素的映象) + 指针(指示后继元素存储位置) = 结点。
以“结点的序列”表示线性表,称作线性链表(单链表)。单链表是一种顺序存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。
链表的结点结构: 
┌──┬──┐   
│data│next│   
└──┴──┘   
data域:存放结点值的数据域   
next域:存放结点的直接后继的地址(位置)的指针域(链域)。
注意:①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。   
②每个结点只有一个链域的链表称为单链表(Single Linked List)。
所谓的链表就好像火车车厢一样,从火车头开始,每一节车厢之后都连着后一节车厢。

反转单链表的方法

反转单链表是数据结构中的常见操作,可以通过迭代或递归的方式实现。以下是两种方法的详细说明和示例代码。

迭代法

迭代法通过遍历链表,逐个反转节点的指针方向。需要维护三个指针:prev、current 和 next_node。

class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverse_list(head):
prev = None
current = head
while current:
next_node = current.next
current.next = prev
prev = current
current = next_node
return prev

步骤解析:

  • 初始化 prev 为 None,current 为链表头节点 head。
  • 遍历链表,保存 current 的下一个节点到 next_node。
  • 反转 current 的指针方向,使其指向 prev。
  • 更新 prev 和 current 为下一个节点。
  • 最终 prev 成为新链表的头节点。
递归法

递归法通过递归调用反转子链表,再将当前节点连接到反转后的子链表末尾。

def reverse_list_recursive(head):
if not head or not head.next:
return head
new_head = reverse_list_recursive(head.next)
head.next.next = head
head.next = None
return new_head

步骤解析:

  • 递归终止条件是当前节点为空或下一个节点为空。
  • 递归调用反转 head.next 的子链表,返回的新头节点为 new_head。
  • 将当前节点 head 的下一个节点的指针指向 head,完成局部反转。
  • 将 head.next 设置为 None,避免链表成环。
  • 最终返回 new_head 作为反转后的链表头节点。
复杂度分析
  • 时间复杂度:两种方法均为 O(n),需要遍历链表一次。
  • 空间复杂度:迭代法为 O(1),递归法为 O(n)(递归调用栈空间)。

部分题目来源网络资源!

相关新闻

  • 2025年内蒙古十大钢结构工程设计公司推荐:钢结构工程设计公
  • 2025资质齐全的品牌策划企业TOP5推荐:美御品牌策划实力
  • 2025年比较好的MF库均化设备/IBAU库均化设备TOP品牌厂家排行榜

最新新闻

  • Super Productivity:Docker容器化部署完全指南,打造个人生产力中心
  • HarmonyOS6踩坑记录之卡片开发 @Prop 和 @Link 搞混了?3 个坑帮你彻底搞懂父子组件传值
  • GPT-Image-2渲染产品图全教程:提示词结构、多轮迭代与实测数据
  • doom-ascii控制指南:从基础移动到高级战斗的快捷键全攻略
  • 2026年市场靠谱的工艺品设计趋势平台口碑排行情况
  • DBeaver连接PostgreSQL:界面异常排查与修复实战指南

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号