2016-06-06 2 views
1

поэтому я написал этот незавершенный, но рабочий код. я очень новичок в программировании, и я думаю, что моя логика неверна (хотя код работает должным образом), потому что слишком много «ifs и elses», я не могу думать о другой рабочей логике для вставки данных в любую позицию связанного списка и вывода данные + обработка, если позиция недействительные им пытаются разработать вычислительное мышление и что-то ошибка говорит мне, этот код может быть написал намного лучшеИщете другую логику

#include <stdio.h> 
#include <stdlib.h> 

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

struct node* head = NULL; 


void Insert(int c ,int e) 
{ 
    int i; 
    static int p = 1; 
    struct node* temp = malloc(sizeof(struct node)); 
    temp -> data = c; 
    temp -> next = NULL; 
    struct node* temp1 = head; 

    if (e > p+1) 
    { 
     printf("Invalid Position"); 
     return; 
    } 

    else if (head == NULL) 
     { 
     head = temp; 
     return; 
     } 

    else if (e <= 1) 
    { 
     temp -> next = head; 
     head = temp; 
     return; 
    } 

    else if (e == 2) 
    { 
     if (temp1 -> next != NULL) 
     { 
      temp -> next = temp1 -> next; 
      temp1 -> next = temp; 

     } 

     else 
     { 
      temp1 -> next = temp; 

     } 

    } 

    else 
    { 
     for (i = 0;i<e-2;i++) 
     { 
      temp1 = temp1 -> next; 
     } 

    temp -> next = temp1 -> next; 
    temp1 -> next = temp; 
    } 
p++; 
} 

void print() { 

    struct node* temp = head; 
    printf("list is: \n"); 
    while (temp != NULL) { 

     printf("%d ,",temp->data); 
     temp = temp->next; 
    } 
} 


int main() { 

printf("How Many Numbers?\n"); 
int a ,b ,c, e; 
scanf("%d" , &b); 
for(a = 0;a<b;a++) { 
    printf("Enter the numbers \n"); 
    scanf("%d",&c); 
    printf("Enter position \n"); 
    scanf("%d",&e); 
    Insert(c , e); 
    print(); 
} 
return 0; 
} 
+1

Я предлагаю удалить теги ubuntu и codeblocks, поскольку вопрос не связан ни с чем из этого. Кроме того, «Введите числа» (множественное число) вводит в заблуждение, так как вы хотите ввести 1 номер.Далее, нет наказания, если вы хорошо назовете ваши переменные. '' void insert (int value, int position) '' выглядит немного лучше, не так ли? '' static int p = 1; '' является плохой практикой. И рано или поздно вам понадобится функция '' int length (const struct node * list) '', и тогда ваш p ​​будет болезненным. Пропуск вперед: e - переменная потока управления. Меньше ifs: сделать несколько функций для каждого случая: '' insert_front() '', ... – BitTickler

+1

http://stackoverflow.com/a/22115254/971127 – BLUEPIXY

+1

Этот вопрос может быть лучше подходит для http: //codereview.stackexchange .com. –

ответ

0

Ваша функция insert может быть упрощена. По существу, у вас есть три условия для рассмотрения:

  1. вставки первого узла в пустой список;
  2. Вставка нового первого узла; и
  3. Вставка нового узла где-то между первым и последним.

Вставка в конец по умолчанию и не требует особого внимания. Кодирование каждого из них в отдельности, можно переписать insert следующим образом:

void insert (int c, int e) 
{ 
    struct node *temp = malloc (sizeof *temp); 
    if (!temp) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     exit (EXIT_FAILURE); 
    } 

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

    if (!head) { head = temp; goto check; } /* empty list */ 

    struct node *iter = head; 

    if (!e) { temp->next = head; head = temp; return; } /* new 1st node */ 
    for (--e; e && iter->next; iter = iter->next, e--) {} /* iterate */ 

    /* inserting before end, update temp->next */ 
    if (iter->next) temp->next = iter->next; 
    iter->next = temp;  /* add node as next */ 

    check:; 
    if (e) 
     fprintf (stderr, "warning, 'e' beyond list, inserted at end.\n"); 
} 

Примечание:insert используется вместо Insert. C избегает Caps и caMelCase для имен переменных и функций в пользу всех нижний регистр. См. NASA - C Style Guide, 1994

Если вы выделяете память для списка, вы должны отслеживать выделенную память, чтобы ее можно было освободить, когда она больше не нужна. Начните хорошие привычки рано, не просто полагайтесь на выход, делая это за вас. Вы уже писали print(), delete() практически то же самое:

