簡體   English   中英

如何遍歷多路樹

[英]How to tree traversal a multiway tree

我曾嘗試遍歷一棵多路樹,但我試圖以一種有效的方式來做,但這並沒有真正的幫助,更重要的是,我想遞歸地這樣做。

我的想法是這樣的:我有一棵樹,一個孩子,是兄弟姐妹。 我想遞歸地跟孩子們走,然后只要有兄弟姐妹遞歸地跟他們走。

在這里,我將向您介紹我的數據結構以及如何嘗試實現此結構。 這是一個完整的功能“可測試對象”,還將創建一張照片供您查看樹並使用代碼:

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

#define SIZE    100

typedef struct tree {
    int value;
    struct tree *child, *sibling;
} *Tree;

Tree initTree(int value) {
    Tree root = malloc(sizeof(struct tree));
    root->value = value;
    root->child = NULL;
    root->sibling = NULL;
    return root;
}

void drawTreeHelper(Tree tree, FILE* stream) {
    Tree tmp;
    if (tree == NULL) {
        return;
    }
    fprintf(stream, "    %ld[label=\"%d\", fillcolor=red]\n", (intptr_t) tree, tree->value);
    tmp = tree->child;

    while (tmp != NULL) {
        fprintf(stream, "    %ld -> %ld \n", (intptr_t) tree, (intptr_t) tmp);
        drawTreeHelper(tmp, stream);
        tmp = tmp->sibling;
    }
}

void drawTree(Tree tree, char *fileName) {
    FILE* stream = fopen("test.dot", "w");
    char buffer[SIZE];
    fprintf(stream, "digraph tree {\n");
    fprintf(stream, "    node [fontname=\"Arial\", shape=circle, style=filled, fillcolor=yellow];\n");
    if (tree == NULL)
        fprintf(stream, "\n");
    else if (!tree->child)
        fprintf(stream, "    %ld [label=\"%d\"];\n", (intptr_t) tree, tree->value);
    else
        drawTreeHelper(tree, stream);
    fprintf(stream, "}\n");
    fclose(stream);
    sprintf(buffer, "dot test.dot | neato -n -Tpng -o %s", fileName);
    system(buffer);
}

int main() {
    int i;
    char buffer[SIZE];
    Tree *forest = malloc(5 * sizeof(Tree));
    for (i = 0; i < 5; i++) {
        forest[i] = initTree(i);
    }

    forest[4]->child = forest[3];
    forest[4]->child->sibling = forest[2];
    forest[1]->child = forest[0];
    forest[1]->child->sibling = forest[4];

    for (i = 0; i < 5; i++) {
        sprintf(buffer, "tree_%d.png", i);
        if (forest[i]) {
            drawTree(forest[i], buffer);
        }
    }
    return 0;
}

我要創建的功能保持不變,即:

Tree findChild(Tree root, int value)
{
    if(!root) return NULL;
    if(root->value == value) return root;

    return findChild(root->child, value);
    Trie iter = root;
    while(iter)
    {
        return findChild(iter->sibling, value);
        iter = iter->sibling;
    }
}

我希望找到該子節點,但是如果該節點不是root的直接子節點,它將返回NULL。 對我要創建的功能的期望:在樹中以最有效的方式找到孩子。

這是您的功能:

Tree findChild(Tree root, int value)
{
    if(!root) return NULL;
    if(root->value == value) return root;

在這里,您遍歷了子節點,但是您說return

    return findChild(root->child, value);

因此,此代碼永遠不會執行:

    Tree iter = root;
    while(iter)
    {
        return findChild(iter->sibling, value);
        iter = iter->sibling;
    }
}

此外,該迭代是無用的,因為無論如何您都要通過調用findChild遍歷下一個同級對象。 因此該函數可能看起來像這樣:

Tree findChild(Tree root, int value)
{
    if(!root) return NULL;
    if(root->value == value) return root;

    Tree *ret = findChild(root->child, value);
    if (!ret)
        ret = findChild(root->sibling, value);

    return ret;
}

這應該可以按預期工作。

編輯:

(無條件) return ,代碼將永遠不會執行。 根本就沒有返回“返回”的代碼路徑。

如果樹中的項目未遵循特定順序,則這可能是最有效的方式(就運行時復雜度而言)。 如果樹是有序的,則可以通過查看當前項目,將其與搜索到的項目進行比較,然后基於比較結果,僅選擇兩個路徑中的一個作為child路徑或sibling路徑,而不必遍歷兩個路徑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM