Informacje o nowych artykułach oraz akcjach edukacyjnych prosto na Twojej skrzynce e-mail!

Abstrakcyjne struktury danych: Lista

Lista wiązana jednokierunkowa

Lista wiązana jednokierunkowa to w zasadzie najprostsza lista jaką można stworzyć. Charakteryzuje się ona między innymi wbudowaną nawigacją pozwalającą na sprawne przesuwanie się element po elemencie do przodu. Jej ogólna struktura w formie graficznej wygląda tak:

lista-jednokierunkowa-wiazana

Jak widać, każdy element listy zawiera jakąś wartość oraz adres do następnego co umożliwia sprawne przesuwanie się.

Teraz już wiemy co chcemy zaprogramować więc pora zabrać się do stworzenia struktury naszej listy w Java:

class Value {

    int value;
    Value next;
}

public class Main {

    public static void main(String[] args) {

    }
}

No to tradycyjnie stworzyliśmy sobie nową klasę o nazwie Value, a w niej dwa pola jedno typu int do przechowywania danych, a drugie typu List (czyli naszej jeszcze nie utworzonej listy) do przechowywania informacji o następnym punkcie na liście.

Oczywiście nie możemy zapomnieć o inicjalizacji wszystkich pól:

class Value
{
    int value;
    Value next;

    Value(int x, Value Next)
    {
        value = x;
        next = Next;
    }
}

public class Main {

    public static void main(String[] args) {

    }
}

Powyżej stworzyliśmy obiekt odpowiadający pojedynczemu elementowi listy. Teraz musimy stworzyć drugi obiekt o nazwie List, który będzie naszą główną listą:

class Value
{
    int value;
    Value next;

    Value(int x, Value Next)
    {
        value = x;
        next = Next;
    }
}

class List
{

}

public class Main {

    public static void main(String[] args) {

    }
}

W klasie List będziemy potrzebowali mieć pole typu Value o nazwie first do szybkiego pobierania informacji o pierwszym elemencie listy – to właśnie od niego będziemy zawsze zaczynać przegląd wszystkich danych. Zmienna ta musi zostać oczywiście zainicjalizowana w konstruktorze.

class Value
{
    int value;
    Value next;

    Value(int x, Value Next)
    {
        value = x;
        next = Next;
    }
}

class List
{
    Value first;

    List()
    {
        first = null;
    }
}

public class Main {

    public static void main(String[] args) {

    }
}

Mamy już ogólną strukturę naszej listy więc teraz zabierzmy się za napisanie pozostałych metod. Do przygotowania mamy jeszcze funkcje takie jak:

  • add() – umożliwia dodanie nowego elementu do listy,
  • searchValue() – wyszukuje element na liście z wartością podaną jako argument,
  • delete() – usuwa wskazany jako argument element z listy.

Metoda add() będzie wyglądała tak:

class Value
{
    int value;
    Value next;

    Value(int x, Value Next)
    {
        value = x;
        next = Next;
    }
}

class List
{
    Value first;

    List()
    {
        first = null;
    }

    Value add(int x, Value v)
    {
        Value l;
        if(first == null)
        {
            l = new Value(x, null);
            first = l;
        }
        else
        {
            l = new Value(x, v.next);
            v.next = l;
        }

        return l;
    }
}

public class Main {

    public static void main(String[] args) {
    
    }
}

Tworzymy tutaj nowy obiekt klasy Value (czyli nową pozycję na liście) i następnie sprawdzamy czy mamy już pierwszy element jeżeli nie to właśnie obiekt, który stworzyliśmy musi się nim stać, jeżeli tak, to do pola next poprzedniego obiektu (poprzedniej pozycji na liście, podanej jako argument) przypisujemy referencję (wskaźnik) do naszego nowo utworzonego elementu na liście. Na samym końcu zwracamy nasz obiekt tak, żeby potem w mainie wiedzieć jaki jest ostatni element na liście (nie musimy tego robić, kiedy w klasie List zrobimy dodatkowe pole przechowujące tą informację).

Kolejna funkcja jaką mamy do napisania czyli searchValue() wygląda tak:

lass Value
{
    int value;
    Value next;

    Value(int x, Value Next)
    {
        value = x;
        next = Next;
    }
}

class List
{
    Value first;

    List()
    {
        first = null;
    }

    Value add(int x, Value v)
    {
        Value l;
        if(first == null)
        {
            l = new Value(x, null);
            first = l;
        }
        else
        {
            l = new Value(x, v.next);
            v.next = l;
        }

        return l;
    }
    
