2010-05-22 3 views
0

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

//reverse the linked list 
    #include <iostream> 
    using namespace std; 

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

    node *A; 

    void addNode(node *&listpointer, int num){ 
     node *temp; 
     temp = new node; 
     temp->number = num; 
     temp->next = listpointer; 
     listpointer = temp; 
    } 

    void reverseNode(node *&listpointer){ 
     node *temp,*current; 
     current = listpointer; 
     temp = new node; 
     while (true){ 
      if (current == NULL){ 
       temp = NULL; 
       break; 
      } 
      temp->number = current->number; 
      current = current->next; 
      temp = temp->next; 
     } 
     listpointer = temp; 
    } 

    int main(){ 
     A = NULL; 
     addNode(A,1); 
     addNode(A,2); 
     addNode(A,3); 

     while (true){ 
      if (A == NULL){break;} 
      cout<< A->number << endl; 
      A = A->next; 
     } 
     cout<< "****" << endl; 
     reverseNode(A); 

     while (true){ 
      if (A == NULL){break;} 
      cout<< A->number << endl; 
      A = A->next; 
     } 

     cout<< "****"<< endl; 

     return 0; 
    } 
+0

Я полагаю, что это домашнее задание. Итак, разрешено ли вам использовать двусвязные списки и/или рекурсию? –

+0

не домашнее задание, но им нужно знать, как это сделать где-то по пути – silent

ответ

3

Ну, первое, что я замечаю, что вы делаете

темп = новый узел

, а затем, на каждом взаимодействии:

Темп = TEMP-> следующая

но вы никогда не назначаете temp-> next

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

+1

Вы также проливаете память. В целом, ваш алгоритм обратного хода не будет работать. Лучший способ перевернуть один связанный список - это сделать это рекурсивно: здесь также есть связанный с этим вопрос: http://stackoverflow.com/questions/2434411/linked-list-recursive-reverse – garph0

+0

Существует также простой итерационный алгоритм. См. [Обратный список с одним цепочкой] (http://stackoverflow.com/questions/1432205/reverse-a-single-chained-list). –

0

Не проверяя свой код Я спрашиваю вас, вы уверены, что ваш связанный список работает?

+0

yup связанный список работает нормально, просто нужно обратная связь по функции reverseNode – silent

+0

Связанный список, кажется, вставляет элементы в начале. Я не уверен, что это намеренно. –

1

Вы можете сделать это:

while (true){ 
    if (current == NULL){ 
     temp = NULL; 
     break; 
    } 
    temp->number = current->number; 
    current = current->next; 
    temp = temp->next; 
} 

Предположим, что это работает, как и предполагалось. Когда существует время, temp будет NULL, правильно?

listpointer = temp; <=> listpointer = NULL; 

Так что это может быть проблемой.

-1

почему нет:

  1. мера длина вашего списка

  2. заполнить добавить свой список с нулями, пока вы не достигнете двойного размера вашего существующего списка

  3. перейти к начало списка,

  4. читайте содержание один за другим, пока не достигнете конца исходного списка

  5. при движении в первоначальном списке:

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

    ((исходная длина списка - текущий индекс узла) * 2 + 1) * размер узла

  7. после того, как вы закончите, указатель первого узла после первоначального списка, чтобы указать на перевернутом список

без того, чтобы создать новый список или работать на нескольких итераций или изменить существующую структуру данных (не превращая его в двойной связанный список)

+0

1, 2 и 4 все занимают время, пропорциональное размеру списка. 2 принимает пропорциональную ему память. Кроме того, для # 6 требуется перемещение назад или повторное повторение до нужного индекса (квадратичного). Я не думаю, что этот алгоритм является разумным. –

+0

это должно быть примерно так: узел + ((max-idx) * 2 + 1) * sizeof (node) = node-> number; узел ++; –

+0

Вы не можете выполнить арифметику указателей. Это связанный список. Кроме того, арифметика указателя обрабатывает * sizeof * для вас. –

0
void reverse(Node** list) { 
    Node* previous=NULL; 
    Node* current=*list; 
    while (NULL!=current) { 
     std::swap(previous, current->next); 
     std::swap(previous, current); 
    } 
    *list=previous; 
} 
Смежные вопросы