Serwis Edukacyjny w I-LO w Tarnowie Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej Autor artykułu: mgr Jerzy Wałaszek |
©2024 mgr Jerzy Wałaszek |
ProblemNależy wyszukać na liście element zawierający największą/najmniejszą wartość. |
Problem ten rozwiązujemy w sposób podobny do wyszukiwania największego/najmniejszego elementu tablicy. Zapamiętujemy adres pierwszego elementu listy. Jeśli jest to adres zerowy, to kończymy i zwracamy ten adres zerowy. W przeciwnym razie przeglądamy listę od elementu następnego do jej końca. Jeśli istnieje następny element listy, to sprawdzamy, czy jego pole data zawiera wartość większą/mniejszą od pola data elementu pod zapamiętanym adresem. Jeśli tak, to zapamiętujemy adres tego element, podmieniając adres zapamiętany poprzednio, po czym przechodzimy w pętli do jego następnika. Gdy osiągniemy koniec listy, zwracamy zapamiętany adres elementu listy.
K01: pmax ← head ; ustawiamy pmax na pierwszy element listy K02: Jeśli head = nil, ; w przypadku listy pustej, kończymy to idź do kroku K07 K03: p ← head→next ; w p umieszczamy adres następnika ; pierwszego elementu listy K04: Dopóki p ≠ nil, ; w pętli przetwarzamy elementy listy wykonuj kroki K05…K06 K05: Jeśli p→data > pmax→data, ; jeśli bieżący element to pmax ← p ; ma większą wartość, to zapamiętujemy go K06: p ← p→next ; przechodzimy do następnika K07: Zakończ z wynikiem pmax
Uwaga, jeśli mamy wyszukać element o wartości najmniejszej, to zmieniamy kierunek nierówności w kroku K05.
W poniżej znajdują się przykładowe funkcje wyznaczania wartości maksymalnej na liście. W przypadku listy dwukierunkowej odwołujemy się do pola:
Pascal |
function l_max(head : PSLel) : PSLel; var p, pmax : PSLel; begin pmax := head; if head <> nil then begin p := head^.next; while p <> nil do begin if p^.data > pmax^.data then pmax := p; p := p^.next; end; end; l_max := pmax; end; |
SLel * l_max(SLel * head) { SLel * p, * pmax; pmax = head; if(head) for(p = head->next; p; p = p->next) if(p->data > pmax->data) pmax = p; return pmax; } |
Basic |
Function l_max(head As SLel Ptr) _ As SLel Ptr Dim As SLel Ptr p, pmax pmax = head If head Then p = head->next While p If p->data > pmax->data Then _ pmax = p p = p->next Wend End If l_max = pmax End Function |
Python (dodatek) |
# klasa elementu listy # dwukierunkowej #--------------------- class DLel: def __init__(self, data): self.next = None self.prev = None self.data = data # klasa listy dwukierunkowej #--------------------------- class DLvar: # Konstruktor def __init__(self): self.head = None self.tail = None self.count = 0 # Znajduje max def l_max(self): pmax = self.head if self.head: p = self.head.next while p: if p.data > pmax.data: pmax = p p = p.next return pmax |
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
Program wykorzystuje obiekt listy dwukierunkowej, w którym dodaliśmy metodę l_max( ) oraz zmodyfikowaliśmy nieco metodę l_printl( ). Tworzona jest lista 30 przypadkowych znaków od A do z. Następnie na liście wyszukiwany jest pierwszy element zawierający znak o najwyższym kodzie ASCII. Znaleziony znak zostaje otoczony przy pomocy znaków > i <. |
Pascal// Wyszukiwanie największego elementu // Data: 18.02.2012 // (C)2020 mgr Jerzy Wałaszek //----------------------------------- program dlist_max; // Definicje typów //---------------- type PDLel = ^DLel; // wskaźnik do elementów listy // Element listy //-------------- DLel = record next : PDLel; // następnik prev : PDLel; // poprzednik data : char; end; // Definicja obiektu listy dwukierunkowej //--------------------------------------- DLvar = object public head : PDLel; // początek listy tail : PDLel; // koniec listy count : cardinal; // licznik elementów constructor init; destructor destroy; procedure l_print; procedure l_push_front(v : char); procedure l_push_back(v : char); procedure l_insert_before(e : PDLel; v : char); procedure l_insert_after(e : PDLel; v : char); procedure l_remove(e : PDLel); procedure l_pop_front; procedure l_pop_back; function l_max : PDLel; end; //--------------------------------------------- // Definicje metod obiektu listy dwukierunkowej //--------------------------------------------- // Inicjuje pola zmiennej listy //----------------------------- constructor DLvar.init; begin head := nil; tail := nil; count := 0; end; // Usuwa elementy listy //--------------------- destructor DLvar.destroy; begin while count > 0 do l_pop_front; end; // Procedura wyświetla zawartość elementów listy //---------------------------------------------- procedure DLvar.l_print; var p : PDLel; begin write(count:3, ' : '); p := head; while p <> NIL do begin write(p^.data); p := p^.next; end; writeln; end; // Procedura dodaje nowy element na początek listy //------------------------------------------------ procedure DLvar.l_push_front(v : char); var p : PDLel; begin new(p); // tworzymy nowy element p^.data := v; p^.prev := nil; p^.next := head; head := p; inc(count); if p^.next <> nil then p^.next^.prev := p else tail := p; end; // Procedura dodaje nowy element na koniec listy //---------------------------------------------- procedure DLvar.l_push_back(v : char); var p : PDLel; begin new(p); // tworzymy nowy element p^.data := v; p^.next := nil; p^.prev := tail; tail := p; inc (count); if p^.prev <> nil then p^.prev^.next := p else head := p; end; // Procedura dodaje nowy element przed wybranym //--------------------------------------------- procedure DLvar.l_insert_before(e : PDLel; v : char); var p : PDLel; begin if e = head then l_push_front(v) else begin new(p); p^.data := v; p^.next := e; p^.prev := e^.prev; inc(count); e^.prev^.next := p; e^.prev := p; end; end; // Procedura dodaje nowy element za wybranym //------------------------------------------ procedure DLvar.l_insert_after(e : PDLel; v : char); var p : PDLel; begin if e = tail then l_push_back(v) else begin new(p); p^.data := v; p^.next := e^.next; p^.prev := e; inc(count); e^.next^.prev := p; e^.next := p; end; end; // Procedura usuwa wybrany element z listy //---------------------------------------- procedure DLvar.l_remove(e : PDLel); begin dec(count); if e^.prev <> nil then e^.prev^.next := e^.next else head := e^.next; if e^.next <> nil then e^.next^.prev := e^.prev else tail := e^.prev; dispose(e); end; // Procedura usuwa element z początku listy //----------------------------------------- procedure DLvar.l_pop_front; begin if count > 0 then l_remove(head); end; // Procedura usuwa element z końca listy //-------------------------------------- procedure DLvar.l_pop_back; begin if count > 0 then l_remove(tail); end; // Wyszukuje element o największej wartości //----------------------------------------- function DLvar.l_max : PDLel; var p, pmax : PDLel; begin pmax := head; if head <> nil then begin p := head^.next; while p <> nil do begin if p^.data > pmax^.data then pmax := p; p := p^.next; end; end; l_max := pmax; end; //--------------- // Program główny //--------------- var L : DLvar; p : PDLel; i : integer; begin Randomize; L.init; for i := 1 to 30 do L.l_push_back(char(65+random(58))); L.l_print; p := L.l_max; L.l_insert_before(p, '>'); L.l_insert_after(p, '<'); L.l_print; L.destroy; end. |
// Wyszukiwanie największego elementu // Data: 18.02.2012 // (C)2020 mgr Jerzy Wałaszek //----------------------------------- #include <iostream> #include <iomanip> #include <cstdlib> #include <ctime> using namespace std; // Element listy //-------------- struct DLel { DLel * next; // następnik DLel * prev; // poprzednik char data; }; // Definicja obiektu listy dwukierunkowej //--------------------------------------- class DLvar { public: DLel * head; // początek listy DLel * tail; // koniec listy unsigned count; // licznik elementów DLvar(); // konstruktor ~DLvar(); // destruktor void l_print(); void l_push_front(char v); void l_push_back(char v); void l_insert_before(DLel * e, char v); void l_insert_after(DLel * e, char v); void l_remove(DLel * e); void l_pop_front(); void l_pop_back(); DLel * l_max(); }; //------------------------------------ // Metody obiektu listy dwukierunkowej //------------------------------------ // Inicjuje pola zmiennej listy //----------------------------- DLvar::DLvar() { head = tail = NULL; count = 0; } // Usuwa listę z pamięci //---------------------- DLvar::~DLvar() { while(count) l_pop_front(); } // Wyświetla zawartość elementów listy //------------------------------------ void DLvar::l_print() { DLel * p; cout << setw(3) << count << ": "; p = head; while(p) { cout << p->data; p = p->next; } cout << endl; } // Dodaje nowy element na początek listy //------------------------------------------------ void DLvar::l_push_front(char v) { DLel * p; p = new DLel; p->data = v; p->prev = NULL; p->next = head; head = p; count++; if(p->next) p->next->prev = p; else tail = p; } // Dodaje nowy element na koniec listy //---------------------------------------------- void DLvar::l_push_back(char v) { DLel * p; p = new DLel; p->data = v; p->next = NULL; p->prev = tail; tail = p; count++; if(p->prev) p->prev->next = p; else head = p; } // Dodaje nowy element przed wybranym //----------------------------------- void DLvar::l_insert_before(DLel * e, char v) { DLel * p; if(e == head) l_push_front(v); else { p = new DLel; p->data = v; p->next = e; p->prev = e->prev; count++; e->prev->next = p; e->prev = p; } } // Dodaje nowy element za wybranym //-------------------------------- void DLvar::l_insert_after(DLel * e, char v) { DLel * p; if(e == tail) l_push_back(v); else { p = new DLel; p->data = v; p->next = e->next; p->prev = e; count++; e->next->prev = p; e->next = p; } } // Usuwa wybrany element z listy //------------------------------ void DLvar::l_remove(DLel * e) { count--; if(e->prev) e->prev->next = e->next; else head = e->next; if(e->next) e->next->prev = e->prev; else tail = e->prev; delete e; } // Usuwa element z początku listy //------------------------------- void DLvar::l_pop_front() { if(count) l_remove(head); } // Usuwa element z końca listy //---------------------------- void DLvar::l_pop_back() { if(count) l_remove(tail); } // Wyszukuje element o największej wartości //----------------------------------------- DLel * DLvar::l_max() { DLel * p, * pmax; pmax = head; if(head) for(p = head->next; p; p = p->next) if(p->data > pmax->data) pmax = p; return pmax; } //--------------- // Program główny //--------------- int main() { DLvar L; DLel * p; int i; srand(time(NULL)); for(i = 0; i < 30; i++) L.l_push_back(65+rand()%58); L.l_print(); p = L.l_max(); L.l_insert_before(p, '>'); L.l_insert_after(p, '<'); L.l_print(); return 0; } |
Basic' Wyszukiwanie największego elementu ' Data: 18.02.2012 ' (C)2020 mgr Jerzy Wałaszek '----------------------------------- ' Element listy '-------------- Type DLel next As DLel Ptr ' następnik prev As DLel Ptr ' poprzednik data As String * 1 End Type ' Typ obiektowy listy dwukierunkowej '----------------------------------- Type DLvar head As DLel Ptr ' początek listy tail As DLel Ptr ' koniec listy count As UInteger ' licznik elementów Declare Constructor() Declare Destructor() Declare Sub l_print() Declare Sub l_push_front(v As String) Declare Sub l_push_back(v As String) Declare Sub l_insert_before(e As DLel Ptr, _ v As String) Declare Sub l_insert_after(e As DLel Ptr, _ v As String) Declare Sub l_remove(e As DLel Ptr) Declare Sub l_pop_front() Declare Sub l_pop_back() Declare Function l_max() As DLel Ptr End Type '--------------- ' Program główny '--------------- Dim L As DLvar Dim p As DLel Ptr Dim i As Integer Randomize For i = 1 To 30 L.l_push_back(Chr(65+Int(Rnd()*58))) Next L.l_print() p = L.l_max() L.l_insert_before(p, ">") L.l_insert_after(p, "<") L.l_print() End ' Konstruktor listy '------------------ Constructor DLvar() head = 0 tail = 0 count = 0 End Constructor ' Usuwa listę z pamięci Destructor DLvar() While count > 0 l_pop_front() Wend End Destructor ' Procedura wyświetla zawartość elementów listy '---------------------------------------------- Sub DLvar.l_print() Dim p As DLel Ptr Print Using "### : ";count; p = head while p Print p->Data; p = p->next Wend Print End Sub ' Procedura dodaje nowy element na początek listy '------------------------------------------------ Sub DLvar.l_push_front(v As String) Dim p As DLel Ptr p = New DLel p->data = v p->prev = 0 p->next = head head = p count += 1 If p->next Then p->next->prev = p Else tail = p End If End Sub ' Procedura dodaje nowy element na koniec listy '---------------------------------------------- Sub DLvar.l_push_back(v As String) Dim p As DLel Ptr p = New DLel p->data = v p->next = 0 p->prev = tail tail = p count += 1 If p->prev Then p->prev->next = p Else head = p End If End Sub ' Procedura dodaje nowy element przed wybranym '--------------------------------------------- Sub DLvar.l_insert_before(e As DLel Ptr, _ v As String) Dim p As DLel Ptr If e = head Then l_push_front(v) Else p = New DLel p->data = v p->next = e p->prev = e->prev count += 1 e->prev->next = p e->prev = p End If End Sub ' Procedura dodaje nowy element za wybranym '------------------------------------------ Sub DLvar.l_insert_after(e As DLel Ptr, _ v As String) Dim p As DLel Ptr If e = tail Then l_push_back(v) Else p = New DLel p->data = v p->next = e->next p->prev = e count += 1 e->next->prev = p e->next = p End If End Sub ' Procedura usuwa wybrany element z listy '---------------------------------------- Sub DLvar.l_remove(e As DLel Ptr) count -= 1 If e->prev Then e->prev->next = e->next Else head = e->next End If If e->next Then e->next->prev = e->prev Else tail = e->prev End If Delete e End Sub ' Procedura usuwa element z początku listy '----------------------------------------- Sub DLvar.l_pop_front() If count > 0 Then _ l_remove(head) End Sub ' Procedura usuwa element z końca listy '-------------------------------------- Sub DLvar.l_pop_back() If count > 0 Then _ l_remove(tail) End Sub ' Wyszukuje element o największej wartości '----------------------------------------- Function DLvar.l_max() As DLel Ptr Dim As DLel Ptr p, pmax pmax = head If head Then p = head->next While p If p->data > pmax->data Then _ pmax = p p = p->next Wend End If l_max = pmax End Function |
Python (dodatek) |
# Wyszukiwanie największego elementu # Data: 15.05.2024 # (C)2024 mgr Jerzy Wałaszek #----------------------------------- import random # klasa elementu listy #--------------------- class DLel: def __init__(self, data): self.next = None self.prev = None self.data = data # klasa listy dwukierunkowej #--------------------------- class DLvar: # Konstruktor def __init__(self): self.head = None self.tail = None self.count = 0 # Destruktor def __del__(self): while self.count: self.l_pop_front() # Wyświetla zawartość listy def l_print(self): print("%3d: "% self.count, end="") p = self.head while p: print(p.data, end="") p = p.next print() # Dodaje nowy element na początek def l_push_front(self, v): p = DLel(v) p.next = self.head self.head = p self.count += 1 if p.next: p.next.prev = p else: self.tail = p # Dodaje nowy element na koniec def l_push_back(self, v): p = DLel(v) p.prev = self.tail self.tail = p self.count += 1 if p.prev: p.prev.next = p else: self.head = p # Dodaje nowy element przed def l_insert_before(self, e, v): if e is self.head: self.l_push_front(v) else: p = DLel(v) p.next = e p.prev = e.prev self.count += 1 e.prev.next = p e.prev = p # Dodaje nowy element za def l_insert_after(self, e, v): if e is self.tail: self.l_push_back(v) else: p = DLel(v) p.next = e.next p.prev = e self.count += 1 e.next.prev = p e.next = p # Usuwa wybrany element def l_remove(self, e): self.count -= 1 if e.prev: e.prev.next = e.next else: self.head = e.next if e.next: e.next.prev = e.prev else: self.tail = e.prev # Usuwa element z początku def l_pop_front(self): if self.count: self.l_remove(self.head) # Usuwa element z końca def l_pop_back(self): if self.count: self.l_remove(self.tail) # Wyszukuje element o największej wartości def l_max(self): pmax = self.head if self.head: p = self.head.next while p: if p.data > pmax.data: pmax = p p = p.next return pmax #--------------- # Program główny #--------------- dl = DLvar() for i in range(30): dl.l_push_back(chr(random.randrange(65, 123))) dl.l_print() p = dl.l_max() dl.l_insert_before(p, '>') dl.l_insert_after(p, '<') dl.l_print() |
Wynik: |
30 : zAUOF^iXCxfzK^uLS`rmW\nENJXykt 32 : >z<AUOF^iXCxfzK^uLS`rmW\nENJXykt |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2024 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.