2012-04-06 3 views
3

В моем назначении мне нужно написать функцию, которая принимает в качестве аргументов указатель на структуру «LNode» и целочисленный аргумент. Затем я должен не только добавить это целое число в связанный список, но и разместить его так, чтобы список находился в правильном порядке возрастания. Я пробовал несколько различных попыток, и это мой код для публикации.Добавление и сортировка связанного списка в C

LNode* AddItem(LNode *headPtr, int newItem) 
{ 
    auto LNode *ptr = headPtr; 

    ptr = malloc(sizeof(LNode)); 

    if (headPtr == NULL) 
    { 
     ptr->value = newItem; 
     ptr->next = headPtr; 
     return ptr; 
    } 
    else 
    { 

     while (headPtr->value > newItem || ptr->next != NULL) 
     { 
      printf("While\n"); // This is simply to let me know how many times the loop runs 
      headPtr = headPtr->next; 
     } 
     ptr->value = newItem; 
     ptr->next = headPtr; 
     return ptr; 
    } 

} // end of "AddItem" 

Когда я бегу, и попытаться вставить сказать 5, а затем 3, 5 Вставляется, но затем цикл пока выполняется один раз, и я получаю ошибку сегментации.

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

Если это помогает, это то, что структура выглядит

typedef struct LNode 
{ 
    int     value; 
    struct LNode  *next; 

} LNode; 
+0

Есть ли у вас опыт работы с gdb? Было бы поучительно проходить через программу по мере ее запуска и наблюдать за тем, что делают все переменные. – gcbenison

+0

headPtr ваш головной узел и новый узел ptr? –

ответ

2

Ваше пока условие цикла не так. Вы никогда не устанавливали ptr->next, но вы используете его, чтобы проверить ptr->next!=NULL, что означает, что headPtr=headPtr->next идет в цикле. Поэтому вы должны установить: ptr->next=NULL, как только вы установите его значение.

Вы также можете взять эти строки выкладываем его на вершине:

ptr->value = newItem; 
    ptr->next = headPtr; 

Попробуйте это:

LNode* AddItem(LNode *headPtr, int newItem) 
{ 
    auto LNode *ptr, *temp, *orghead; 
    orghead = headPtr; 
    int fl=0; 
    ptr = malloc(sizeof(LNode)); 
    ptr->value = newItem; 
    ptr->next = NULL; 
    temp = ptr; 

    if (headPtr == NULL) 
     return ptr; 
    else 
     { 

     while(headPtr != NULL && headPtr->value < newItem) 
      { 
      printf("While\n"); 
      fl =1; 
      temp = headPtr; 
      headPtr = headPtr->next; 
      } 
     temp->next = ptr; 
     ptr->next = headPtr; 
     if(fl) return orghead; 
     else return temp; 
     } 

} // end of "AddItem" 
+0

Все еще делаю что-то. Я пытаюсь сделать изображение мест памяти, чтобы попытаться понять это. Функция отображения просто проходит через связанный список, поэтому я сомневаюсь, что это что-то с этим, и даже если бы я не мог изменить эту функцию в любом случае. – user1202963

0

Ваше время цикла идет до конца вашего связанного списка, и ваш последний элемент равен нулю. Таким образом, в вашем состоянии вы разыскиваете нулевой узел (headPtr), таким образом, получая ошибку сегментации. Я думаю, вам нужно проверить, является ли ваш пустой узел или не нравится:

while (headPtr != NULL && (headPtr->value > newItem || ptr->next != NULL)) 
+0

Даниэль Фишер имеет лучший ответ. :) – ervinbosenbacher

3

В вашем цикле

while (headPtr->value > newItem || ptr->next != NULL) 
    { 
    printf("While\n"); // This is simply to let me know how many times the loop runs 
    headPtr = headPtr->next; 

вы проверить, является ли неинициализированные ptr->next (не) NULL. Это неразумно и может привести к хаосу, если возможно, что бит-бит в этой части ptr не относится к указателю NULL, поскольку в этом случае у вас есть ||10, тогда условие цикла всегда истинно, и вы завершаете его список.

|| В любом случае, это не так, вам нужно &&, оба условия должны быть выполнены, что-то не NULL, и соотношение между значениями должно быть выполнено.

И, поскольку вы хотите, чтобы список в порядке возрастания, вы должны пройти список, а значение в списке - меньше, чем значение, которое должно быть вставлено.

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

if (headPtr->value >= newItem) { 
    ptr->value = newItem; 
    ptr->next = headPtr; 
    return ptr; 
} 
while(headPtr->next != NULL && headPtr->next->value < newItem) { 
    headPtr = headPtr->next; 
} 
// Now headPtr is the node behind which the new item is to be inserted 
ptr->value = newItem; 
ptr->next = headPtr->next; 
headPtr->next = ptr; 
return ?? 

Но какой указатель вы вернетесь? Если новый элемент является первым в списке, вы возвращаете указатель на первый узел. Если вы также захотите сделать это, если новый элемент будет вставлен позже, вам нужно сохранить (копию) оригинал headPtr и вернуть его.

0

настолько верно, из всего выше

while (headPtr->value > newItem || ptr->next != NULL) 
     { 
      printf("While\n"); // This is simply to let me know how many times the loop runs 
      headPtr = headPtr->next; 
     } 

Вы не проверяя нулевое условие для headPtr внутри While

в этой точке

headPtr = headPtr->next; 

headPtr-> следующая может быть нулевым, что делает ваша программа для сбоя

бит больше

LNode* AddItem(LNode *headPtr, int newItem) 
{ 

auto LNode *ptr = headPtr; ? 

    ptr = malloc(sizeof(LNode)); 

    if (headPtr == NULL) 
    { 
     ptr->value = newItem; 
     ptr->next = headPtr; 
     return ptr; 
    } 

считают headPtr не NULL, PTR теперь указывает на какой-то таНос кучу ptr-> следующая может или не может быть NULL Insuch случае

while (headPtr->value > newItem || ptr->next != NULL) 

будет не-предсказуемы

может быть вам нужно взглянуть на свою логику немного больше

см. ниже для псевдо-логики, если вы любите

LNode* add_time(LNode *headptr , data){ 

    LNode *ptr = headptr, *temp;   

    temp = malloc(sizeof(LNode)); 

    if(!temp) 
     return ptr; 

    temp->next = NULL; 
    temp->value= data; 

    if(ptr == NULL){ 
     /** There is no list**/ 
     ptr = temp; 
     return ptr; 
    } 

    /* go to last node*/ 
    while(ptr->next) 
     ptr = ptr->next; 

    ptr->next = temp; 

    return ptr; 

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