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

C++多叉树根到叶路径打印代码报错:函数实参过多求助

多叉树根到叶路径打印功能的参数不匹配错误排查与修复

问题描述

开发多叉树根节点到所有叶节点的路径打印功能时,编译报错,错误信息如下:

main.cpp: 在函数‘void printAllRootToLeafPath(TreeNode)’中:
main.cpp:33:39: error: 函数‘void printAllRootToLeafPath(TreeNode)’的实参过多
33 | printAllRootToLeafPath(t , vec);
| ^
main.cpp:27:8: note: 在此处声明
27 | void printAllRootToLeafPath(struct TreeNode t)

完整代码如下:

#include <iostream>
#include <vector>
#include<cstring>
#include <string>
#include <sstream>
using namespace std;
int m = 0;
struct TreeNode{
    int ownAddress ;
    int parentAddress;
    vector< int > childrenAddress ;
} info[10] ; 

void printPath(vector<int> vec){         
    // Print elements in the vector           
    for (int ele : vec)             
    {
        cout << ele << " ";
    }
    cout << endl;
}  

void printAllRootToLeafPath(struct TreeNode t)            
{
    vector<int> vec;
    printAllRootToLeafPath(t , vec);
}   

void printAllRootToLeafPath(struct TreeNode root , vector<int>vec)   
{                
    ostringstream str1 , str3 ;                
    str1 << root.ownAddress;                
    str3 << root.childrenAddress[0];                
    string var1 = str1.str();                
    string var3 = str3.str();                
    if(var1.compare(var3) == 0)                
    {                                     
        // Print the path                
        printPath(vec);                     
        // Pop the leaf node and return                 
        vec.pop_back();                
        return;                                         
    }                
    // Recur for all children of the current node                
    int child = sizeof(root.childrenAddress)/sizeof(root.childrenAddress[0]);                
    for (int i = 0;i < child; i++)                      
        // Recursive Function Call                
        printAllRootToLeafPath(info[i], vec);
}    

int main()    
{
    info[0].ownAddress = 478523;
    info[0].parentAddress = 478523;
    info[0].childrenAddress.push_back (124569);
    info[0].childrenAddress.push_back (253946);
    info[0].childrenAddress.push_back (325489);
    // Node 1 Relation who is the parent and child of that node.
    info[1].ownAddress = 124569;
    info[1].parentAddress = 478523;
    info[1].childrenAddress.push_back (423657);
    info[1].childrenAddress.push_back (523498);
    // Node 2 Relation who is the parent and child of that node.
    info[2].ownAddress = 253946;
    info[2].parentAddress = 478523;
    info[2].childrenAddress.push_back (632549);
    // Node 3 Relation who is the parent and child of that node.
    info[3].ownAddress = 325489;
    info[3].parentAddress = 478523;
    info[3].childrenAddress.push_back (745863);
    // Node 4 Relation who is the parent and child of that node.
    info[4].ownAddress = 423657;
    info[4].parentAddress = 124569;
    info[4].childrenAddress.push_back (852369);
    // Node 5 Relation who is the parent and child of that node.
    info[5].ownAddress = 523498;
    info[5].parentAddress = 124569;
    info[5].childrenAddress.push_back (963258);
    // Node 6 Relation who is the parent and child of that node.
    info[6].ownAddress = 632549;
    info[6].parentAddress = 253946;
    info[6].childrenAddress.push_back (102359);
    // Node 7 Relation who is the parent and child of that node.
    info[7].ownAddress = 745863;
    info[7].parentAddress = 325489;
    info[7].childrenAddress.push_back (745863);
    // Node 8 Relation who is the parent and child of that node.
    info[8].ownAddress = 852369;
    info[8].parentAddress = 423657;
    info[8].childrenAddress.push_back (852369);
    // Node 9 Relation who is the parent and child of that node.
    info[9].ownAddress = 963258;
    info[9].parentAddress = 523498;
    info[9].childrenAddress.push_back (963258);
    // Node 10 Relation who is the parent and child of that node.
    info[10].ownAddress = 102359;
    info[10].parentAddress = 632549;
    info[10].childrenAddress.push_back (102359);
    printAllRootToLeafPath(info[m]);
    return 0;    
};

错误原因分析

  • 函数声明顺序问题:C++要求调用函数前必须先声明或定义。你先定义了单参数的printAllRootToLeafPath,在它内部调用双参数版本时,双参数版本还未声明,编译器只会认为你在调用当前的单参数函数,导致参数不匹配报错。
  • 路径维护错误:当前代码没有将当前节点加入路径向量,且传递向量时用值传递,递归中修改的向量不会影响上层,路径无法正确累积。
  • 叶节点判断逻辑问题:通过比较ownAddress和childrenAddress[0]判断叶节点,逻辑不严谨,且如果节点没有子节点会触发数组越界访问。
  • 递归子节点获取错误:循环中直接使用info[i],这是取数组的第i个元素,而不是当前节点的子节点对应的元素。

