Функция InsertAfter в односвязном списке (C) - PullRequest
0 голосов
/ 12 марта 2019

Мне нужно написать код для вставки нового узла со значением после первого узла, который содержит findValue. Если findValue отсутствует в списке, вставьте новый узел в качестве хвоста связанного списка.

Я получаю ошибку сегментации, когда пытаюсь что-то вставить. Ищите, почему это происходит и в чем ошибка в коде.

void insertAfter(listNode **listPtr, int findValue, int value) {    
  while((*listPtr)->next !=NULL){
    if((*listPtr)->value ==findValue){
      listNode *newNodePtr=(listNode *)malloc(sizeof(listNode));
      newNodePtr->value = value;
      newNodePtr->next = (*listPtr)->next;
      (*listPtr)->next =newNodePtr;
      (*listPtr)=(*listPtr)->next;
     }
   if((*listPtr)->next ==NULL){
     listNode *newNodePtr = (listNode *)malloc(sizeof(listNode));
     newNodePtr->value = value;
     newNodePtr->next = NULL;
     (*listPtr)->next=newNodePtr;}
  }
}

Ответы [ 2 ]

0 голосов
/ 12 марта 2019

Если ваш *listPtr равен NULL, вы получите ошибку сегмента в этой строке: while((*listPtr)->next !=NULL){

Это первая строка в вашей функции.

Попробуйте следующий код. Я добавил соответствующие проверки, а также удалил ненужный беспорядок:

void insertAfter(listNode **listPtr, int findValue, int value) {

    listNode * newNodePtr = malloc(sizeof(listNode));
    newNodePtr->value = value;
    newNodePtr->next = NULL;


    if ((*listPtr) == NULL ){
    (*listPtr) = newNodePtr;
    return;
    }

    while ( (*listPtr)->next != NULL ){    

    if ((*listPtr)->value ==findValue){
        newNodePtr->next = (*listPtr)->next;
        (*listPtr)->next =newNodePtr;
        return;
    }   
    (*listPtr) = (*listPtr)->next;
    }


    (*listPtr)->next =newNodePtr;

}

Наконец, мне было интересно, почему вы берете указатель на указатель. Таким образом, вы измените исходный указатель. Я думаю, вы не должны этого делать. Вам следует только изменить COPY указателя, а не исходный указатель. Поскольку я считаю, что этот указатель является главой связанного списка.

Я рекомендую изменить listNode **listPtr на listNode *listPtr и соответственно изменить определение.

0 голосов
/ 12 марта 2019

Ваш абзац не соответствует вашим скобкам.До:

while((*listPtr)->next !=NULL){
  if((*listPtr)->value ==findValue){
  }
if((*listPtr)->next ==NULL){
   }
}

после:

while((*listPtr)->next !=NULL){
  if((*listPtr)->value ==findValue){
  }
}
if((*listPtr)->next ==NULL){
}

Обычно мы не любим код с испорченным отступом.Трудно понять, что не так.Но этот код все равно не будет работать, потому что больше ошибок.Давайте попробуем это:

while((*listPtr)->next !=NULL){
  if((*listPtr)->value ==findValue) {
    listNode *newNodePtr=(listNode *)malloc(sizeof(listNode));
    newNodePtr->value = value;
    newNodePtr->next = (*listPtr)->next;
    (*listPtr)->next =newNodePtr;
    return;
  }
  listPtr = &((*listPtr)->next); /* advancer was really messed up */
}
if((*listPtr)->next ==NULL){
  listNode *newNodePtr = (listNode *)malloc(sizeof(listNode));
  newNodePtr->value = value;
  newNodePtr->next = NULL;
  (*listPtr)->next=newNodePtr;
}

Но мы можем удалить большое количество дубликатов:

while((*listPtr) != NULL){
  if((*listPtr)->value ==findValue) {
    break;
  }
  listPtr = &((*listPtr)->next);
}
listNode *newNodePtr = (listNode *)malloc(sizeof(listNode));
newNodePtr->value = value;
newNodePtr->next = (*listPtr)->next;
(*listPtr)->next=newNodePtr;

Или даже более кратко:

for(;*listPtr && (*listPtr)->value != findValue;
    listPtr = &((*listPtr)->next)) { }
struct listNode *newNodePtr = malloc(sizeof(struct listNode));
newNodePtr->value = value;
newNodePtr->next = (*listPtr)->next;
(*listPtr)->next=newNodePtr;

На этом этапеОстальные ошибки в исходном коде являются адресуемыми:

for(;*listPtr && (*listPtr)->value != findValue;
    listPtr = &((*listPtr)->next)) { }
struct listNode *newNodePtr = malloc(sizeof(struct listNode));
if (*listPtr) { /* it's insert after, not insert before, but we have to handle not finding anything and putting it on the end */
    newNodePtr->value = *listPtr->value;
    *listPtr->value = value;
} else {
    newNodePtr->value = value;
}
newNodePtr->next = *listPtr; /* Don't try to follow next off the end */
*listPtr = newNodePtr;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...