【问题标题】:fill empty linked list from another linked list in c languagec语言从另一个链表填充空链表
【发布时间】:2015-01-25 18:07:51
【问题描述】:

我有一个完整的链表,里面有数据,我想要的是用相同的数据填充另一个链表,但有一个条件,所以假设这是链表:

char cl; 
int time; 
int lng;

C 0 1

D 0 2

B 2 1

A 2 2

我想从这个列表复制到一个新的空列表,但前提是(时间>0),所以新的将是这样的:

B 2 1

A 2 2

我试过这段代码,但它不起作用:

void insert(const node * n )// this where i put the pointer of the full node
{
    node *head=n;
    node *sec; // new node
    sec=(node*)malloc(sizeof(node)); 

    do{
        if(head->time>0){
            strcpy(sec->cl,head->cl);
            sec->time= head->time;
            sec->lng= head->lng;
            head=head->next;
            sec=sec->next;
        }
        else 
            head=head->next;
    }while(head!=NULL);
    print(sec) // this will print the new node
}

请帮帮我。谢谢

【问题讨论】:

  • 'new'是c++中的保留字,如果编译器既懂C又懂C++,就会出问题。
  • 你是如何创建原始链表的?为什么你不能使用你用来构建该列表的函数?
  • 您只为sec 中的第一项而不是后续的分配内存,sec=sec->next 将导致未定义的行为,因为该字段尚未初始化。
  • 删除else head=head->next;之前的else
  • while(head!=NULL) 应该在循环的顶部,而不是尾部。

标签: c list linked-list


【解决方案1】:

我结合了来自 cmets 的所有建议以及一些额外的修复。 这是生成的代码:

const node* insert(const node * head)
{
    node *sec = NULL;  // start of the new, second list
    node *last = NULL; // points to the last inserted node

    while(head!=NULL){
        if(head->time > 0){
            node* newsec=(node*)malloc(sizeof(node)); 
            newsec->cl = head->cl;
            newsec->time = head->time;
            newsec->lng = head->lng;
            newsec->next = NULL;
            //Add the new node to the list:
            if(last == NULL){ //This is the first element in the new list
               sec = newsec;
            }else{
               last-> next = newsec;
            }
            last = newsec;
        }
        head=head->next;
    }
    print(sec); // this will print the new node
    return sec;
}

你的错误:

  • 错误的内存分配(您只分配了一次内存)
  • 不需要strcpy(char不需要字符串副本)
  • while 必须位于循环的开头(如果给定列表为空,您的代码将失败)
  • 缺少分号
  • 新列表连接错误
  • 错误的 const 正确性(node *head=n; 中缺少 const)
  • 内部head-变量不是必须的(而且参数命名n也不理想。如果命名为“start”/“head”/“begin”,注释就不需要了)

另一个建议:为您的结构使用大写名称,因为这样更容易区分类型和变量(应该是Node,而不是node)

请注意,您可能希望从返回值类型中删除 const

【讨论】:

  • node newsec 应该是node *newsec,并且不要强制转换 malloc 的结果。
  • @Jite 我猜 OP 正在使用 C++ 编译器,这需要强制转换。
  • 你为什么会这样猜?它是 C 代码,要编译 C 代码,您使用 C 编译器,即使编译器可以编译 C++。没有必要,而且确实不建议在 C 中转换 malloc 的结果。问题标记为 C。
  • 例程不应该返回sec作为复制列表的头部吗?
  • @Jite C++ 需要强制转换 malloc 的结果 (stackoverflow.com/questions/3477741/…) - 虽然问题被标记为 C,但我认为 OP 实际上使用的是 C++ 编译器,因为他使用了@987654332 @在他最初的帖子中。如果他实际上使用的是 C 编译器,他可以删除强制转换。 (我想确保我的答案适用于他的设置。)
【解决方案2】:
// Note: a better function name might be: printNodesWithTime

void insert(const node * pOld )
{

    // note: since nothing is done with the new linked list,
    //       there is no need to actually create it

    while( NULL != pOld )
    {

        if(pPld->time > 0)
        {
            print(pOld) // this will print the node
        }

        // step to next old node
        pOld = pOld->next;

    } // end while
} // end function: insert

【讨论】:

  • 现在,如果 OP 确实想要保留一个“提取”的链表,那么上述将不是一个合适的答案
  • OP 想要创建原始列表的副本,按时间过滤。
猜你喜欢
  • 1970-01-01
  • 2016-02-14
  • 1970-01-01
  • 2014-05-07
  • 2014-02-11
  • 1970-01-01
  • 2016-12-01
  • 2019-09-04
  • 1970-01-01
相关资源
最近更新 更多