2014-10-26 4 views
0

Я очень новичок в программировании. Попытка написать функцию, которая получает головку списка + данные, которые нужно вставить, и возвращает новый заголовок списка. Я много сделал с добавлением элемента в голову списка, но по какой-то причине я не могу обмануть эту небольшую разницу.C: Enqueue() - Вставка в конец связанного списка, возврат главы списка

#include <assert.h> 
#include <stdio.h> 
#include <stdlib.h> 

typedef struct node_{ 
    int data; 
    struct node_ *next; 
} Queue; 

int main(void){ 

    Queue* queue = NULL; 

    queue = enqueue(queue, 1); 

    assert(queue->next == NULL); 
    assert(queue->data == 1); 

    queue = enqueue(queue, 2); 

    assert(queue->data == 1); 
    assert(queue->next != NULL); 
    assert(queue->next->data == 2); 

    free(queue->next); 
    free(queue); 

    return 0; 

} 

Queue *enqueue(Queue *queue, int data){ 

    Queue *new_node, *p; 

    new_node = malloc(sizeof(Queue)); 

    new_node->data = data; 
    new_node->next = NULL; 

    p = queue; 

    while(p->next != NULL){ 
     p = p->next; 
    } 

    p->next = new_node; 

    return ?????? 

} 

Я знаю, что вставить в голову, вы можете:

new_node->data = data; 
new_node->next = queue; 
return new_node; 

Извинения, если то, что я написал выше, не имеет особого смысла. Я довольно устал, и я провел немало итераций. Вероятно, пропало что-то очевидное.

ответ

2

Просто верните queue. Вы также должны проверить, является ли вход queue NULL, и в этом случае вы, очевидно, не можете получить доступ к указателю next, чтобы найти конец, поэтому в этом случае просто верните новый узел.

Queue *enqueue(Queue *queue, int data){ 

    Queue *new_node, *p; 

    new_node = malloc(sizeof(Queue)); 
    new_node->data = data; 
    new_node->next = NULL; 

    if (!queue) 
     return new_node; 

    p = queue; 
    while (p->next) 
     p = p->next; 
    p->next = new_node; 

    return queue; 
} 
+0

Итак, если (queue == NULL) возвращает new_node, правильно? Но как насчет следующей части? Все еще немного смущен. Будет ли мне все еще нужен цикл while для перехода по списку? Как только queue-> next == NULL, возвращает очередь? Но, er, сначала установите queue = new_node? * царапины голова * Извините за плотный! Спасибо, что пытались помочь! – AzathothM

+0

Если очередь пуста, то нет причин (возможности) ее прохождения. Поэтому просто верните новый узел в этот момент. См. Обновленный ответ для некоторого кода. – ooga

+0

святой корова это сработало. Хах. Попытка лучше понять это сейчас. Если queue = NULL, он возвращает new_node. Я понимаю. Если очередь не равна null, она переходит к концу списка и назначает queue-> next to queue. то он назначает new_node queue-> next ... и возвращает очередь. Будет ли это работать более чем на два элемента? Связанные списки заставляют мою голову болеть. Большое вам спасибо за помощь! – AzathothM

1

Как вы отправляете указатель головы, который queue здесь вам не нужно ничего возвращать.


#include<stdio.h> 
#include<stdlib.h> 

typedef struct node_{ 
    int data; 
    struct node_ *next; 
} Queue; 

Queue * enqueue(Queue *queue, int data){ 

    Queue *new_node, *p; 

    new_node = malloc(sizeof(Queue)); 

    new_node->data = data; 
    new_node->next = NULL; 

    p = queue; 

    while(p->next != NULL){ 
     p = p->next; 
    } 

    p->next = new_node; 
    p = new_node; 

    return (queue); 
} 

void display(Queue *queue) 
{ 
    Queue *temp; 
    for(temp=queue->next;temp!=NULL;temp=temp->next) 
     printf("%d -> ",temp->data); 
    printf("null \n"); 
} 

int main(void){ 

    Queue *queue; 
    queue = malloc(sizeof(Queue)); 
    queue->next = NULL; 
    queue = enqueue(queue, 1); 
    queue = enqueue(queue, 2); 
    queue = enqueue(queue, 3); 
    queue = enqueue(queue, 4); 
    display(queue); 
} 

Выход

1 -> 2 -> 3 -> 4 -> null 
+0

Спасибо, что нашли время ответить на мой вопрос! Если бы мне пришлось возвращать указатель на заголовок, как бы вы порекомендовали мне продолжить? Вот почему я так много боролся. Я пытаюсь работать над дополнительным заданием «prelab», которое должно помочь нам подготовиться к лаборатории позже на этой неделе. В присваивании основной использует assert (queue-> next == NULL); и assert (queue-> data == 1) после queue = enqueue (queue, 1), чтобы увидеть, правильно ли работает наша функция. Когда я пытаюсь реализовать свою логику, но с возвратом p в конце, я получаю segfault. Прошу прощения за то, что я медленно! Спасибо, что попробовали! – AzathothM

+0

Я отредактировал свою главную функцию, чтобы показать, как она выглядит. Сейчас он показывает все утверждения. Когда я пытаюсь вернуть очередь, я получаю ошибку seg. Если я изменил свой основной, чтобы иметь очередь-> next = NULL, он работает, но утверждение терпит неудачу в 'queue-> next == ((void *) 0)' failed. Прервано, говорит он. Не уверен, что происходит. На более практическом замечании, я ДУМАЮ, Я понимаю суть происходящего, но я не уверен, почему и p-> next = new_node, и p = new_node – AzathothM

+0

@AzathothM: Это замечательно, что вы поняли.'p-> next = new_node', это добавит ваш новый узел в список, а' p = new_node' переместит 'p' на следующий узел. – user1336087

0

В enqueue функции:

Проверьте, если очередь аргумент NULL, это будет справедливо для 1-й раз, вы должны обрабатывать его как специальный случай:

if (queue == NULL) 
{  
    p = new_node; 
    p->next = NULL; 
    return p; 
} 
Смежные вопросы