树的中序遍历的迭代写法

	/*
	2020年3月20日17:28:22
	*/
	第一次写博客,Mark一下。主要目的是便于以后复习。
	树的中序遍历的迭代写法可以用栈来实现,大概思路如下:对每一个要访问的节点,直接将根节点放入栈中,然后把左子树也放入栈,当左子树为空的时候访问其相对应的根节点并弹出,最后再访问右节点,直到栈为空。动手画一下过程会更容易理解。
// 伪代码
栈S;
p= root;
while(p || S不空){
    while(p){
        p入S;
        p = p的左子树;
    }
    p = S.top 出栈;
    访问p;
    p = p的右子树;
}


//C++代码
class Solution {
public:
    vector<int> result;
    stack<TreeNode*> s;
    vector<int> inorderTraversal(TreeNode* root) {
        TreeNode* p = root;
        while(p || s.size()){
            while(p){   //当p不空
                s.push(p);
                p = p->left;
            }
            p = s.top();
            s.pop();
            result.push_back(p->val);
            p = p->right;
        }
        return result;
    }
};

### 实现二叉树的中序遍历算法 #### 递归方法实现中序遍历 对于二叉树的中序遍历,一种常见的做法是采用递归方式来处理。具体来说,在每次调用函数时都会先尝试访问当前节点的左子;当无法继续深入左侧分支后,则输出(或处理)当前节点的数据;最后再转向右侧分支重复上述过程直到整个结构被完全解析完毕[^3]。 ```c void InOrderTraverse(BiTree T) { if (T == NULL) return; InOrderTraverse(T->lchild); // 中序遍历左子 printf("%c", T->data); // 处理结点数据 InOrderTraverse(T->rchild); // 中序遍历右子 } ``` 此段代码展示了如何通过递归来完成一次完整的中序遍历操作。每当遇到一个新的非空节点`T`时,程序会优先探索其左边的孩子节点(`T->lchild`),接着才打印出自身的值,并最终前往右边的孩子节点(`T->rchild`)进行同样的流程[^4]。 #### 非递归方法实现中序遍历 除了利用系统的调用栈来进行递归外,还可以借助显式的栈结构手动模拟这一过程以达到相同的效果。这种方法特别适用于那些想要避免深度过大的递归可能导致堆栈溢出的情况或者希望更好地理解内部机制的学习者们[^2]。 ```c #include <stdio.h> #include <stdlib.h> typedef struct TreeNode { char data; struct TreeNode *left, *right; } BiNode; // 定义一个简单的链表形式的栈用于存储待处理的节点指针 typedef struct StackNode { BiNode* nodePtr; struct StackNode* next; } SNode; SNode* createStack() { return NULL; } int isEmpty(SNode* top) { return !top; } void push(SNode** top_ref, BiNode* newNode) { SNode* stackNode = (SNode*)malloc(sizeof(SNode)); stackNode->nodePtr = newNode; stackNode->next = (*top_ref); (*top_ref) = stackNode; } BiNode* pop(SNode** top_ref) { if (!isEmpty(*top_ref)) { SNode* temp = *top_ref; BiNode* popped = temp->nodePtr; *top_ref = temp->next; free(temp); return popped; } return NULL; } void inorderTraversalNonRecursive(BiNode* root) { SNode* s = createStack(); while (root != NULL || !isEmpty(s)) { // 将所有左孩子的路径压入栈中 while (root != NULL) { push(&s, root); root = root->left; } // 开始回溯并访问最近的一个未访问过的节点 root = pop(&s); // 执行实际的操作比如打印字符 printf("%c ", root->data); // 转向右子 root = root->right; } } ``` 这段代码实现了基于栈的非递归版本的中序遍历逻辑。它首先尽可能多地沿着最左边的一条路线下探并将沿途经过的所有节点依次加入到自定义的栈里去;一旦到达尽头就弹出栈顶元素作为下一个要处理的对象,随后转而考察这个刚刚取出的节点所对应的另一侧——也就是它的右子部分。 #### 应用场景分析 无论是选择递归还是迭代的方式取决于具体的编程环境和个人偏好等因素。如果是在教学环境中讲解概念性的知识点,那么简洁明了易于理解和记忆的递归写法往往更加合适一些;而在工业级应用开发当中考虑到性能优化以及防止潜在的风险如过深嵌套引起崩溃等问题则可能倾向于使用循环加辅助数据结构的方法[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值