通过向后遍历链表结构树结构来获取路径

时间:2015-09-23 08:04:24

标签: c algorithm

我有一个如下所示的树结构

-> grandma
    -> dad
        -> me
        -> sister
            -> niece
        -> brother
    -> uncle
        -> cousin

我有一个结构如下

struct Node{
Node *parent;
Node *next;
Node *child;
Node *prev;
}

如果我有 niece 节点,我想回到root,并将该路径保存在c字符串中,我不知道如何在字符串中保存遍历的路径。如果我有侄女,它应该保存路径,祖母/数据/我/姐妹/侄女

如果我还有堂兄,我想回到路上,那应该是奶奶/叔叔/堂兄,我怎么知道那个叔叔父母是祖母,并在完整的遍历路径中连接它?

2 个答案:

答案 0 :(得分:4)

要执行此操作,您可以使用递归函数调用自身来查找根,然后将节点名称附加到某个缓冲区。

示例:

void buildPath(Node* node, char* buffer)
{
    if (node->parent != NULL)
        buildPath(node->parent, buffer);
    else
        strcpy("", buffer);

    strcat(buffer, node->name);
}

笑话迭代的例子(不要这样做!):

void buildPath(Node* node, char* buffer)
{
    strcpy("", buffer);

    do {
        strrev(node->name);
        strcat(node->name, buffer);
        strrev(node->name);

        node = node->parent;
    } while (node != NULL);

    strrev(buffer);
}

简单的堆栈迭代示例:

void buildPath(Node* node, char* buffer)
{
    const size_t MAX_STACK_SIZE = 1024;
    char* stack[MAX_STACK_SIZE];
    char** top = stack;

    do {
        *top++ = node->name; // Stack overflow can occurs here!!!
        node = node->parent;
    } while (node != NULL);

    strcpy("", buffer);

    do {
        strcat(buffer, *top--);
    } while (top > stack);
}

答案 1 :(得分:2)

由于@Ahmed Saleh的需求,我已经为缓冲和长度的迭代做了一个完整的例子。然而,它没有被评论。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node { struct node *parent; char const * name; };

char* PushString(char* buffer, char* currentPosition, char const *toAdd)
{
    if(buffer == NULL || currentPosition == NULL)
        return NULL;
    if(toAdd == NULL)
        return currentPosition;

    {
        size_t freeSpace = currentPosition - buffer;
        size_t length = strlen(toAdd);
        if(length > freeSpace)
            return NULL;
        currentPosition -= length;
        //Note: I'm using a sizeof here, to avoid bad surprises
        //when this code is someday converted to use wchar_t instead of char
        memcpy(currentPosition, toAdd, length * sizeof(*toAdd));
        return currentPosition;
    }
}

char* BuildPath(struct node const* theNode, char *buffer, size_t bufferSize)
{
    char * currentPosition = buffer + bufferSize;
    if(buffer==NULL || bufferSize==0)
        return NULL;

    *(--currentPosition) = '\0';

    while(theNode != NULL)
    {
        currentPosition = PushString(buffer, currentPosition, theNode->name);
        if(currentPosition == NULL)
            return NULL;
        currentPosition = PushString(buffer, currentPosition, "/");
        if(currentPosition == NULL)
            return NULL;
        theNode = theNode->parent;
    }
    return currentPosition;
}

int main(void)
{
    struct node node1 = { NULL, "root" };
    struct node node2 = { &node1, "child" };
    struct node node3 = { &node2, "grandchild" };
    char buffer[80];
    char* ret = BuildPath(&node3, buffer, sizeof buffer / sizeof(*buffer));
    if(ret == NULL)
    {
        puts("Failed.");
        return EXIT_FAILURE;
    }
    printf("Result: %s\n", ret);
    return EXIT_SUCCESS;
}