首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于将列表展平为单个列表的函数

用于将列表展平为单个列表的函数
EN

Stack Overflow用户
提问于 2010-12-20 15:55:42
回答 5查看 974关注 0票数 4

给定一个链表结构,其中每个节点表示一个链表,并包含其类型的两个指针:

(i)指向主列表中下一个节点的指针。

(ii)指向该节点为头部的链表的指针。

编写一个C函数来将列表展平为单个链表。

例如:

如果给定的链表是

代码语言:javascript
复制
  1 -- 5 -- 7 -- 10 
  |    |    | 
  2    6    8 
  |    | 
  3    9 
  | 
  4 

然后将其转换为

代码语言:javascript
复制
1 - 2 - 3 - 4 - 5 - 6 - 9 - 7 - 8 -10 

我的解决方案

代码语言:javascript
复制
struct node {
    int data; 
    struct node *fwd; //pointer to next node in the main list. 
    struct node *down; //pointer to a linked list where this node is head. 
}*head,*temp,*temp2; 

temp=head; 
while(temp->fwd!=NULL) {
    temp2=temp->fwd; 
    while(temp->down!=NULL) {
        temp=temp->down;
    } 
    temp->down=temp2;
    temp->fwd=NULL;
    temp=temp2;
 }  

如果欢迎anything...other解决方案和优化,请通知我

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-12-20 17:09:24

首先,让它正常工作是很重要的。由于while(temp->fwd!=NULL),您的解决方案不适用于这些场景:

代码语言:javascript
复制
A) 1 -- 2     B) 1 -- 3
        |        |    |
        3        2    4

试着这样做:

代码语言:javascript
复制
#include <stdio.h>

struct node {
    int data;
    struct node *fwd; //pointer to next node in the main list.
    struct node *down; //pointer to a linked list where this node is head.
};

struct node *solve(struct node *head) {
    struct node *temp = head, *fwd;
    while (temp != NULL) {
        fwd = temp->fwd;
        while (temp->down != NULL) {
            temp = temp->down;
        }
        temp->down = fwd;
        temp->fwd = NULL;
        temp = fwd;
    }
    return head;
}

int main(int argc, char **argv) {
    struct node
        n12 = { 12, NULL, NULL },
        n11 = { 11, NULL, &n12 },
        n10 = { 10, NULL, &n11 },
        n8 = { 8, NULL, NULL },
        n7 = { 7, &n10, &n8 },
        n9 = { 9, NULL, NULL },
        n6 = { 6, NULL, &n9 },
        n5 = { 5, &n7, &n6 },
        n4 = { 4, NULL, NULL },
        n3 = { 3, NULL, &n4 },
        n2 = { 2, NULL, &n3 },
        n1 = { 1, &n5, &n2 },
        *result = solve(&n1);

    while (result != NULL) {
        printf("%d%s", result->data, result->down ? " - " : "");
        result = result->down;
    }
    puts("");

    return 0;
}

注意:,这当然不涉及node->down->fwd。你可能想使用一个递归函数来解决这个问题,这个函数留作练习。

票数 1
EN

Stack Overflow用户

发布于 2010-12-20 16:30:50

如果您将“向下”链接视为左子指针,而将“向前”链接视为右子指针,则您正在寻找简单二叉树的顺序遍历。也就是说,您先访问节点;然后访问左(下)子节点,然后访问右(前)子节点。把它写成递归函数是很容易的。

如果第一个节点只有一个向下指针而没有向前指针,那么您的解决方案将不会遍历任何树。如果最后一个指针有向下指针(因为它没有向前指针),它也不会从最后一个指针开始向下搜索。

我认为(但我不确定--我还没有测试过它)您的解决方案在比示例中更茂密的树上遇到了麻烦。如果节点2有前向指针,我认为在搜索该子树时会出现问题。

使用递归;它是微不足道且可靠的。虽然您可以消除简单的尾递归,但这需要的不仅仅是简单的尾递归。

票数 1
EN

Stack Overflow用户

发布于 2014-11-12 01:51:24

代码语言:javascript
复制
struct node* flatten_dfwalk(struct node * root)
{   

    struct node *lnode, *rnode, *temp;

    if (NULL == root)
    {
        return NULL;
    }


    lnode = flatten_dfwalk(root->down);
    rnode = flatten_dfwalk(root->next);

    if (NULL == lnode)
    {
        return root;
    }

    temp = lnode;
    while(lnode->next != NULL)
    {
        lnode = lnode->next;
    }

    lnode->next = root->next;
    root->next = temp;

    return root;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4487797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档