C 函数将列表展平为单个列表

C 函数将列表展平为单个列表,c,algorithm,linked-list,C,Algorithm,Linked List,给定一个链表结构,其中每个节点表示一个链表,并且 包含其类型的两个指针: (i) 指向主列表中下一个节点的指针。 (ii)指向链接列表的指针,其中该节点为头部 编写一个C函数将列表展平为单个链接列表 例如 如果给定的链表是 1 -- 5 -- 7 -- 10 | | | 2 6 8 | | 3 9 | 4 然后将其转换为 1 - 2 - 3 - 4 - 5 - 6 - 9 - 7 - 8 -10 我的解决方案 s

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

(i) 指向主列表中下一个节点的指针。
(ii)指向链接列表的指针,其中该节点为头部

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

例如

如果给定的链表是

  1 -- 5 -- 7 -- 10 
  |    |    | 
  2    6    8 
  |    | 
  3    9 
  | 
  4 
然后将其转换为

1 - 2 - 3 - 4 - 5 - 6 - 9 - 7 - 8 -10 
我的解决方案

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;
 }  

如果有任何问题,请通知我…欢迎使用其他解决方案和优化

解决方案在我看来还可以。一个微小的变化可能是,从解决方案的图表中,我希望答案应该是一个“水平”列表(使用fwd指针),而不是解决方案生成的垂直列表(使用向下指针),如果您将“向下”链接视为左子指针,“向前”链接视为右子指针,然后,您正在寻找一个简单二叉树的顺序遍历。即访问节点;然后访问左(下)子对象,然后访问右(前)子对象。把它写成递归函数很容易

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

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


使用递归;它是琐碎而可靠的。虽然可以消除简单的尾部递归,但这需要的不仅仅是简单的尾部递归。

首先,让它工作起来很重要。由于
while(temp->fwd!=NULL)
,您的解决方案不适用于以下情况:

A) 1 -- 2     B) 1 -- 3
        |        |    |
        3        2    4
请尝试以下方法:

#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;
}
#包括
结构节点{
int数据;
struct node*fwd;//指向主列表中下一个节点的指针。
struct node*down;//指向此节点所在的链表的指针。
};
结构节点*求解(结构节点*头){
结构节点*temp=head,*fwd;
while(temp!=NULL){
fwd=温度->fwd;
while(临时->停机!=NULL){
温度=温度->下降;
}
温度->下降=前进;
temp->fwd=NULL;
温度=fwd;
}
回流头;
}
int main(int argc,字符**argv){
结构节点
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},
*结果=求解(&n1);
while(结果!=NULL){
printf(“%d%s”,结果->数据,结果->向下?”-“:”);
结果=结果->向下;
}
认沽权(“”);
返回0;
}

注意:这当然不涉及
节点->向下->前进
。您可能希望使用递归函数来解决这个问题,这只是一个练习。

我的解决方案:struct node{int data;struct node*fwd;//指向主列表中下一个节点的指针。struct node*down;//指向此节点为head的链接列表的指针。}*head,*temp,*temp2;温度=水头;while(temp->fwd!=NULL){temp2=temp->fwd;while(temp->down!=NULL){temp=temp->down;}temp->down=temp2;temp->fwd=NULL;temp=temp2;}如果有任何其他解决方案和优化需要,请通知我welcome@wilhelmtell当前位置从写作方式猜测你是对的。不,这不是家庭作业……这是一个面试问题。你能提出更好的答案吗?@sjngm它缺少最后一部分:“或者你得了D”@prp列表旅行对于一个好的面试问题来说似乎太幼稚了。如果乔纳森的解决方案对你来说没有意义,只要看看你的列表图表,同时把头向左倾斜45度。
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;
}
    struct node * last;
    void dfs(struct node * root)
    {
        if(root)
        {
            dfs(root->down);
            if(last!=NULL)
            {
                last->next=root->next;
                last=NULL;
            }
            dfs(root->next);
            if(root->down)
            root->next=root->down;

            if(root->next==NULL&&root->down==NULL)
                last=root;
        }
    }