|
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
|
| SPIS TREŚCI |
| Tematy pomocnicze |
| Podrozdziały |
Słownik można utworzyć przy pomocy list. Zaletą list w stosunku do tablic jest to, iż listy posiadają z natury dynamiczną naturę. Czas wstawiania nowego elementu jest klasy O(n). Listy nie muszą, jak tablice, zajmować spójnego bloku pamięci dlatego listy lepiej wykorzystują dostępną pamięć. Przykładowy słownik zrealizujemy przy pomocy listy jednokierunkowej o następującej strukturze

Każdy element listy będzie zawierał trzy pola:
next : wskazuje następny element listy. Ostatni element zawiera
tu wskazanie puste.
klucz : unikalny klucz, z którym powiązane jest następne pole
wartości. Klucz
jest daną prostego typu: liczba, tekst...
wartość : powiązana z kluczem.
Wartość jest daną dowolnego typu i może się
powtarzać w słowniku.
Program będzie pamiętał adres pierwszego elementu listy w zmiennej td. Jeśli adres ten jest pusty (nil), to lista nie zawiera żadnego elementu i słownik jest pusty.
Definicje elementu listy słownika są następujące:
Pascaltype
PDict = ^TDict;
TDict = record
next : PDict;
key : typ_klucza;
value : typ_wartości;
end;
...
var
td : PDict;
|
struct TDict
{
TDict * next;
typ_klucza key;
typ_wartości value;
};
...
TDict * td;
|
BasicType TDict next As TDict Ptr key As typ_klucza value As typ_wartości End Type ... Dim td As TDict Ptr |
Python
(dodatek)class TDict
def __init__(self, k, d):
self.next = None
self.key = k
self.value = v
...
td = None # Wskazanie początku
# listy ze słownikiem
|
K01: Jeśli td = nil, ; Lista pusta? to zakończ K02: Jeśli td→key <> k, ; Pierwszy węzeł? to idź do kroku K07 K03: r ← td→next ; Zapamiętujemy następny węzeł K04: Usuń td ; Usuwamy węzeł początkowy K05: td ← r ; Jako pierwszy będzie węzeł następny K06: Zakończ K07: p ← td ; Przeszukujemy listę K08: Dopóki p→next <> nil i p→next→key <> k, K09: wykonuj p ← p→next K10: Jeśli p→next = nil, ; Jeśli klucza brak to zakończ K11: r ← p→next→next ; zapamiętujemy element następny K12: Usuń p→next ; usuwamy węzeł z kluczem K13: p→next ← r K14: Zakończ
K01: d_del(td, k) ; usuwamy starą parę o kluczu k K02: Utwórz nowy węzeł p K03: p→next ← td ; węzeł wstawiamy na początek listy K04: p→key ← k K05: p→value ← v K06: td ← p K06: Zakończ
K01: p ← td ; przeglądamy listę K02: Dopóki p ≠ nil i p→key ≠ k, wykonuj p ← p→next K03: Jeśli p ≠ nil, to zakończ z wynikiem p→value K04: Zakończ z wynikiem wartość specjalna
K01: c ← 0 ; zerujemy licznik kluczy K02: p ← td; rozpoczynamy od początku listy K03: Dopóki p ≠ nil, wykonuj kroki K04...K05 K04: c ← c + 1 K05: p ← p→next K06: Zakończ z wynikiem c
|
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 tworzy słownik w liście. Klucze są tekstami imion męskich. Wartości są liczbami rzeczywistymi z zakresu od 0 do 10. Do słownika zostaje wprowadzone 7 elementów w przypadkowej kolejności. Następnie do słownika zostaje wprowadzone 5 dalszych elementów, które mogą już występować w słowniku. Usuwamy ze słownika 5 kluczy, których może nie być w słowniku. Na koniec szukamy 10 przypadkowych kluczy i jeśli są, wypisujemy związane z nimi wartości, klucze mogą się powtarzać. |
Pascal// Program testowy dla słownika na liście
// Data: 4.11.2024
// (C)2024 mgr Jerzy Wałaszek
//---------------------------------------
program dlist_test;
// Typ elementów listy
//--------------------
type
PDict = ^TDict;
TDict = record
next : PDict;
key : String;
value : double;
end;
const
// Wartość specjalna
SV = -1000000.0;
// Usuwa klucz ze słownika
//------------------------
procedure d_del(var td : PDict; k : string);
var
p, r : PDict;
begin
if td = nil then Exit;
if td^.key = k then
begin
r := td^.next;
dispose(td);
td := r;
Exit;
end;
p := td;
while (p^.next <> nil) and
(p^.next^.key <> k) do
p := p^.next;
if p^.next = nil then Exit;
r := p^.next^.next;
dispose(p^.next);
p^.next := r;
end;
// Umieszcza w słowniku parę (k,v)
//--------------------------------
procedure d_put(var td : PDict;
k : String;
v : double);
var
p : PDict;
begin
d_del(td, k);
new(p);
p^.next := td;
p^.key := k;
p^.value := v;
td := p
end;
// Zwraca wartość v skojarzoną z kluczem k
// lub wartość specjalną SV, jeśli słownik
// nie zawiera klucza k.
function d_get(td : PDict; k : string)
: double;
var
p : PDict;
begin
p := td;
while (p <> nil) and (p^.key <> k) do
p := p^.next;
if p <> nil then Exit(p^.value);
Exit(SV);
end;
// Funkcja oblicza liczbę kluczy w słowniku
//-----------------------------------------
function d_size(td : PDict) : cardinal;
var
p : PDict;
c : cardinal;
begin
c := 0; // zerujemy licznik
p := td;
while p <> nil do
begin
inc(c); // zwiększamy licznik o 1
p := p^.next;
end;
Exit(c);
end;
// Procedura wyświetla zawartość słownika
//---------------------------------------
procedure d_print(td : PDict);
var
i : cardinal;
p : PDict;
begin
writeln('Liczba kluczy : ', d_size(td));
p := td;
i := 1;
while p <> nil do
begin
writeln('Para #', i,
' k = ', p^.key,
' v = ', p^.value:5:2);
inc(i);
p := p^.next;
end;
writeln;
end;
//---------------
// Program główny
//---------------
var
// Klucze
names : array[0..9] of string =
('Janusz', 'Marian',
'Henryk', 'Adrian',
'Bogdan', 'Cyprian',
'Dariusz','Zenon',
'Tadeusz','Karol');
i,x : integer;
v : real;
td : PDict; // Słownik
begin
randomize();
td := nil;
// W słowniku umieszamy 7 danych
writeln('TWORZENIE');
for i := 1 to 7 do
begin
x := random(10);
v := random * 10;
d_put(td,names[x],v);
writeln('(',names[x],',',
v:5:2,')');
end;
d_print(td);
// Dodajemy 5 elementów
writeln('DODAWANIE');
for i := 1 to 5 do
begin
x := random(10);
v := random * 10;
d_put(td,names[x],v);
writeln('(',names[x],',',
v:5:2,')');
end;
d_print(td);
// Usuwamy 5 kluczy
writeln('USUWANIE');
for i := 1 to 5 do
begin
x := random(10);
d_del(td,names[x]);
writeln('(',names[x],',*)');
end;
d_print(td);
// Szukamy 10 kluczy
writeln('WYSZUKIWANIE');
for i := 1 to 10 do
begin
x := random(10);
v := d_get(td,names[x]);
if v <> SV then
begin
writeln('klucz ',
names[x],
' obecny, v = ',
v:5:2)
end
else
begin
writeln('klucza ',
names[x],' brak');
end;
end;
// Usuwamy słownik z pamięci
while td <> nil do
d_del(td,td^.key);
end.
|
C++// Program testowy dla słownika na liście
// Data: 6.11.2024
// (C)2024 mgr Jerzy Wałaszek
//---------------------------------------
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
// Typ elementów listy
//--------------------
struct TDict
{
TDict * next;
string key;
double value;
};
// Wartość specjalna
const double SV = -1000000.0;
// Usuwa klucz ze słownika
//------------------------
void d_del(TDict * & td, string k)
{
TDict * p, * r;
if(!td) return;
if(td->key == k)
{
r = td->next;
delete td;
td = r;
return;
}
p = td;
while(p->next && p->next->key != k)
p = p->next;
if(!p->next) return;
r = p->next->next;
delete p->next;
p->next = r;
return;
}
// Umieszcza w słowniku parę (k,v)
//--------------------------------
void d_put(TDict * & td,
string k,
double v)
{
TDict * p;
d_del(td, k);
p = new(TDict);
p->next = td;
p->key = k;
p->value = v;
td = p;
}
// Zwraca wartość v skojarzoną z kluczem k
// lub wartość specjalną SV, jeśli słownik
// nie zawiera klucza k.
double d_get(TDict * td, string k)
{
TDict * p;
p = td;
while(p && p->key != k)
p = p->next;
if(p) return p->value;
return SV;
}
// Funkcja oblicza liczbę kluczy w słowniku
//-----------------------------------------
int d_size(TDict * td)
{
TDict * p;
int c;
c = 0; // zerujemy licznik
p = td;
while(p)
{
c++; // zwiększamy licznik o 1
p = p->next;
}
return c;
}
// Procedura wyświetla zawartość słownika
//---------------------------------------
void d_print(TDict * td)
{
int i;
TDict * p;
cout << "Liczba kluczy : "
<< d_size(td) << endl;
p = td;
for(i = 1; p; i++,p = p->next)
cout << "Para #" << i
<< " k = " << p->key
<< " v = " << setw(5)
<< p->value << endl;
cout << endl;
}
//---------------
// Program główny
//---------------
int main()
{
// Klucze
string names[] =
{"Janusz", "Marian",
"Henryk", "Adrian",
"Bogdan", "Cyprian",
"Dariusz","Zenon",
"Tadeusz","Karol"};
int i,x;
double v;
TDict * td; // Słownik
cout << fixed
<< setprecision(2);
srand(time(nullptr));
td = nullptr;
// W słowniku umieszamy 7 danych
cout << "TWORZENIE" << endl;
for(i = 0; i < 7; i++)
{
x = rand()%10;
v = 10*rand()/double(RAND_MAX);
d_put(td,names[x],v);
cout << "(" << names[x]
<< "," << setw(5)
<< v << endl;
}
d_print(td);
// Dodajemy 5 elementów
cout << "DODAWANIE" << endl;
for(i = 0; i < 5; i++)
{
x = rand()%10;
v = 10*rand()/double(RAND_MAX);
d_put(td,names[x],v);
cout << "(" << names[x]
<< "," << setw(5)
<< v << endl;
}
d_print(td);
// Usuwamy 5 kluczy
cout << "USUWANIE" << endl;
for(i = 0; i < 5; i++)
{
x = rand()%10;
d_del(td,names[x]);
cout << "(" << names[x]
<< ",*)" << endl;
}
d_print(td);
// Szukamy 10 kluczy
cout << "WYSZUKIWANIE" << endl;
for(i = 0; i < 10; i++)
{
x = rand()%10;
v = d_get(td,names[x]);
if(v != SV)
cout << "klucz " << names[x]
<< " obecny, v = "
<< setw(5) << v << endl;
else
cout << "klucza " << names[x]
<< " brak" << endl;
}
// Usuwamy słownik z pamięci
while(td)
d_del(td,td->key);
return 0;
}
|
Basic' Program testowy dla słownika na liście
' Data: 6.11.2024
' (C)2024 mgr Jerzy Wałaszek
'---------------------------------------
' Typ elementów listy
'--------------------
Type TDict
next As TDict Ptr
key As String
value As Double
End Type
' Wartość specjalna
Const SV = -1000000.0
' Usuwa klucz ze słownika
'------------------------
Sub d_del(ByRef td As TDict Ptr, _
ByRef k As String)
Dim As TDict Ptr p, r
If td = 0 Then Return
If td->key = k Then
r = td->next
delete td
td = r
Return
End If
p = td
While (p->next <> 0) AndAlso _
(p->next->key <> k)
p = p->next
Wend
If p->next = 0 Then Return
r = p->next->next
delete p->next
p->next = r
Return
End Sub
' Umieszcza w słowniku parę (k,v)
'--------------------------------
Sub d_put(ByRef td As TDict Ptr, _
ByRef k As String, _
ByVal v As Double)
Dim As TDict Ptr p
d_del td, k
p = New TDict
p->next = td
p->key = k
p->value = v
td = p
End Sub
' Zwraca wartość v skojarzoną z kluczem k
' lub wartość specjalną SV, jeśli słownik
' nie zawiera klucza k.
Function d_get(ByVal td As TDict Ptr, _
ByRef k As String) _
As Double
Dim As TDict Ptr p
p = td
While (p <> 0) AndAlso (p->key <> k)
p = p->next
Wend
If p <> 0 Then Return p->value
Return SV
End Function
' Funkcja oblicza liczbę kluczy w słowniku
'-----------------------------------------
Function d_size(ByVal td As TDict Ptr) _
As Integer
Dim As TDict Ptr p
Dim As Integer c
c = 0 ' zerujemy licznik
p = td
While p <> 0
c += 1 ' zwiększamy licznik o 1
p = p->next
Wend
Return c
End Function
' Procedura wyświetla zawartość słownika
'---------------------------------------
Sub d_print(ByVal td As TDict Ptr)
Dim As Integer i
Dim As TDict Ptr p
Print "Liczba kluczy : ";d_size(td)
p = td
i = 1
While p <> 0
Print "Para #"; i; " k = "; _
p->key; " v = ";
Print Using "##.##"; p->value
i += 1
p = p->next
Wend
Print
End Sub
'---------------
' Program główny
'---------------
' Klucze
Dim As String names(9) = _
{"Janusz", "Marian", _
"Henryk", "Adrian", _
"Bogdan", "Cyprian",_
"Dariusz","Zenon", _
"Tadeusz","Karol"}
Dim As Integer i,x
Dim As Double v
Dim As TDict Ptr td ' Słownik
Randomize
td = 0
' W słowniku umieszamy 7 danych
Print "TWORZENIE"
For i = 1 To 7
x = Int(Rnd*10)
v = Rnd*10
d_put td,names(x),v
Print "(";names(x);",";
Print Using "##.##";v
Next
d_print td
' Dodajemy 5 elementów
Print "DODAWANIE"
For i = 1 To 5
x = Int(Rnd*10)
v = Rnd*10
d_put td,names(x),v
Print "(";names(x);",";
Print Using "##.##)";v
Next
d_print td
' Usuwamy 5 kluczy
Print "USUWANIE"
For i = 1 To 5
x = Int(Rnd*10)
d_del td,names(x)
Print "(";names(x);",*)"
Next
d_print td
' Szukamy 10 kluczy
Print "WYSZUKIWANIE"
For i = 1 To 10
x = Int(Rnd*10)
v = d_get(td,names(x))
If v <> SV Then
Print "klucz ";names(x);" obecny, v = ";
Print Using "##.##";v
Else
Print "klucza ";names(x);" brak"
End If
Next
' Usuwamy słownik z pamięci
While td <> 0
d_del td,td->key
Wend
End
|
| Python (dodatek) |
# Program testowy dla słownika na liście
# Data: 7.11.2024
# (C)2024 mgr Jerzy Wałaszek
#---------------------------------------
import random
# Typ elementów listy
class TDict:
def __init__(self,n,k,v):
self.next = n
self.key = k
self.value = v
# Wartość specjalna
SV = -1000000.0
# Usuwa klucz ze słownika
def d_del(td,k):
if not td: return None
if td.key == k:
r = td.next
del td
td = None
return r
p = td
while p.next and p.next.key != k:
p = p.next
if not p.next: return td
r = p.next.next
del p.next
p.next = r
return td
# Umieszcza w słowniku parę (k,v)
def d_put(td,k,v):
td = d_del(td, k)
p = TDict(td,k,v)
return p
# Zwraca wartość v skojarzoną z kluczem k
# lub wartość specjalną SV, jeśli słownik
# nie zawiera klucza k.
def d_get(td,k):
global SV
p = td
while p and p.key != k:
p = p.next
if p: return p.value
return SV
# Funkcja oblicza liczbę kluczy w słowniku
def d_size(td):
c = 0 # zerujemy licznik
p = td
while p:
c += 1 # zwiększamy licznik o 1
p = p.next
return c
# Procedura wyświetla zawartość słownika
def d_print(td):
print("Liczba kluczy :",d_size(td))
p = td
i = 1
while p:
print("Para nr",i,"k =",
p.key,"v = %5.2f" % p.value)
i += 1
p = p.next
print()
#---------------
# Program główny
#---------------
# Klucze
names = ["Janusz", "Marian",
"Henryk", "Adrian",
"Bogdan", "Cyprian",
"Dariusz","Zenon",
"Tadeusz","Karol"]
td = None # Słownik
# W słowniku umieszamy 7 danych
print("TWORZENIE SŁOWNIKA:")
for i in range(7):
x = random.randrange(10)
v = random.uniform(0.0,10.0)
td = d_put(td,names[x],v)
print("(",names[x],", %5.2f)" % v, sep="")
d_print(td)
# Dodajemy 5 elementów
print("DODAWANIE ELEMENTÓW:")
for i in range(5):
x = random.randrange(10)
v = random.uniform(0,10)
td = d_put(td,names[x],v)
print("(",names[x],", %5.2f)" % v, sep="")
d_print(td)
# Usuwamy 5 kluczy
print("USUWANIE KLUCZY:")
for i in range(5):
x = random.randrange(10)
td = d_del(td,names[x])
print("(",names[x],",*)",sep="")
d_print(td)
# Szukamy 10 kluczy
print("WYSZUKIWANIE KLUCZY:")
for i in range(10):
x = random.randrange(10)
v = d_get(td,names[x])
if v != SV:
print("klucz",names[x],
"obecny, v = %5.2f" % v)
else:
print("klucza",names[x],"brak")
# Usuwamy słownik z pamięci
while td:
td = d_del(td,td.key)
|
| Wynik: |
TWORZENIE (Bogdan, 2.11) (Henryk, 6.88) (Janusz, 2.18) (Bogdan, 8.93) (Bogdan, 8.44) (Karol, 9.70) (Dariusz, 7.22) Liczba kluczy : 5 Para #1 k = Dariusz v = 7.22 Para #2 k = Karol v = 9.70 Para #3 k = Bogdan v = 8.44 Para #4 k = Janusz v = 2.18 Para #5 k = Henryk v = 6.88 DODAWANIE (Henryk, 8.93) (Marian, 0.83) (Cyprian, 6.27) (Adrian, 8.44) (Zenon, 5.06) Liczba kluczy : 9 Para #1 k = Zenon v = 5.06 Para #2 k = Adrian v = 8.44 Para #3 k = Cyprian v = 6.27 Para #4 k = Marian v = 0.83 Para #5 k = Henryk v = 8.93 Para #6 k = Dariusz v = 7.22 Para #7 k = Karol v = 9.70 Para #8 k = Bogdan v = 8.44 Para #9 k = Janusz v = 2.18 USUWANIE (Cyprian,*) (Adrian,*) (Cyprian,*) (Bogdan,*) (Dariusz,*) Liczba kluczy : 5 Para #1 k = Zenon v = 5.06 Para #2 k = Marian v = 0.83 Para #3 k = Henryk v = 8.93 Para #4 k = Karol v = 9.70 Para #5 k = Janusz v = 2.18 WYSZUKIWANIE klucz Henryk obecny, v = 8.93 klucz Zenon obecny, v = 5.06 klucz Henryk obecny, v = 8.93 klucz Marian obecny, v = 0.83 klucz Marian obecny, v = 0.83 klucza Adrian brak klucza Tadeusz brak klucz Marian obecny, v = 0.83 klucza Cyprian brak klucz Karol obecny, v = 9.70 |
![]() |
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.