2014-02-01 5 views
1

Я работаю в C, и я пытаюсь создать программу, которая читает строки из файла и сортирует их в двойной список. В настоящее время я могу правильно прочитать файл, и до того, как я добавил функцию сортировки, двойной связанный список записывал значения, как ожидалось, но по какой-то причине теперь я пытаюсь добавить значения в середину списка, а не просто в конце весь список переписывается с помощью самого последнего ввода. Ниже приведена моя инициализация структуры данных и реализация функции вставки. Я использую параметр ID для сортировки узлов, и в конце, если я выдаю идентификаторы, они находятся в правильном порядке, это просто данные, сохраненные в переменной val (которая является строкой из файла), которая не сохранить правильно. Благодаря!Вставка значения в середину двойного связанного списка

typedef struct ListNode { 
    struct ListNode *next; 
    struct ListNode *prev; 
    char *val; 
    int id; 
} ListNode; 

typedef struct List { 
    int count; 
    ListNode *first; 
    ListNode *last; 
} List; 


void List_push(List *list, char *newval, int id) 
{ 
    ListNode *node = malloc(sizeof(ListNode)); 

    if(list->count >0) { 
      printf("First in list is now %s", list->first->val); 
    } 

    node->val = newval; 
    node->id = id; 
    printf("This value is: %s The id is: %d\n", node->val, node->id); 
    if(list->last == NULL) { 
      printf("List is empty, inserting first element\n"); 
      list->first = node; 
      list->last = node; 
    } 
    else if(node->id < list->first->id) { 
      printf("Value is smaller than first in list\n"); 
      printf("First in list was %s \n", list->first->val); 
      node->next = list->first; 
      printf("%s is now second\n", node->next->val); 
      list->first->prev = node; 
      printf("First in list is now %s", list->first->prev->val); 
      list->first = node; 
      printf("First in list is now %s\n", list->first->val); 
      printf("Then %s\n", list->first->next->val); 
    } 
    else { 
      node->next = list->first; 
      printf("Value bigger than first in list\n"); 
      int found = 0; 
      while((node->next != NULL) && (found ==0)) { 
        if(node->id < node->next->id) { 
          found = 1; 
        } 
else { 
          printf("Still looking\n"); 
          printf("%d\n", node->next->id); 
          node->next = node->next->next; 
        } 
      } 
      if(found == 1) { 
        printf("Found location\n"); 
        node->prev = node->next->prev; 
        node->next->prev = node; 
        printf("First in list: %d\n", list->first->id); 
      } 
      else { 
        list->last->next = node; 
        node->prev = list->last; 
        list->last = node; 
      } 
    } 

    list->count++; 
} 
+0

Просьба показать образец ввода и вывода. –

+0

Откуда берется 'newval'? Указывает ли это на ваш входной буфер или вы сделали копию ввода перед вызовом 'List_push'? – Notlikethat

+2

С двусвязным списком необходимо установить четыре указателя, чтобы вставить элемент между двумя элементами (по одному из существующих элементов, чтобы указать на новый элемент, и два в новом элементе, чтобы указать на существующие элементы). В вашем последнем if/else я вижу только обновление двух и трех указателей. При отладке структур данных, подобных этому, создайте чертеж, который вы обновляете по мере запуска кода (измените только то, что изменит код, не рисуйте, что вы думаете *, должно быть только то, что * действительно делает *, и вы найдете свою ошибку). – Dithermaster

ответ

0

В Found location блоке вы забыли установить next предыдущего узла; изменить

   node->next->prev = node; 

в

   node->prev->next = 
       node->next->prev = node; 

там.

0

Длинный короткий вставки узла в середине связанного списка, как это:

  1. У вас есть функция, которая передаст в ДЕЙСТВУЮЩИЙ указатель на узел в качестве аргумента.
  2. Вы создали новый узел (node_new)
  3. Вы устанавливаете node_new->next = node->next
  4. Вы устанавливаете node_new->prev = node
  5. Вы устанавливаете node->next = node_new
  6. IF node_new->next является NOT NULL, то вы говорите node_new->next->prev = node_new; это потому, что если node_new->next == NULL, то у него нет поля prev.

Это ОЧЕНЬ важная проверка; если вы этого не сделаете, вы можете столкнуться с ОЧЕНЬ СТРАННЫМИ ПРОБЛЕМАМИ!

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