Эта функция возвращает список, который содержит значения, которые появляются в списке «A» в позициях, указанных в «pos_list» - PullRequest
2 голосов
/ 04 октября 2019

-Если список содержит целочисленные данные, такие как: 1-> 2-> 3-> 4-> 5-> 6 -И в списке pos_list есть целочисленные данные, такие как: 4-> 0-> 5 -Тогда эта функция должнаreturn new New list содержит значения, которые появляются в списке 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

Ответы [ 3 ]

1 голос
/ 04 октября 2019

Ваш код имеет несколько проблем:

  • Вы должны начать свой обход с pos_list, а не с pos_list->next. Узел, на который указывает указатель головы, является частью списка. Кроме того, если pos_list == NULL, pos_list->next приведет к неопределенному поведению.
  • Внешнее определение int i бесполезно. Удалите его.
  • Не просматривайте A с помощью позиции. Если позиция недопустима, вы выйдете за пределы списка, получите нулевые указатели и вызовете неопределенное поведение. Списки должны повторяться по узлам списков, к которым обращались указатели next предыдущих узлов. (Это, конечно, обязанность вызывающего абонента предоставлять правильные позиции, но ваша программа должна корректно обрабатывать некорректный ввод.)
  • Создавать новый узел только тогда, когда вы нашли правильную позицию. В противном случае вы создаете узел, который никогда не вставляется, и, таким образом, теряете память.
  • Здесь: newList = newList->next, newList->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;
}
0 голосов
/ 04 октября 2019

Для начала функцию 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;
}
0 голосов
/ 04 октября 2019

Вопрос не оправдывает использование "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');
}
*/
...