    int searchValue(int x)
    {
        Value f = first;

        while(f != null && f.value != x)
            f = f.next;

        return f.value;
    }
}

public class Main {

    public static void main(String[] args) {
    
    }
}

Tutaj sprawa jest dość prosta. Począwszy od pierwszego elementu (pole first) przechodzimy po całej liście do momentu znalezienia szukanej wartości lub przejścia przez całą listę. Na końcu oczywiście zwracamy znalezioną wartość.

No i na koniec pozostała nam metoda delete():

class Value
{
    int value;
    Value next;

    Value(int x, Value Next)
    {
        value = x;
        next = Next;
    }
}

class List
{
    Value first;

    List()
    {
        first = null;
    }

    Value add(int x, Value v)
    {
        Value l;
        if(first == null)
        {
            l = new Value(x, null);
            first = l;
        }
        else
        {
            l = new Value(x, v.next);
            v.next = l;
        }

        return l;
    }

    void delete(int x)
    {
        Value f = first;
        Value prev = null;

        while (f != null && f.value != x) {
            prev = f ;
            f = f.next;
        }

        if (f != null)
            if (prev == null)
                first = f.next;
            else
                prev.next = f.next;
    }

    int searchValue(int x)
    {
        Value f = first;

        while(f != null && f.value != x)
            f = f.next;

        return f.value;
    }
}

public class Main {

    public static void main(String[] args) {

    }
}

Tutaj na początku tworzymy sobie dwa pola, pierwsze przechowuje informację o początkowym elemencie listy, a drugie o poprzedzającym elemencie (na początku jest puste, bo first nie ma swojego poprzednika). Dalej szukamy naszego elementu na liście i przy okazji zapisujemy informację o elemencie poprzedzającym. Po przebrnięciu przez ten fragment musimy rozważyć dwa przypadki bowiem inaczej będzie wyglądała procedura skasowania pierwszego elementu, a inaczej kolejnych. Musimy się tutaj również zabezpieczyć przed próbą jakiś zmian na liście w wypadku kiedy nie znajdziemy elementu, którego chcemy usunąć. Jeżeli kasujemy pierwszy element to po prostu do pola first przypisujemy first.next czyli kolejny punkt na liście. Natomiast, jeżeli kasujemy jakiś inny element to po prostu do wskaźnika next elementu poprzedniego przypisujemy referencję (czyli wskazujemy na nowy obiekt) do obiektu następnego po tym, który chcemy skasować.

Nasza lista jest już gotowa, pora więc napisać maina i sprawdzić czy wszystko działa. Poniżej publikuję kod przykładowego programu:

class Value
{
    int value;
    Value next;

    Value(int x, Value Next)
    {
        value = x;
        next = Next;
    }
}

class List
{
    Value first;

    List()
    {
        first = null;
    }

    Value add(int x, Value v)
    {
        Value l;
        if(first == null)
        {
            l = new Value(x, null);
            first = l;
        }
        else
        {
            l = new Value(x, v.next);
            v.next = l;
        }

        return l;
    }

    void delete(int x)
    {
        Value f = first;
        Value prev = null;

        while (f != null && f.value != x) {
            prev = f ;
            f = f.next;
        }

        if (f != null)
            if (prev == null)
                first = f.next;
            else
                prev.next = f.next;
    }

    int searchValue(int x)
    {
        Value f = first;

        while(f != null && f.value != x)
            f = f.next;

        return f.value;
    }
}

public class Main {

    public static void main(String[] args) {

        List lista = new List(); //tworzymy listę

        Value value = null;

        for(int i = 0;i<10;i++)
        {
            value = lista.add(i,value); //dopisujemy do listy elementy od 0 do 9
        }

        Value x = lista.add(11,value); //dopisujemy element 11 na koniec listy
        lista.add(13,value); //dopisujemy element 13 po elemencie 9

        System.out.println(lista.searchValue(5)); //sprawdzamy czy element 5 jest na liście
        lista.delete(6); //usuwamy element 6

        Value f = lista.first;

        while(f != null)
        {
            System.out.print(f.value + " -> "); //wypisujemy listę
            f = f.next;
        }
    }
}

Strony: 1 2 3 4 5

Spodobało się?

Jeśli tak, to zarejestruj się do newslettera aby otrzymywać informacje nowych artykułach oraz akcjach edukacyjnych. Gwarantuję 100% satysfakcji i żadnego spamowania!

, , , , , , ,

Dodaj komentarz

Komentarze (12)

Odpowiedz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Pin It on Pinterest