微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用 C 编写的代码的递归到迭代转换

如何解决用 C 编写的代码的递归到迭代转换

这是在 C 中打印 xml 树的代码。如何迭代地编写它?

static void
print_element_names(xmlNode *a_node)
{
    xmlNode *cur_node = NULL;

    for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
        if (cur_node->type == XML_ELEMENT_NODE) {
            printf("node type: Element,name: %s\n",cur_node->name);
        }
        print_element_names(cur_node->children);
    }
}

解决方法

您可以利用 libxml2 中使用的 parent 结构中的 xmlNode 节点:

typedef struct _xmlNode xmlNode;
struct _xmlNode {
    void *_private;              // application data
    xmlElementType type;         // type number,must be second !
    const xmlChar *name;         // the name of the node,or the entity
    struct _xmlNode *children;   // parent->childs link
    struct _xmlNode *last;       // last child link
    struct _xmlNode *parent;     // child->parent link
    struct _xmlNode *next;       // next sibling link
    struct _xmlNode *prev;       // previous sibling link
    struct _xmlDoc *doc;         // the containing document End of common p
    xmlNs *ns;                   // pointer to the associated namespace
    xmlChar *content;            // the content
    struct _xmlAttr *properties; // properties list
    xmlNs *nsDef;                // namespace definitions on this node
    void *psvi;                  // for type/PSVI informations
    unsigned short line;         // line number
    unsigned short extra;        // extra data for XPath/XSLT
};

这是一个非递归版本:

static void print_element_names(xmlNode *a_node) {
    if (a_node != NULL) {
        xmlNode *stop = a_node->parent;
        xmlNode *cur_node = a_node;
        int skip = 0;

        for (;;) {
            if (!skip) {
                if (cur_node->type == XML_ELEMENT_NODE) {
                    printf("node type: Element,name: %s\n",cur_node->name);
                }
                if (cur_node->children) {
                    cur_node = cur_node->children;
                    continue;
                }
            }
            if (cur_node->next) {
                cur_node = cur_node->next;
                skip = 0;
            } else {
                cur_node = cur_node->parent;
                if (cur_node == stop)
                    break;
                skip = 1;
            }
        }
    }
}
,

在 libxml2 的上下文中,这是处理前序和后序遍历的一般方法。正如@chqrlie 所指出的,libxml2 存储一个指向父节点的指针,因此您可以使用常量内存迭代子树。

typedef void
(*callbackFn)(xmlNode *cur,void *data);

void
iterateSubtree(xmlNode *cur,callbackFn callbackPreorder,callbackFn callbackPostorder,void *data) {
    xmlNode *orig;

    if (!cur)
        return;

    orig = cur;
    do {
        callbackPreorder(cur,data);

        while (cur->children) {
            cur = cur->children;
            callbackPreorder(cur,data);
        }

        while (cur != orig) {
            // Storing a copy of next and parent allows the postorder
            // callback to append to or delete a node.
            xmlNode *next = cur->next;
            xmlNode *parent = cur->parent;

            callbackPostorder(cur,data);

            if (next) {
                cur = next;
                break;
            }
            cur = parent;
        }
    } while (cur != orig);

    callbackPostorder(cur,data);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?