修复方案

1. 调整函数声明顺序,添加前置声明

在单参数函数前声明双参数版本,让编译器提前知道该函数的存在:

void printAllRootToLeafPath(struct TreeNode root , vector<int>& vec);

2. 修复路径传递与维护

  • 使用引用传递向量,确保递归中路径的修改能正确回溯。
  • 进入函数时先将当前节点的ownAddress加入路径,叶节点处理完后再弹出,保证路径的正确性。

3. 修正叶节点判断逻辑

先检查childrenAddress是否非空,再判断子节点地址是否等于自身地址,避免越界:

if (!root.childrenAddress.empty() && root.ownAddress == info[root.childrenAddress[0]].ownAddress)

4. 修正递归子节点的获取

将childrenAddress改为存储数组索引而非地址值,直接通过索引访问info数组中的子节点,简化逻辑。

完整修复后的代码

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

int m = 0;

struct TreeNode{
    int ownAddress ;
    int parentAddress;
    vector<int> childrenAddress ; // 存储数组索引,而非地址值,方便直接访问
} info[11] ; // 节点共11个,数组大小改为11避免越界

void printPath(vector<int> vec){         
    for (int ele : vec)             
    {
        cout << ele << " ";
    }
    cout << endl;
}  

// 前置声明双参数版本
void printAllRootToLeafPath(struct TreeNode root , vector<int>& vec);

void printAllRootToLeafPath(struct TreeNode t)            
{
    vector<int> vec;
    printAllRootToLeafPath(t, vec);
}   

void printAllRootToLeafPath(struct TreeNode root , vector<int>& vec)   
{                
    // 将当前节点加入路径
    vec.push_back(root.ownAddress);

    // 判断是否为叶节点:子节点指向自身
    bool isLeaf = false;
    if (!root.childrenAddress.empty()) {
        isLeaf = (root.ownAddress == info[root.childrenAddress[0]].ownAddress);
    }

    if(isLeaf)                
    {                                     
        printPath(vec);                     
        vec.pop_back(); // 回溯,弹出当前节点
        return;                                         
    }                

    // 遍历所有子节点递归
    for (int childIdx : root.childrenAddress) {                      
        printAllRootToLeafPath(info[childIdx], vec);
    }

    // 回溯,弹出当前节点
    vec.pop_back();
}    

int main()    
{
    // 修正childrenAddress存储数组索引而非地址值
    info[0].ownAddress = 478523;
    info[0].parentAddress = 478523;
    info[0].childrenAddress.push_back(1);
    info[0].childrenAddress.push_back(2);
    info[0].childrenAddress.push_back(3);

    info[1].ownAddress = 124569;
    info[1].parentAddress = 478523;
    info[1].childrenAddress.push_back(4);
    info[1].childrenAddress.push_back(5);

    info[2].ownAddress = 253946;
    info[2].parentAddress = 478523;
    info[2].childrenAddress.push_back(6);

    info[3].ownAddress = 325489;
    info[3].parentAddress = 478523;
    info[3].childrenAddress.push_back(7);

    info[4].ownAddress = 423657;
    info[4].parentAddress = 124569;
    info[4].childrenAddress.push_back(8);

    info[5].ownAddress = 523498;
    info[5].parentAddress = 124569;
    info[5].childrenAddress.push_back(9);

    info[6].ownAddress = 632549;
    info[6].parentAddress = 253946;
    info[6].childrenAddress.push_back(10);

    info[7].ownAddress = 745863;
    info[7].parentAddress = 325489;
    info[7].childrenAddress.push_back(7); // 自身索引,标记为叶节点

    info[8].ownAddress = 852369;
    info[8].parentAddress = 423657;
    info[8].childrenAddress.push_back(8);

    info[9].ownAddress = 963258;
    info[9].parentAddress = 523498;
    info[9].childrenAddress.push_back(9);

    info[10].ownAddress = 102359;
    info[10].parentAddress = 632549;
    info[10].childrenAddress.push_back(10);

    printAllRootToLeafPath(info[m]);
    return 0;    
};

修复说明

  • 调整childrenAddress存储数组索引,避免通过地址查找节点的麻烦,直接通过索引访问子节点。
  • 用引用传递路径向量,确保递归过程中路径的正确累积与回溯。
  • 修正函数声明顺序,解决参数不匹配的编译错误。
  • 优化叶节点判断逻辑,避免数组越界访问。

内容的提问来源于stack exchange,提问作者Vipin Maurya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 19:09:28