当前位置: 首页 > ds >正文

迭代优化法解决问题实例

迭代优化的思路:

在后序遍历中,我们会先从左向右依次后序遍历每个子节点为根的子树,再遍历根节点本身。此时利用栈先进后出的原理,依次从右向左将子节点入栈,这样出栈的时候即可保证从左向右依次遍历每个子树。

参考方法二的原理,可以提前将后续需要访问的节点压入栈中。首先把根节点入栈,因为根节点是前序遍历中的第一个节点。随后每次我们找到栈顶节点 u ,如果当前节点的子节点没有遍历过,则应该先把 u 的所有子节点从右向左逆序压入栈中,这样出栈的节点则是顺序从左向右的,同时对节点 u 进行标记,表示该节点的子节点已经全部入栈;

如果当前节点 u 为叶子节点或者当前节点的子节点已经全部遍历过,则从栈中弹出节点 u ,并记录节点 u 的值。例如 u 的子节点从左到右为 v1 , v2 , v3 ,那么入栈的顺序应当为 v3, v2 , v1,这样就保证了下一个遍历到的节点(即 u 的左侧第一个孩子节点 v1 )出现在栈顶的位置。此时,访问第一个子节点 v1 时,仍然按照此方法则会先访问 v1 的左侧第一个孩子节点。

代码

Java

class Solution {public List<Integer> postorder(Node root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}Deque<Node> stack = new ArrayDeque<Node>();Set<Node> visited = new HashSet<Node>();stack.push(root);while (!stack.isEmpty()) {Node node = stack.peek();/* 如果当前节点为叶子节点或者当前节点的子节点已经遍历过 */if (node.children.size() == 0 || visited.contains(node)) {stack.pop();res.add(node.val);continue;}for (int i = node.children.size() - 1; i >= 0; --i) {stack.push(node.children.get(i));}visited.add(node);}return res;}
}

C++

class Solution {
public:vector<int> postorder(Node* root) {vector<int> res;if (root == nullptr) {return res;}stack<Node *> st;unordered_set<Node *> visited;st.emplace(root);while (!st.empty()) {Node * node = st.top();/* 如果当前节点为叶子节点或者当前节点的子节点已经遍历过 */if (node->children.size() == 0 || visited.count(node)) {res.emplace_back(node->val);st.pop();continue;}for (auto it = node->children.rbegin(); it != node->children.rend(); it++) {st.emplace(*it);}visited.emplace(node);}       return res;}
};

C#

public class Solution {public IList<int> Postorder(Node root) {IList<int> res = new List<int>();if (root == null) {return res;}Stack<Node> stack = new Stack<Node>();ISet<Node> visited = new HashSet<Node>();stack.Push(root);while (stack.Count > 0) {Node node = stack.Peek();/* 如果当前节点为叶子节点或者当前节点的子节点已经遍历过 */if (node.children.Count == 0 || visited.Contains(node)) {stack.Pop();res.Add(node.val);continue;}for (int i = node.children.Count - 1; i >= 0; i--) {stack.Push(node.children[i]);}visited.Add(node);}return res;}
}

C

#define MAX_NODE_SIZE 10000typedef struct {void * key;UT_hash_handle hh; 
} HashItem;void freeHash(HashItem ** obj) {HashItem * curr = NULL, * next = NULL;HASH_ITER(hh, *obj, curr, next) {HASH_DEL(*obj, curr);free(curr);}
}int* postorder(struct Node* root, int* returnSize) {if (NULL == root) {*returnSize = 0;return NULL;}int * res = (int *)malloc(sizeof(int) * MAX_NODE_SIZE);struct Node ** stack = (struct Node **)malloc(sizeof(struct Node *) * MAX_NODE_SIZE);int pos = 0, top = 0;  stack[top++] = root;HashItem * visited = NULL;HashItem * pEntry = NULL;while (top != 0) {struct Node * node = stack[top - 1];pEntry = NULL;HASH_FIND_PTR(visited, &node, pEntry);/* 如果当前节点为叶子节点或者当前节点的子节点已经遍历过 */if (node->numChildren == 0 || NULL != pEntry) {res[pos++] = node->val;top--;continue;}for (int i = node->numChildren - 1; i >= 0; i--) {stack[top++] = node->children[i];}pEntry = (HashItem *)malloc(sizeof(HashItem));pEntry->key = node;HASH_ADD_PTR(visited, key, pEntry);}free(stack);*returnSize = pos;return res;
}

好了,今天的文章分享就到这里了,希望对大家的学习有帮助哦! 

http://www.xdnf.cn/news/13788.html

相关文章:

  • day27/60重写(补充)
  • 流体仿真CFD技术在好氧活性污泥曝气系统改造中的应用
  • module_obj笔记
  • 手阳明大肠经之温溜穴
  • MySQL基础知识(DDL、DML)
  • YOLO-FireAD:通过混合注意力与双池化融合实现高精度实时火灾检测
  • 【PyQt5】从零开始的PyQt5 - QTextEdit 篇
  • 2025北京智源大会核心内容
  • RAG系统中Rerank技术的深度解析与应用实践
  • DNS的工作原理
  • 【AI News | 20250611】每日AI进展
  • IPv6检测指标中的IPv6授权体系是什么意思?(国科云)
  • HTML5 定位网页元素
  • 让DELPHI11及之后的新版本编译的程序支持Windows XP
  • 2025暑假第三十二届全国高校人工智能(多模态大模型+具身智能)与嵌入式高级师资培训通知
  • 6.11本日总结
  • MVVM 分层思想详解
  • Binder
  • matlab脉冲信号并绘制波形2025.6.11
  • 12.安卓逆向2-frida hook技术-HookJava重载方法
  • element-MessageBox 弹框组件 调整按钮位置(确认在左,取消在右)、删除场景回车调取消事件,默认调确认事件
  • 串口通信入门基础
  • 【Linux】Makefile基础
  • Halcon深度图转换(real、uint2、byte)
  • 基本多线程编译make命令
  • 达梦数据库raw绑定磁盘-DSC集群部署
  • 再说一说LangChain Runnable接口
  • 禁止虚拟机里的Win10的Windows Defender
  • 【热更新知识】学习一 Lua语法学习
  • 【学习笔记】计算机操作系统(六)—— 输入输出系统