Usuwanie dowolnego elementu z kolejki

0

Witam!
Muszę zaimplementować kolejkę w C (przy pomocy wskaźników). Następnie dodać do niej liczby całkowite od 1 do 8,usunąć pewną wartość i ponownie wyświetlić kolejkę.
W związku z tym mam pytanie:
Czy jeśli mam kolejkę A, która ma 8 elementów i chce usunąć czwarty element to pierwsze trzy elementy,
które zdjąłem mam dodać jeszcze raz na końcu tej samej kolejki? Czy powinienem utworzyć nową kolejkę do której dodam te wcześniej zdjęte
elementy oraz te elementy, które zdejmę ze starej kolejki po usunięciu elementu czwartego?

np.
wariant 1
kolejka A: 1,2,3,4,5,6,7,8

  1. Zdejmuje pierwsze trzy elementy i od razu dodaje na końcu
    kolejka A: 4,5,6,7,8,1,2,3
  2. Zdejmuje i usuwam element 4
    kolejka A: 5,6,7,8,1,2,3
  3. koniec

wariant 2

  1. Kolejka A: 1,2,3,4,5,6,7,8
  2. tworzę kolejkę B, zdejmuje z kolejki A elementy 1,2,3 i dodaje je do kolejki B (w takiej kolejności w jakiej je zdejmowałem)
    kolejka A: 4,5,6,7,8
    kolejka B: 1,2,3
  3. zdejmuje i usuwam element 4 z kolejki A
    kolejka A: 5,6,7,8
    kolejka B: 1,2,3
  4. zdejmuję z kolejki A pozostałe elementy i dodaje do kolejki B
    kolejka A: null
    kolejka B: 1,2,3,5,6,7,8
  5. zwracam wskaźnik do nowej kolejki

Nie mam problemów z kodem. Napiszę go sam, tylko nie wiem, który wariant wybrać (który jest poprawny).
Z góry dziękuję za odpowiedź

1

Z tego co wiem, to kolejka działa na tej zasadzie, że dodajesz na koniec a usuwasz z początku. Jesteś pewien, że musisz usuwać element ze środka? Jeśli już robić coś takiego to osobiście zdecydowałbym się na wariant 2, czyli żeby po usunięciu elementu kolejka wyglądała tak samo.

2

Wystarczy Ci jedna kolejnka, w której zrealizujesz usuwanie dowolnego elementu; Zdejmujesz i dodajesz na początek tyle żeby się dokopać do tego ustalonego, zdejmujesz ten ustalony i tyle; Jeśli zależy Ci na ponownym ułożeniu elementów kolejki tak, jak było na początku to znów zdejmujesz i dodajesz odpowiednią ilość, aż elementy poukładają się w poprzedniej kolejności;

Raczej nie ma potrzeby wykorzystywania drugiej kolejki czy innego bufora do przechowania tymczasowo zdjętych elementów, ale nic nie stoi na przeszkodzie aby zdjęte elementy gdzieś zapamiętać i po zdjęciu ustalonego elementu z powrotem dodać na początek; Łatwiej będzie od razu dodawać przy zdejmowaniu, ale czy szybciej - nie wiem;

@szweszwe - żeby przywrócić kolejce poprzednią kolejność wcale nie trzeba dodatkowej kolejki - wystarczy tylko:

  • zdjąć i od razu dodać tyle elementów, aby się dokopać do ustalonego,
  • zdjąć ustalony,
  • zdjąć i od razu dodać tyle elementów, aby przywrócić pierwotną kolejność;
    Rozwiązanie protsze, nie wiem czy szybsze, ale na pewno wygodniejsze.
0

OK, napisałem taki kod.

#ifndef _KOLEJKA_H
#define _KOLEJKA_H

template<class T>
struct element {
    T value;
    element * next;
};

// head - wskaźnik na pierwszy element
template<class T>
void dodaj( element<T> * &head, T value ) {
    element<T> * nowy = new element<T>;

    if( head == nullptr ) {
        nowy->value = value;
        nowy->next = nullptr;
        head = nowy;
    } else {
        element<T> * tmp = head;
        while( tmp->next != nullptr ) {
            tmp = tmp->next;
        }
        nowy->value = value;
        nowy->next = nullptr;
        tmp->next = nowy;
    }
}

template<class T>
void print_k( element<T> *&head ) {
    element<T> * tmp = head;

    while( tmp != nullptr ) {
        cout << tmp->value << endl;
        tmp = tmp->next;
    }
}

// nr - to numer elementu do usuniecia
template <class T>
void zdejmij( element<T> * &head, int nr ) {
    int licznik = 1;
    while( licznik-1 != nr ) {
        element<T> * doZdjecia = head;
        head = head->next;
        if( nr == licznik )
            delete doZdjecia;
        else
            dodaj( head, doZdjecia->value );

        licznik++;
    }
}


#endif // !_KOLEJKA_H

Czy jest ok? chodzi mi głównie o dodawanie nowego elementu. Czy mogę sobie tak przejść po kolejce i dodać nowy element na końcu? Czy może powinienem od razu utworzyć jakiś wskaźnik na ostatni element i za jego pomocą dodawać nowe elementy?

2

Wydaje mi się, że gdy usuwasz element np. czwarty to w trzecim musisz naprawić wskaźnik na el. piąty i usunąć czwarty - ma to tą zaletę, że jest szybsze a przy tym nie zaburzasz kolejności w kolejce. Tak jak w realnym życiu jeśli ktoś wychodzi z kolejki to pozostałe osoby przesuwają się do przodu a nie całkowicie reorganizują kolejkę.
Co do ost. pytania taki dodatkowy wskaźnik na ost. element jest bardzo dobrym pomysłem i usprawnia dodawanie elementu na koniec listy co w kolejce jest najważniejszą operacją. Modyfikacja ta kosztuje jedynie te dodatkowe 4 bajty na wskaźnik a złożoność czasowa dodawania elementu zmienia się z liniowej na stałą.

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