给定一个链表结构,其中每个节点代表一个链表和 包含两个类型的指针:
(i)指向主列表中下一个节点的指针 (ii)指向此节点为head的链表的指针。
编写C函数以将列表展平为单个链表。
EG。
如果给定的链表是
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;
}
如果有的话,请通知我......欢迎提供其他解决方案和优化
答案 0 :(得分:1)
如果将'down'链接视为左子指针,并将'forward'链接视为右子指针,那么您正在寻找一个简单二叉树的有序遍历。也就是说,你访问节点;然后你访问左(下)孩子,然后你访问右(前)孩子。将其作为递归函数编写非常容易。
如果第一个节点只有一个向下指针而没有前向指针,那么您的解决方案将不会遍历任何树。如果它有向下指针(因为它没有前向指针),它也不会从最后一个指针向下搜索。
我认为(但我不确定 - 我还没有测试过)你的解决方案在比实例中的树更麻烦的树上遇到麻烦。如果节点2有前向指针,我认为在搜索子树时会出现问题。
使用递归;它是微不足道和可靠的。虽然你可以消除简单的尾递归,但这不仅仅需要简单的尾递归。
答案 1 :(得分:1)
首先让它运作起来很重要。由于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;
}
注意:这当然不涉及node->down->fwd
。您可能希望使用递归函数来解决这个问题,该函数留作练习。
答案 2 :(得分:1)
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;
}
答案 3 :(得分:0)
解决方案看起来不错。一个微小的变化可能是从解决方案的图表,我希望答案应该是一个“水平”列表(使用fwd指针)而不是你的解决方案产生的垂直指针(使用向下指针)
答案 4 :(得分:-2)
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;
}
}