Funkcja usuwająca n-tą pozycję z listy po wybranej (struktury)

0

Witam,

Mam za zadanie napisać funkcję, która zajmie się usuwaniem pozycji z pojedynczo połączonej listy. Prototyp wygląda tak:

int remove(struct element **p, int number, int offset);

Czyli znajduje liczbę number i usuwam pozycję o offset dalej niż ta znaleziona. Napisałem coś takiego, ale nie do końca działa. Analizowałem ten kod i wydaje się, że jest nie najgorzej... A jednak :)

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

int remove(struct element **p, int number, int offset) {

	int i = 1;
	struct element *tmp;
	
	if (!p)
		return 0;

	if ((*p)->data == number) {

		while (i<offset && *p) {
				(*p) = (*p)->next;
				i++;
			}

		tmp = (*p)->next->next;
		free((*p)->next);
		(*p)->next = tmp;

		return 1;

	}

	while ((*p)->next) {

		if ((*p)->next->data == number) {

			while (i<offset && *p) {
				(*p) = (*p)->next;
				i++;
			}

			tmp = (*p)->next->next;
			free((*p)->next);
			(*p)->next = tmp;

			return 1;

		}

		*p = (*p)->next;

	}

	return 0;

}
0

Dość późno jest, nie mam siły wczytywać się w Twój kod. Ogólnie rozwiązanie powinno wyglądać mniej więcej tak:

int remove(struct element *p, int number, int offset)
{
    if (offset < 0)
        return 1; // error
    if (p == NULL)
        return 1; // error -- pusta lista
    while (p != NULL && p->data != number)
        p = p->next;
    if (p == NULL)
        return 1; // error -- nie znaleziono elementu

    // znaleziono wlasciwy  element, przechodzimy jeszcze 'offset - 1' elementow, zeby znalezc poprzednika elementu usuwanego
    int i = 0;
    for (i = 0; p != NULL && i < offset - 1; ++i)
        p = p->next;
    if (p == NULL)
        return 1; // error -- doszlismy do konca listy zanim dotarlismy do poprzednika

    // usuwamy wlasciwy element
    struct element* tmp = p->next;
    if (tmp == NULL)
        return 1; // error -- brak elementu do usuniecia
    p->next = p->next->next;
    free(tmp);
    return 0; // success
}
0

Ogólnie rozbiłbym problem na dwie funkcje. Lepiej się czyta, analizuje, testuje i można ponownie użyć tych funkcji.

// Odnajdź wskaźnik na element, a NIE element!
struct element **findAnchorOfValue(struct element **firstAnchor, int value) {
     assert(firstAnchor);
     while(*firstAnchor) {
          if ((*firstAnchor)->data == value)
               return firstAnchor;
          firstAnchor = &((*firstAnchor)->next);
     }

     return 0;
}

struct element **findAnchorToItemNr(struct element **firstAnchor, int n) {
     assert(firstAnchor);
     assert(n>=0);
     while(*firstAnchor) {
          if (n==0)
               return firstAnchor;
          n--;
          firstAnchor = &((*firstAnchor)->next);
     }

     return 0;
}

int remove(struct element **p, int number, int offset) {
     assert(p);
     p = findAnchorOfValue(p, number);
     if (!p)
         return ErrValueNotFound;
     p = findAnchorToItemNr(p, offset);
     if (!p)
         return ErrNotEnoughtElements;
     struct element *toRemove = *p;
     *p = (*p)->next;
     free(toRemove);
     return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1