Бесконечный цикл при вставке в связанный список

При вставке узла в конец связанного списка мой код работает в бесконечном цикле.
Используется IDE-Eclipse 64-разрядная ОС

 #include<stdio.h>
 #include<stdlib.h>
 typedef struct Node
   {
     int info;
     struct Node *next;

   }node;
   node *head;
   node *ptr1;
   void insert(int x);
   void show();
   int main()
   {
     int i,x,n;
     puts("Enter number of elements\n");
     scanf("%d",&n);
     for(i=0;i<n;i++)
       {
       puts("Enter elements");
       scanf("%d",&x);
       insert(x);

       }
    show();
    return 0;
     }

//Чтобы вставить данные в связанный список

    void insert(int x)
    {
      node *ptr;
      ptr1=head;
      ptr=(node*)malloc(sizeof(node));
      ptr->info=x;
      if(head==NULL)
        {
         ptr->next=head;
         head=ptr;
        }
      else
        {
        ptr1->next=NULL;
        ptr1=ptr;
        }
       }

//Чтобы распечатать детали списка //Невозможно понять эту функцию

    void show()
    {
    while(ptr1->next!=NULL)
      {
      printf("%d\n",ptr1->info);
      ptr1=ptr1->next;
      }



}

person Dumb    schedule 17.02.2015    source источник
comment
Стандартное предупреждение. Пожалуйста, не выполняйте преобразование возвращаемого значения malloc() и семейства.   -  person Sourav Ghosh    schedule 17.02.2015
comment
Похоже, что для head-›next задано значение head... что приводит к бесконечному циклу в вашей функции show   -  person javajavajava    schedule 17.02.2015
comment
Можете ли вы опубликовать свой вклад?   -  person Karthikeyan.R.S    schedule 17.02.2015
comment
Это бесконечный цикл, печатающий некоторые адреса   -  person Dumb    schedule 18.02.2015


Ответы (2)


Ptr1 устанавливается в заголовок каждый раз, когда ваш код входит в функцию вставки, а затем устанавливает его в ptr в подразделе else, но ничего не указывает на какие-либо предыдущие элементы. Вот пример, если он вам нужен.

typedef struct Node
{
 int info;
 struct Node *next;
}node;

node *head = NULL;
void insert(int x);
void show();
int main()
{
 int i,x,n;
 puts("Enter number of elements\n");
 scanf("%d",&n);
 for(i=0;i<n;i++)
   {
   puts("Enter elements");
   scanf("%d",&x);
   insert(x);

   }
   show();
   return 0;
 }

void insert(int x)
{
  node *ptr = (node*)malloc(sizeof(node));
  ptr->info=x;
  ptr->next=head; /* this will always add the new entry at the beginning of the list all you need it to initialize the head to NULL*/ 
  head = ptr; /* move the head so that it points to the newly created list element */
} 

void show()
{
    node *ptr1 = head;
    printf("%d\n",ptr1->info); /* print the head */
    while(ptr1->next!=NULL) /* now walk the list remember it first looks if the next pointer in the list is null first then it jumps on next element in case it is not*/
    {
        ptr1=ptr1->next;
        printf("%d\n",ptr1->info);
    }
}

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

person weaz    schedule 17.02.2015
comment
Этот код не вставляет узел в конец, а вставляет его вперед. - person Dumb; 18.02.2015
comment
Как написано в комментариях :). Все зависит от вас, чтобы сортировать элементы и даже больше в качестве упражнений. - person weaz; 21.02.2015

Ваши две функции могут быть упрощены. Односвязный список очень легко реализовать. Я бы также улучшил функции, приняв указатель списка в качестве аргумента, а в случае insert() вернул бы новый заголовок списка: но сначала заставьте его работать! Обратите внимание, что нет причин или необходимости объявлять глобальные переменные, если они используются только локально для функции.

// insert new node at head of the list
void insert(int x) {
    node *ptr = malloc(sizeof(node));
    if (ptr == NULL) {
        printf ("malloc failure\n");
        exit (1);
    }
    ptr->info = x;
    ptr->next = head;           // append existing list
    head = ptr;                 // new head of list
    }

// show the linked list
void show() {
    node *ptr = head;           // start at head of list
    while (ptr != NULL) {
        printf("%d\n", ptr->info);
        ptr = ptr->next;        // follow the link chain
    }
}

ИЗМЕНИТЬ вот код для добавления в конец связанного списка

// insert new node at tail of the list
void insert2(int x) {
    node *tail = head;
    node **last = &head;
    node *ptr;
    while (tail) {
        last = &tail->next;
        tail = tail->next;
        }
    ptr = malloc(sizeof(node));
    if (ptr == NULL) {
        printf ("malloc failure\n");
        exit (1);
    }
    ptr->info = x;
    ptr->next = NULL;
    *last = ptr;
}
person Weather Vane    schedule 17.02.2015
comment
Это не вставка узла в конец, а вставка его вперед. - person Dumb; 18.02.2015
comment
Вот как вы используете связанный список. Это стек LIFO. - person Weather Vane; 18.02.2015
comment
Нет, но я пытаюсь распечатать узлы в связанном списке в порядке FIFO и не могу понять, как это сделать? - person Dumb; 18.02.2015
comment
Я добавил еще одну функцию, вы можете видеть, что она сильно усложняет жизнь, работая с хвостом списка. Другим способом было бы создать список, добавив его в заголовок, а затем создать из него другой список, который изменит последовательность. - person Weather Vane; 18.02.2015