2015-05-16 2 views
8

Я пишу базовую программу связанных списков в C и имею немного проблем с удалением. Вот что у меня есть:Основной связанный список в C

#include <stdio.h> 

struct node * delete(struct node * head, struct node * toDelete); 
void print(struct node * head); 

struct node { 
    int value; 
    struct node *next; 
}; 

int main(int argc, const char * argv[]) { 

    struct node node1, node2, node3; 
    struct node *head = &node1; 

    node1.value = 1; 
    node1.next = &node2; 

    node2.value = 2; 
    node2.next = &node3; 

    node3.value = 3; 
    node3.next = (struct node *) 0; 

    print(head); 

    delete(head, &node3); 

    print(head); 

    return 0; 
} 

struct node * delete(struct node * head, struct node * toDelete) { 
    //if to delete is head 
    if (head == toDelete) { 
     head = head->next; 

    } else { 
     //find node preceding node to delete 
     struct node *current = head; 
     while (current->next != toDelete) { 
      current = current->next; 
     } 
     current = current->next->next; 
    } 
    return head; 
} 

void print(struct node * head) { 
    struct node *current = head; 

    while (current != (struct node *) 0) { 
     printf("%i\n", current->value); 
     current = current->next; 
    } 
} 

Вопрос № 1: Так что я пытался написать:

delete(head, node3); 

но Xcode хотел добавить "&" перед "node3". Как правило, верно, что, когда я определяю функцию для ввода указателя, мне нужно передать адрес памяти?

Вопрос № 2:

Моя функция печати работает для распечатки значений 3 узлов. После вызова delete и попытки удалить node3, он все еще печатает 3 узла. Я не знаю, где я ошибся. Я нахожу узел, предшествующий тому, который я хочу удалить, и установите его следующий указатель на узел после узла после (неофициально: node.next = node.next.next).

Любые идеи?

Спасибо за помощь, bclayman

+1

(1) да, * указатель * на что-то означает, что вам нужно * адрес * что-то. (2) ваша функция удаления ничего не делает: 'current = current-> next-> next;' только изменяет локальную переменную. – lurker

ответ

4

Является ли это вообще правда, что когда я определить функцию взять указатель, мне нужно передать в адрес памяти?

Да, xКод является правильным. node3 - это struct node, но ваша функция delete принимает в качестве второго параметра struct node *, поэтому вам нужно передать указатель на node3, а не на переменную.

После вызова удаления и попытки удалить узел3 он по-прежнему печатает 3 узла.

Это потому, что вы не меняете значение next. Кроме того, чтобы быть память безопасным, не забудьте проверить, если указатель NULL:

while ((current->next != toDelete) && (current->next != NULL)) { 
    current = current->next; 
} 
if (current->next != NULL) 
    current->next = current->next->next; 
4

Просто попробуйте изменить current = current->next->next; к current->next=current->next->next. Дайте мне знать, если это не сработает.

6

Вы должны передать его &node3. Для удаления, пожалуйста, измените ваш код от current = current->next->next; к current->next = current->next->next;

7
but xCode wanted me to add "&" in front of "node3". Is it generally true that 
when I define a function to take a pointer, I need to pass in the memory 
address? 

да, если вы объявляете функцию взять указатель, вы должны передать это указатель.

Также при удалении значения из связанного списка вы собираетесь хотите изменить

current->next = current->next->next 
Смежные вопросы