此函数 returns 一个列表,其中包含出现在列表 "A" 中 "pos_list" 中给定位置的值

This function returns a list that contains the values that appear in list "A" at positions given in "pos_list"

-如果A列表有整数数据如:1->2->3->4->5->6 - 而pos_list有整数数据如:4->0->5 -那么这个函数应该 return 一个新列表帽子包含出现在列表 A 中 pos_list 中给定位置的值 这样 New List= 5->1->6

我正在实施深度复制以制作新列表。 我正在尝试使用根据 pos_list 的数据进行迭代的循环。在这个循环中,A 的节点将移动到 pos_list 数据的位置。这次我将复制新列表中的节点 A 以制作另一个列表。 对于第一种情况,pos_list 有数据 4,因此循环将 运行 4 次,直到列表 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

您的代码有几个问题:

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

这是一个应该有效的实现:

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

问题不允许使用 "struct" 来实现解决方案。 如果是,我错了,但如果不是,这不是矫枉过正,当类似于以下的东西可以实现时....

#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');
}
*/

对于初学者来说,函数 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;

因此函数总是 returns 一些不确定的值而不是新创建列表的头部。该值是不确定的,因为新创建的节点的数据成员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;
}