该函数返回一个列表,该列表包含出现在列表“ A”中“ pos_list”中给定位置的值

时间:2019-10-04 07:50:19

标签: c algorithm linked-list singly-linked-list deep-copy

-如果列表具有整数数据,例如:1-> 2-> 3-> 4-> 5-> 6 -并且pos_list具有整数数据,例如:4-> 0-> 5 -然后此函数应返回一个New List帽子,其中包含出现在pos_list中给定位置的列表A中的值 这样New List = 5-> 1-> 6

我正在实现深层复制以创建新列表。 我正在尝试使用根据pos_list数据进行迭代的循环。在此循环内,A的节点将移动到pos_list数据的位置。这一次,我将在新列表中复制节点A,以创建另一个列表。 对于第一种情况,pos_list具有数据4,因此循环将运行4次,直到list A的节点指向其第四位置。在此循环中,我将在新循环中复制列表A的数据。 我需要一个指导来解决这个问题。

struct node * sublist(struct node * A, struct node * pos_list) {
struct node* newList=NULL;
struct node * curr;
int i=0;

for (i = 0, curr = pos_list->next; (curr != NULL); curr = curr->next) { //pos_list->data has a dummy node so loop until the end of pos_list->data.
   struct node* newList = (struct node *) malloc(sizeof (struct node));

    for(int i=0;i<=pos_list->data;i++){   //counter for pos_list as it will be (3 then 0,6 and 4)
        if(i==pos_list->data){            //At the time when i == pos_list->data(3 or 0 or 6..)
            newList->data = A->data;      //Putting value of list A data in new list.
            newList = newList->next;      //Linking
            printf("%d\t", newList->data);   //Just for log
        }
        A=A->next;                       //Going to next position on A
    }
   pos_list=pos_list->next;             //Going to next position on B
}
return newList ;
}

如果列表为:1-> 2-> 3-> 4-> 5-> 6 pos_list是:4-> 0-> 5

我希望输出是新列表,如5-> 1-> 6

3 个答案:

答案 0 :(得分:1)

您的代码有几个问题:

  • 您应使用pos_list而不是pos_list->next开始遍历。头指针指向的节点是列表的一部分。此外,如果pos_list == NULLpos_list->next将导致不确定的行为。
  • int i的外部定义没有用。删除它。
  • 请勿通过该职位来遍历A。如果位置无效,则将超出列表的末尾,获取空指针并调用未定义的行为。列表应由从先前节点的next指针访问的列表节点进行迭代。 (当然,调用者有责任提供有效的头寸,但您的程序应妥善处理无效的输入。)
  • 仅在找到有效位置后才创建新节点。否则,您将创建一个永远不会插入的节点,从而泄漏内存。
  • 此处:newList = newList->nextnewList->next未初始化。请记住,malloc为您提供了大量未初始化的数据。
  • 您尝试使newList指向新创建的列表的末尾,以便快速添加新节点。这是一个好主意,但是如果返回该指针,则将获得仅包含一个元素的列表。 (您也将没有日志程序可以访问该列表中以前创建的任何节点。)

这是应该起作用的实现:

struct node *sublist(struct node *A, struct node *pos_list)
{
    struct node *newHead = NULL;
    struct node *newTail = NULL;
    struct node *pos = pos_list;

    while (pos) {
        struct node *a = A;
        int i = 0;

        while (a) {
            if (i == pos->data) {
                struct node *node = malloc(sizeof(*node));

                if (newHead == NULL)  newHead = node;
                if (newTail) newTail->next = node;
                node->data = a->data;
                node->next = NULL;
                newTail = node;

                break;
            }

            a = a->next;
            i++;
        }

        pos = pos->next;
    }

    return newHead;
}

答案 1 :(得分:0)

问题不容忍使用“结构”来实现解决方案。 如果可以,那么我会弄错了,但是如果没有,那是不是过大了,当可以执行类似于以下内容的事情时......

#include <stdio.h> 
#define CREATE_ARRAY(n) int result[n]

void main() {
  int data[] = {1,2,3,4,5,6};
  int pos[] = {4,0,5};
  int i;

  CREATE_ARRAY(sizeof(pos)/sizeof(int));
  for(i = 0; i < sizeof(pos)/sizeof(int);++i)
    result[i] = data[pos[i]];
/*
  To print the values stored in result
  for(i = 0;i < sizeof(result)/sizeof(int); ++i)
    printf("%d ",result[i]);
  putchar('\n');
}
*/

答案 2 :(得分:0)

对于初学者来说,函数sublist的声明应类似于

struct node * sublist( const struct node *A, const struct node *pos_list );

因为列表A和列表pos_list均未在函数中更改。否则,该函数的声明会使代码阅读者感到困惑。

一个糟糕的主意是列表pos_list包含一个虚拟节点,因为它写在该语句的注释中

for (i = 0, curr = pos_list->next; (curr != NULL); curr = curr->next) { //pos_list->data has a dummy node so loop until the end of pos_list->data

两个虚拟节点都不应在列表中。

在这个内循环中

for(int i=0;i<=pos_list->data;i++){

没有使用列表的虚拟节点。此外,pos_list在两个循环中遍历:外部循环和内部循环

for (i = 0, curr = pos_list->next; (curr != NULL); curr = curr->next) { //pos_list->data has a dummy node so loop until the end of pos_list->data.
   struct node* newList = (struct node *) malloc(sizeof (struct node));

    for(int i=0;i<=pos_list->data;i++){

在循环中,变量newList的值已更改

newList = newList->next;

因此,该函数始终返回一些不确定的值,而不是新创建的列表的开头。该值不确定,因为未初始化新创建节点的下一个数据成员。

newList->data = A->data;      //Putting value of list A data in new list.
newList = newList->next; 

可以通过以下方式定义功能

struct node * sublist( const struct node *A, const struct node *pos_list ) 
{
    struct node *newList = NULL;
    struct node **current = &newList;

    for ( ; pos_list != NULL; pos_list = pos_list->next )
    {
        const struct node *target = A;

        for ( int index = pos_list->data; index != 0 && target != NULL; --index )
        {
            target = target->next;
        }

        if ( target != NULL )
        {
            *current = malloc( sizeof( struct node ) );
            ( *current )->data = target->data;
            ( *current )->next = NULL;
            current = &( *current )->next;
        }
    }

    return newList;
}