2013-04-24 2 views
1

У меня есть проблема с базовым связанным списком, которую я попытался решить ниже. Я был бы признателен за любые входы в мой подход, правильность алгоритма (и даже стиль кодирования). Проблема вызывает функцию, которая удаляет все вхождения int в круговом связанном списке и возвращает любой узел из списка или NULL (когда список имеет значение null).Удаление узла в круговом связанном списке

Вот некоторый код C++, что я до сих пор:

struct Node{ 
    Node* next; 
    int data; 
}; 

Node* deleteNode(Node* &node, int num){ 

    if(!node){ 
     return NULL; 
    } 

    Node* given = node; 
    Node* del; 

    while(node->next != given){ 
     if(node->next->data == num){ 
      del = node->next; 
      node->next = node->next->next; 
      delete del; 
     } 
     node = node->next; 
    } 

    //Check if the first node needs to be deleted, with variable node pointing to last element 
    if(given->data == num){ 
     node->next = given->next; 
     delete given; 
    } 

    return node; 
} 
+1

Вы запросили комментарии к стилю, так что вот один. Вы должны создать класс List, а deleteNode должен быть частным членом этого класса. Вы должны думать в терминах интерфейса, который ваш код представляет пользователю вашего кода. Ни один пользователь класса List не хочет или не хочет знать об узлах, они просто хотят добавлять и удалять элементы из своего списка. Посмотрите на std :: list для примера хорошего дизайна. – john

ответ

1

delete node; должен быть delete del;.

Кроме того, использование Node* node в качестве параметра, вместо того, чтобы Node* &node, который позволит предотвратить не-lvalues ​​от прохождения в.

P.S. Забыли точку с запятой после определения структуры? :)

+0

Вам нужно положить a; после структуры? Я думал, что это было только для классов –

+0

@ yzn-pku Спасибо! Первая проблема - опечатка :) Что касается 2-го момента, исправьте меня, если я ошибаюсь, но я думаю, что если я использую узел «Node *», то я не буду изменять указатель фактического узла. Вот почему я использовал ссылку на указатель узла. И да, добавит точку с запятой после struct :) – KT100

+0

@Jesse, в C++ структура и класс почти одно и то же, единственное отличие - это модификатор доступа по умолчанию: это 'public' для structs и' private' для классов – SingerOfTheFall

1

Не следуя всей вашей логике, я могу сразу увидеть, что этот код не может работать.

Вы проверяете, что список ввода пуст, и это единственный случай, когда ваш код возвращает NULL. Но что произойдет, если вам передан список, в котором все элементы должны быть удалены?

Эта проблема также имеет тонкость в ней. Чтобы проверить, завершили ли вы круговой список, вам нужно сравнить с первым адресом, чтобы узнать, связаны ли вы с началом. Однако, если этот элемент был удален, то по стандарту C++ вы даже не разрешили использовать его адрес в сравнении.

Чтобы избежать двух проходов над элементами, подлежащими удалению, один возможный трюк состоит в том, чтобы «разбить цикл» при запуске итерации, чтобы вы могли проверить NULL вместо проверки адреса стартового узла.

+0

Угловой случай, когда все элементы необходимо удалить, является отличным уловом. Этот код, безусловно, не удастся. Как бы вы рекомендовали изменить цикл while, чтобы позаботиться об этом? Я думаю о том, чтобы обеспечить удаление указателей, чтобы они были установлены в NULL, поэтому мы гарантируем, что в конечном итоге возвращаемый переменный узел равен NULL для этого случая. Обратите внимание, что я проверяю первый элемент списка только в конце, поэтому ваш второй комментарий недействителен AFAIK. Кроме того, не могли бы вы продолжить разработку (с примером кода) по разрыву цикла? Благодаря! – KT100

+0

Я взял сейчас время, чтобы прочитать ваш код, и я вижу другую проблему в вашем подходе. Если в конце вы обнаружите, что узел 'given' должен быть удален, вам также нужно исправить указатель, который ссылается на него.Например, учитывая список '(2, 3, 4, 2, 5, 7)', если вам дано первое '2', и им будет предложено удалить все' 2', вы закончите с '(2, 3, 4 , 5, 7) 'после цикла, а затем вы проверяете удаление' given', но вам также нужно исправить указатель 'next' узла' 7'. – 6502

Смежные вопросы