void delete() 
{ 
    struct node *tmp = head; 
    while (tmp != NULL) { 
     struct node *victim = tmp; 
     tmp = tmp->next; 
     free (victim); 
    } 
} 

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

#include <stdio.h> 
#include <stdlib.h> 

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

struct node *head = NULL; 

void insert (int c, int e); 
void print(); 
void delete(); 

int main (void) { 

    int a, b, c, e, rtn; 
    a = b = c = e = rtn = 0; 

    printf ("\nDefine list, values and positons (zero based positions)\n\n"); 
    do { 
     printf (" numer of list elements?: "); 
     if ((rtn = scanf ("%d", &b)) != 1 || b < 1) 
      fprintf (stderr, "error: invalid input.\n"); 
     if (rtn == EOF) exit (EXIT_FAILURE); 
    } while (b < 1); 

    for (a = 0; a < b; a++) { 
     do printf ("\n number %2d: ", a + 1); 
     while ((rtn = scanf ("%d", &c)) != 1 && rtn != EOF); 
     if (rtn == EOF) exit (EXIT_FAILURE); 

     do printf (" position : "); 
     while ((rtn = scanf ("%d", &e)) != 1 && e >= 0 && rtn != EOF); 
     if (rtn == EOF) exit (EXIT_FAILURE); 

     insert (c, e); 
     print(); 
    } 
    delete(); 
    return 0; 
} 

void insert (int c, int e) 
{ 
    struct node *temp = malloc (sizeof *temp); 
    if (!temp) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     exit (EXIT_FAILURE); 
    } 

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

    if (!head) { head = temp; goto check; } /* empty list */ 

    struct node *iter = head; 

    if (!e) { temp->next = head; head = temp; return; } /* new 1st node */ 
    for (--e; e && iter->next; iter = iter->next, e--) {} /* iterate */ 

    /* inserting before end, update temp->next */ 
    if (iter->next) temp->next = iter->next; 
    iter->next = temp;  /* add node as next */ 

    check:; 
    if (e) 
     fprintf (stderr, "warning, 'e' beyond list, inserted at end.\n"); 
} 

void print() 
{ 
    struct node *temp = head; 
    printf (" current list is: "); 
    while (temp != NULL) { 
     printf (" %d", temp->data); 
     temp = temp->next; 
    } 
    putchar ('\n'); 
} 

void delete() 
{ 
    struct node *tmp = head; 
    while (tmp != NULL) { 
     struct node *victim = tmp; 
     tmp = tmp->next; 
     free (victim); 
    } 
} 

Пример использования/вывода

$ ./bin/llins 

Define list, values and positons (zero based positions) 

numer of list elements?: 5 

    number 1: 6 
    position : 0 
current list is: 6 

    number 2: 7 
    position : 3 
warning, 'e' beyond list, inserted at end. 
current list is: 6 7 

    number 3: 8 
    position : 0 
current list is: 8 6 7 

    number 4: 9 
    position : 2 
current list is: 8 6 9 7 

    number 5: 10 
    position : 3 
current list is: 8 6 9 10 7 

Посмотрите его и дайте мне знать, если у вас есть какие-либо Que stions.

+0

благодарю вас за размахивание этой логики Это мне очень помогает. im также пытается обработать случай, когда пользовательский ввод является символом вместо целого. – jaindoe

0

Да, вы можете уменьшить глубину на один уровень за счет сочетания двух условий к одному:

if (e > p + 1) { 
     printf("Invalid Position"); 
     return; 
    } 
    else if (head == NULL) { 
     head = temp; 
     return; 
    } 
    else if (e <= 1) { 
     temp->next = head; 
     head = temp; 
     return; 
    } 
    else if (e == 2 && temp1->next != NULL) { 
     temp->next = temp1->next; 
     temp1->next = temp; 

    } 
    else if (temp1->next == NULL) { 
     temp1->next = temp; 

    } 
    else { 
     for (i = 0; i < e - 2; i++) { 
      temp1 = temp1->next; 
     } 
     temp->next = temp1->next; 
     temp1->next = temp; 
    } 
+0

Я имею в виду, что вся эта логика может быть написана по-разному. Я не говорил о функциях в этом коде, например: https://www.youtube.com/watch?v=V42FBiohc6c&list=PL2_aWCzGMAwI9HK8YPVBjElbLbI3ufctn – jaindoe

0

наверняка, если и еще не хороший дизайн рисунка, но вы должны использовать i t в C. Вы можете изменить свой дизайн, когда используете язык ООП (объектно-ориентированное программирование).

В C вы должны иметь модульный код, поэтому просто делайте небольшие части кода с функциями, где бы вы ни находились.

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