|
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 |
©2026 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 ©2026 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.