Удаление элемента связанного списка - C (СИ)
Формулировка задачи:
Здравствуйте, у меня есть программа и нужно удалить элемент из связанного списка по порядковому номеру под которым он выводится при отображении элементов списка на экран:
Удаление заданного элемента пытался реализовать в case 7 , однако ничего не удаляется. Элементы списка отображаются при вызове case 2. Может кто-нибудь подскажет как правильно сделать?
#include "stdio.h"
#include "ctype.h"
#include "stdlib.h"
#include "math.h"
#include "string.h"
#define SIZE 100
double dummy = sin(0.0);
struct sputnik {
char nazvanie[30];
char nazvanie_main[30];
int year;
float d;
int period;
struct sputnik *next;
};
int main(void){
char choice;
int punkt;
int i, count=0;
struct sputnik *head=NULL;
struct sputnik *prev,*current;
int res,kolvo,j,number;
struct sputnik a[SIZE];
system("clear");
while(1){
printf("Viberite punkt menu: ");
printf ("1-Vvod \n 2-Vivod \n 3-Zapis v fail \n 4-Chnenie iz faila \n 5-Dobavit sputnik \n 6-Izmenit polia sputnika \n 7-Udalenie zapici \n 8-Vihod \n");
scanf("%d",&punkt);
while(getchar()!='\n') continue;
switch(punkt){
case 1:
while(1){
printf("Sozdat novuu tablicy ili dopisat v staruu (N-new;O-old)");
choice=toupper(getchar());
if (choice=='N'){
count=0;
prev=head;
while(prev != NULL){
current=prev->next;
free(prev);
prev=current;
}
head=NULL;
}
if (choice!='N'&& choice !='O'){
while(getchar()!='\n') continue;
continue;
}
while(getchar()!='\n') continue;
break;
}
for ( ; ;count++){
current = (struct sputnik *)malloc(sizeof(struct sputnik));
if (head==NULL) head=current;
else prev->next=current;
current->next = NULL;
printf("Vvedite nazvanie %d sputnika :", count+1);
gets(current->nazvanie);
printf ("Vvedite nazvanie planeti :");
gets(current->nazvanie_main);
printf ("Vvedite god otkritia :");
scanf("%d",¤t->year);
while(getchar()!='\n') continue;
printf("Vvedite diametr :");
scanf("%f",¤t->d);
while(getchar()!='\n') continue;
printf("Period obrachenia :");
scanf("%d",¤t->period);
while(getchar()!='\n') continue;
prev=current;
printf("Zakonchit vvod?:y/n: \n");
if (toupper(getchar()) =='Y'){
count++;
break;
}
else {
while(getchar()!='\n') continue;
continue;
};
}
break;
case 2:
if (head==NULL) printf ("Dannie ne vvedensi \n");
else printf("Spisok sputnikov: \n");
current=head;
i=0;
while(current!=NULL) {
printf("%d sputnik - %s planeta %s god %d diametr %4.3f period %d\n",++i, current->nazvanie,current->nazvanie_main, current->year,current->d,current->period);
current=current->next;
}
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
int nummer;
printf(" Vvedite nomer zapisi kotoryu nuzno udalit :\n");
scanf ("%d",&nummer);
while(getchar()!='\n') continue;
current=head;
i=0;
while(current!=NULL) {
if (i==nummer-1){
prev=current;
free(current);
current = prev->next;
}
else
{current=current->next;
i=i+1;}
}
break;
case 8:
prev=head;
while(prev!=NULL){
current=prev->next;
free(prev);
prev=current;
}
printf("Programma zavershila rabitu \n");
return 0;
break;
default:
printf ("Punkt vibran ne verno! \n");
break;
}
}
return 0;
}Решение задачи: «Удаление элемента связанного списка»
textual
Листинг программы
list *Remove(list *&pp, int n)
{
list *q; // Указатель на текущий элемент
for (q = pp; q!=NULL && n!=0; q = q->next, n--); // Отсчитать n -ый
if (q==NULL) return NULL; // нет элемента с таким номером
if (q->prev==NULL) // удаление первого -
pp=q->next; // коррекция заголовка
else q->prev->next = q->next; // следующий для предыдущего =
// следующий за текущим
if (q->next!=NULL) // удаление не последнего -
q->next->prev = q->prev; // предыдущий для следующего =
return q;
} // предыдущий текущего
Объяснение кода листинга программы
- Указатель
qинициализируется значениемpp(указатель на начало списка). - В цикле
forперебираются элементы списка до тех пор, пока не будет достигнуто условиеq == NULLилиn != 0. - Если встретился элемент с
n- ным индексом, то вqсохраняется указатель на этот элемент. - Если встреченного элемента нет, то возвращается
NULL. - Если встреченный элемент является первым в списке, то его удаляют, а указатель
ppкорректируют так, чтобы он указывал на следующий элемент. - Если встреченный элемент не является последним, то его
nextссылается наprevэтого элемента, тем самым удаляя его из списка. - Если встреченный элемент является последним, то его
nextприсваивается значениеNULL. - Возвращается указатель на удаленный элемент.