Ваша функция insert
может быть упрощена. По существу, у вас есть три условия для рассмотрения:
- вставки первого узла в пустой список;
- Вставка нового первого узла; и
- Вставка нового узла где-то между первым и последним.
Вставка в конец по умолчанию и не требует особого внимания. Кодирование каждого из них в отдельности, можно переписать 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.
Я предлагаю удалить теги 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
http://stackoverflow.com/a/22115254/971127 – BLUEPIXY
Этот вопрос может быть лучше подходит для http: //codereview.stackexchange .com. –