C 使用递归函数打印链表

C 使用递归函数打印链表,c,recursion,tree,linked-list,nodes,C,Recursion,Tree,Linked List,Nodes,我可以打印我的链接列表: | |-> [ID: 3] Poetry | | | |-> [ID: 3] Notes 3 | | | |-> [ID: 2] Notes 2 | | | |-> [ID: 1] Notes 1 | | | |-> [ID: 2] Diet | | | |-> [ID: 2] Diet 2 | | | |-> [ID: 1] Diet 1 | | |

我可以打印我的链接列表:

|
|-> [ID: 3] Poetry
|   |
|   |-> [ID: 3] Notes 3
|   |   
|   |-> [ID: 2] Notes 2
|   |   
|   |-> [ID: 1] Notes 1
|   |   
|
|-> [ID: 2] Diet
|   |
|   |-> [ID: 2] Diet 2
|   |   
|   |-> [ID: 1] Diet 1
|   |   
|
|-> [ID: 1] Program
使用我编写的以下函数:

void printn(NODE *handle)   //only 2 depths allowed
    {
    NODE *copy_handle = NULL; 
    NODE *depth1 = NULL;
    NODE *depth2 = NULL;

    for( copy_handle = handle ; copy_handle != NULL ; copy_handle = copy_handle->pNext  )
        {
        printf("|\n|-> [ID: %d] %s\n", copy_handle->id, copy_handle->pLabel);

        if(copy_handle->pInner != NULL )
            {
            printf("|\t|\n");
            for(depth1 = copy_handle->pInner ; depth1 != NULL ; depth1 = depth1->pNext  )
                {
                printf("|\t|-> [ID: %d] %s\n", depth1->id, depth1->pLabel);

                if(depth1->pInner != NULL )
                    {
                    printf("|\t|\t|\n");
                    for(depth2 = depth1->pInner ; depth2 != NULL ; depth2 = depth2->pNext  )
                        {
                        printf( "|\t|\t|-> [ID: %d] %s\n", depth2->id, depth2->pLabel);
                        }
                    }

                printf("|\t|\t\n");
                } 
            }
        }

    }
但是,该函数的局限性在于,我只能打印节点的一个子节点和该子节点的一个子节点,或者,正如我在代码中所称,我只能允许深度为2。我想做的是能够打印无限深度,所以我查看了我的原始函数,我觉得用递归重新设计它是合适的。因此,我开发了以下内容:

void rec_printn(NODE *handle, int tab)   //unlimited depths
    {

    printf("tab %d\n", tab); //for testing purposes
    NODE *copy_handle = handle;
    for( ; copy_handle != NULL ; copy_handle = copy_handle->pNext )
        {
        printf("%*s|-> [ID: %d] %s\n", tab, " ",  copy_handle->id, copy_handle->pLabel);   //add variable spacing 

        if(copy_handle->pInner != NULL )
            {
            tab+=5;
            rec_printn(copy_handle->pInner , tab);
            }
        else if(copy_handle->pNext == NULL )
            {
            tab-=5;
            printf("<take back the indent\n"); //for testing purposes
            }

        }
    }
tab 5
     |-> [ID: 3] Poetry
tab 10
          |-> [ID: 3] Notes 3
          |-> [ID: 2] Notes 2
          |-> [ID: 1] Notes 1
<take back the indent
          |-> [ID: 2] Diet
tab 15
               |-> [ID: 2] Diet 2
               |-> [ID: 1] Diet 1
<take back the indent
               |-> [ID: 1] Program
<take back the indent
void rec\u printn(节点*句柄,int选项卡)//无限深度
{
printf(“选项卡%d\n”,选项卡);//用于测试目的
节点*复制\句柄=句柄;
for(;copy_handle!=NULL;copy_handle=copy_handle->pNext)
{
printf(“%*s |->[ID:%d]%s\n”,制表符“”,复制句柄->ID,复制句柄->pLabel);//添加变量间距
if(复制句柄->pInner!=NULL)
{
tab+=5;
rec_printn(复制手柄->钉板,选项卡);
}
else if(复制句柄->pNext==NULL)
{
tab-=5;

printf(“在每次迭代中,您将在
选项卡中添加5个

不要改变
选项卡
,而是将正确的值传递给函数,并让递归处理它:

if (copy_handle->pInner != NULL)
{
    rec_printn(copy_handle->pInner, tab + 5);
}
else if (copy_handle->pNext == NULL )
{
    printf("<take back the indent\n");
}
if(复制句柄->pInner!=NULL)
{
rec_printn(复制手柄->压针,制表符+5);
}
else if(复制句柄->pNext==NULL)
{

printf(“在调用之前,您总是递增5,因此
选项卡-=5
会被取消。快速修复方法是执行
选项卡-=10;
太棒了!解决了我的问题。我原以为函数不会“记住”这是以前的选项卡级别,我不完全理解为什么会这样?@ShadyProgrammer每次调用函数都有自己的变量“tab”,它们是完全独立的。(它的工作原理与以非递归方式调用完全不同的函数的工作原理完全相同-即使碰巧有一个名为“tab”的局部变量或参数,也不会发生任何事情),因为您从未在“此级别”上为
tab
分配新值,它没有改变。哦,我现在明白了,谢谢。作为一个旁白和好奇的问题:我能不递归地完成它吗?我遇到的主要问题是,指针地址在打印列表后被覆盖,列表随后被破坏,因此我在第一个示例中为每个深度使用了单独的变量e、 @ShadyProgrammer这是可以做到的,但它会很混乱,因为你的“列表”实际上是一棵树。迭代树遍历通常涉及管理你自己的值堆栈,而不是让机器通过参数传递来为你做。