You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

除尾递归消除外,二叉树中序遍历代码还应用了何种编译器优化?

二叉树中序遍历递归转嵌套循环的编译器优化技术

你看到的这种将递归代码转化为大量嵌套循环的编译器优化,核心是递归到迭代转换(Recursion-to-Iteration Conversion),具体来说GCC在此基础上结合了**递归展开(Recursion Unrolling)**与尾递归消除的组合操作。

你的原递归中序遍历逻辑是:先递归遍历左子树、打印当前节点、最后递归遍历右子树。编译器识别到这种固定的递归结构后,会做以下处理:

  • 对于左子树的递归遍历,将其展开为多层嵌套循环,模拟递归不断深入左子树的过程;
  • 对于右子树的尾递归调用(当前节点处理完毕后发起的最后一次递归),直接转化为循环迭代,避免栈帧的重复创建与销毁。

这种优化把递归的栈式遍历逻辑,转化为手动的循环结构,彻底消除递归带来的栈开销,同时通过嵌套循环模拟递归的深度遍历流程,这就是反编译代码出现大量嵌套循环的原因。

原递归C代码

void inorderTraversal(struct TreeNode* root) {
    if (root == NULL) {
        return;
    }
    inorderTraversal(root->left);  
    printf("%d ", root->val);  
    inorderTraversal(root->right);  
}

编译命令

gcc inorder.c -O2 -o inorder_O2

反编译得到的High Level IL代码

void inorderTraversal(int32_t* arg1){
    int32_t* i_1 = arg1
    if (arg1 != 0)
        int32_t* i
        do
            int32_t* j_2 = *(i_1 + 8)
            int32_t* j_1 = j_2
            if (j_2 != 0)
                int32_t* j
                do
                    int32_t* k_2 = *(j_1 + 8)
                    int32_t* k_1 = k_2
                    if (k_2 != 0)
                        int32_t* k
                        do
                            int32_t* r15_1 = *(k_1 + 8)
                            if (r15_1 != 0)
                                do
                                    int32_t* rbx_1 = *(r15_1 + 8)
                                    if (rbx_1 != 0)
                                        do
                                            int32_t* r13_1 = *(rbx_1 + 8)
                                            if (r13_1 != 0)
                                                do
                                                    int32_t* r12_1 = *(r13_1 + 8)
                                                    if (r12_1 != 0)
                                                        do
                                                            int32_t* r14_1 = *(r12_1 + 8)
                                                            if (r14_1 != 0)
                                                                do
                                                                    int32_t* r9_1 = *(r14_1 + 8)
                                                                    if (r9_1 != 0)
                                                                        do
                                                                            inorderTraversal(*(r9_1 + 8))
                                                                            __printf_chk(flag: 1, format: &data_2004, zx.q(*r9_1))
                                                                            r9_1 = *(r9_1 + 0x10)
                                                                        while (r9_1 != 0)
                                                                    __printf_chk(flag: 1, format: &data_2004, zx.q(*r14_1))
                                                                    r14_1 = *(r14_1 + 0x10)
                                                                while (r14_1 != 0)
                                                            __printf_chk(flag: 1, format: &data_2004, zx.q(*r12_1))
                                                            r12_1 = *(r12_1 + 0x10)
                                                        while (r12_1 != 0)
                                                    __printf_chk(flag: 1, format: &data_2004, zx.q(*r13_1))
                                                    r13_1 = *(r13_1 + 0x10)
                                                while (r13_1 != 0)
                                            __printf_chk(flag: 1, format: &data_2004, zx.q(*rbx_1))
                                            rbx_1 = *(rbx_1 + 0x10)
                                        while (rbx_1 != 0)
                                    __printf_chk(flag: 1, format: &data_2004, zx.q(*r15_1))
                                    r15_1 = *(r15_1 + 0x10)
                                while (r15_1 != 0)
                            __printf_chk(flag: 1, format: &data_2004, zx.q(*k_1))
                            k = *(k_1 + 0x10)
                            k_1 = k
                        while (k != 0)
                    __printf_chk(flag: 1, format: &data_2004, zx.q(*j_1))
                    j = *(j_1 + 0x10)
                    j_1 = j
                while (j != 0)
            __printf_chk(flag: 1, format: &data_2004, zx.q(*i_1))
            i = *(i_1 + 0x10)
            i_1 = i
        while (i != 0)
}

内容的提问来源于stack exchange,提问作者Fish Toucher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 04:47:10