我正在编写代码,以递归方式打印出链接在一起的节点的字符。这些节点链接在一起创建一个“map”(只是从struct到其他节点的指针)。结构如下实现:
typedef struct Node *node_ptr;
struct Node{
char ch;
node_ptr firstPtr;
node_ptr secondPtr;
node_ptr thirdPtr;
};
现在,我需要打印出x节点的步骤。我从控制台获取此值,该控制器存储在int
变量中并将其传递给函数。我也将指针传递给Node。此功能实际打印出正确的输出,但是有两个小错误。
例如,我有一个节点我叫“A”。 “A”的ch
字段是'A',每个节点我有ch
字段将是我称之为节点的指针以使其简单。我想要的一个简单示例如下:
节点A:
ch -> 'A';
A->firstPtr = B;
A->seondPtr = NULL;
A->thirdPtr = NULL;
节点B:
ch = 'B'.
B->firstPtr = A;
B->secondPtr = C;
B->thirdPtr = F;
因此,如果我用户输入A并且距离为2,则应打印出:B,C,F。
我写的递归函数做了这个,但也打印出A.这很可能是因为B也指向A并且它也打印出来,但我认为我处理了这种情况,它仍然会这样做。另外,它在程序结束时给出了分段错误,我也不确定为什么。这是递归函数:
void print_levels(int dist, node_ptr aNode){
if(dist == 0){
// if int is zero, do nothing we are done.
}
else{
/*
if there is pointer (doesn't point to NULL) and if the Node it's pointing
to does not have the same "ch" as the current Node.
*/
if(aNode->firstPtr && !(aNode->firstPtr->ch == aNode->ch)){
printf("%c\n", aNode->firstPtr->ch);
}
if(aNode->secondPtr && !(aNode->secondPtr->ch == aNode->ch)){
printf("%c\n", aNode->secondPtr->ch);
}
if(aNode->thirdPtr && !(aNode->thirdPtr->ch == aNode->ch)){
printf("%c\n", aNode->thirdPtr->ch);
}
print_levels(dist-1, aNode->firstPtr);
print_levels(dist-1, aNode->secondPtr);
print_levels(dist-1, aNode->thirdPtr);
}
}
我要问的是为什么在我给出的示例中,它还打印出A,为什么会导致分段错误?我是C的新手,并且事先欣赏所有的帮助和见解。
答案 0 :(得分:1)
你打电话:
print_levels(dist-1, aNode->firstPtr);
print_levels(dist-1, aNode->secondPtr);
print_levels(dist-1, aNode->thirdPtr);
如果aNode->firstPtr
等等为NULL,您应该在每个之前检查:
if (aNode->firstPtr != NULL)
print_levels(dist-1, aNode->firstPtr);
if (aNode->secondPtr != NULL)
print_levels(dist-1, aNode->secondPtr);
if (aNode->thirdPtr != NULL)
print_levels(dist-1, aNode->thirdPtr);
或者检查print_levels
aNode
是否为NULL并返回:
void print_levels(int dist, node_ptr aNode){
if (dist == 0 || aNode == NULL){
答案 1 :(得分:1)
1)打印出A的原因是,一旦递归调用print_levels()
,aNode
将引用当前节点而不是前一节点。由于图表中有一个周期,因此打印出A:一旦aNode
为B,aNode->
为'B',因此aNode->firstPtr->ch
为'A'并打印,因为它不等于'B'。如果要避免打印初始节点,可以将其他字符传递给print_levels函数并检查它是否相等。
2)分段错误是一个运行时错误,如果没有看到所有代码,则更难以进行二次转换。我建议您在调试器(例如gdb)中运行代码,并找出错误发生的位置(堆栈跟踪)。正如breakfoot在评论中建议的那样,确保所有变量在使用前都已初始化。尤其要确保aNode
不是NULL
:(aNode && aNode->firstPtr && !(aNode->firstPtr->ch == aNode->ch))
,否则访问aNode->firstPtr
是未定义的行为。
答案 2 :(得分:0)
我认为链表中存在循环,导致分段错误。 A指向B,B再指向A,依此类推。你应该实现一些东西来避免循环。