|
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
|
Drzewo Trie (ang. trie, digital tree, prefix tree,
czytaj traj) jest drzewem poszukiwań, które używa się do
przechowywania kluczy tekstowych. Umożliwia ono szybkie wyszukiwanie klucza w
zbiorze w czasie

Tablica triref[ ] posiada tyle komórek, z ilu znaków składa się alfabet
używany przez klucze, jeśli są to litery
Pole prefend jest polem logicznym i zawiera informację o końcu znaków klucza (stan true). Poznamy to na przykładach.
Puste drzewo Trie (nie zawierające żadnego klucza) składa się tylko z jednego węzła Trie - korzenia. W korzeniu pole prefend ma zawsze wartość false, co oznacza, iż żaden klucz tutaj się nie kończy. Tablica triref[ ] korzenia pustego drzewa Trie składa się z samych wskazań pustych nil. Oprócz powyższych pól każdy węzeł Tri może przechowywać dodatkowe dane. Węzły Trie definiowane są następująco:
Pascaltype
PTRInode = ^TRInode;
TRInode = record
prefend : Boolean;
triref : array[0..25] of PTRInode;
Data: typ_danych;
end; |
struct TRInode
{
bool prefend;
TRInode * triref[26];
typ_danych data;
}; |
BasicType TRInode prefend As Boolean triref(0 To 25) As TRInode Ptr data As typ_danych End Type |
| Python (dodatek) |
# węzeł TRI
#----------
class TRInode:
def __init__(self):
self.prefend = False
self.triref = [None] * 26
self.data = dane
|
Drzewa Trie służą do efektywnego przechowywania kluczy tekstowych (słów). Prześledźmy na przykładzie wstawianie pierwszego klucza "AND" do pustego drzewa Trie.
![]() |
Puste drzewo Trie składa się tylko z korzenia,
który jest zwykłym węzłem Trie. Tablica triref[ ] zawiera tylko puste wskazania. Pole prefend ma wartość false, co oznacza, iż żaden klucz nie kończy się w tym węźle. |
![]() |
Do drzewa Tri zostanie wstawiony klucz "AND". |
![]() |
Rozpoczynamy "wstawianie" od
pierwszej litery
klucza "AND". W tym celu wyliczamy pozycję pierwszej litery "A" w tablicy triref[ ]: pozycja ← kod("A") - kod("A") = 65 - 65 = 0 Następnie sprawdzamy, czy triref[0] wskazuje węzeł Trie. Nie wskazuje, zatem tworzymy nowy, pusty węzeł Trie i jego adres wstawiamy do triref[0]. Przechodzimy do nowo-utworzonego węzła Trie. |
![]() |
Będąc w nowym węźle Trie (A) wyliczamy pozycję
litery "N" w jego tablicy triref[ ], ponieważ klucz "AND" jeszcze się nie kończy na tej literze: pozycja ← kod("N") - kod("A") = 78 - 65 = 13 Sprawdzamy, czy triref[13] zawiera jakieś wskazanie. Nie zawiera, zatem tworzymy nowy węzeł Trie, wpisujemy jego adres do triref[13] i przechodzimy do nowego węzła. |
![]() |
Jesteśmy w utworzonym węźle Trie
(N). Wyliczamy pozycję litery "D" w tablicy triref[ ]: pozycja ← kod("D") - kod("A") = 68 - 65 = 3 Sprawdzamy, czy triref[3] zawiera jakieś wskazanie. Nie zawiera, zatem tworzymy nowy węzeł Trie (D), wpisujemy jego adres do triref[3] i przechodzimy do niego. Ponieważ litera "D" była ostatnią literą klucza "AND", to nie tworzymy już nowego węzła Trie, natomiast wpisujemy true do pola prefend. Wstawianie jest skończone. |
Węzły drzewa Trie same nie przechowują liter wstawionych kluczy. Informacja o literach znajduje się
pośrednio w ich t
Do naszego drzewa Trie wstawiliśmy klucz "AND" i drzewo wygląda następująco:

Teraz wstawimy do naszego drzewa klucz "ANY":
![]() |
Wstawianie rozpoczynamy zawsze od korzenia
drzewa Trie. W tym przypadku drzewo Trie zawiera już klucz "AND". |
![]() |
Będąc w korzeniu obliczamy pozycję pierwszej
litery
klucza "ANY" w jego tablicy triref[ ]: pozycja ← kod("A") - kod("A") = 65 - 65 = 0 Następnie sprawdzamy, czy element triref[0] wskazuje jakiś węzeł Tri. Tutaj wskazuje, zatem przechodzimy do wskazywanego węzła Tri. Oznacza to, iż w drzewie Trie są już klucze rozpoczynające się od prefiksu "A...". |
![]() |
Będąc w węźle A
obliczamy pozycję drugiej litery klucza "ANY" w jego tablicy triref[ ]: pozycja ← kod("N") - kod("A") = 78 - 65 = 13 Sprawdzamy, czy element trieref[13] wskazuje węzeł Trie. U nas wskazuje, zatem przechodzimy do wskazywanego węzła (N). Oznacza to, iż w drzewie Tri są klucze rozpoczynające się od prefiksu "AN...". |
![]() |
Teraz przetwarzamy ostatnią literę "Y".
Jesteśmy w węźle N. Obliczamy pozycję litery "Y" w tablicy triref[ ] węzła N: pozycja ← kod("Y") - kod("A") = 89 - 65 = 24 Sprawdzamy, czy element triref[24] wskazuje węzeł Trie. Nie wskazuje, zatem tworzymy nowy węzeł Trie i przechodzimy do niego. Ponieważ litera "Y" była ostatnią literą klucza "ANY", to w pole prefend wstawiamy wartość logiczną true. Drzewo Trie zawiera dwa klucze: "AND" i "ANY". Węzeł Y jest liściem drzewa Trie. |
Wynika stąd następujący algorytm wstawiania klucza do drzewa Tre:
K01: p ← r ; rozpoczynamy od korzenia K02: Dla i = 0,1,...,|k|-1: ; przeglądamy k wykonuj kroki K3...K7 K03: c ← kod(k[i])-65 ; pozycja znaku w triref[] K04: Jeśli p→triref[c] ≠ nil, to idź do kroku K07 K05: Utwórz nowy, pusty węzeł Tri K06: p→triref[c] ← adres nowego węzła Tri K07: p ← p→triref[c] ; przechodzimy do węzła K08: p→prefend ← true K09: Zakończ z wynikiem p ; zwracamy wskazanie węzła ; powiązanego z ostatnim znakiem klucza
Standardowy algorytm wyszukiwania klucza w drzewie Trie zwraca logiczne true, jeśli klucz znajduje się w drzewie Tri, inaczej zwraca logiczne false, jeśli drzewo Tri nie przechowuje danego klucza. W zastosowaniach drzew Trie w węzłach umieszcza się zwykle dodatkowe dane powiązane z przechowywanymi kluczami. Najczęściej węzeł skojarzony z ostatnią literą klucza zawiera pożądane dane. Z tego powodu umówmy się, iż nasz algorytm będzie zwracał wskazanie puste, jeśli szukanego klucza brak w drzewie, inaczej będzie zwracał wskazanie węzła powiązanego z ostatnią literą klucza. Ten sposób pracy algorytmu będzie dla nas bardziej użyteczny.
Wyszukiwanie klucza w drzewie Trie
jest podobne do wstawiania, różni się tym, iż nie są tu dodawane do drzewa
węzły, jedynie sprawdza się, czy dla każdej litery klucza jest w drzewie Trie
odpowiedni węzeł oraz czy dla ostatniej litery jej węzeł ma ustawione pole prefend
na true. Jeśli te warunki są spełnione, to drzewo Trie zawiera sprawdzany
klucz.
Jeśli któryś z warunków jest niespełniony, sprawdzanego klucza brak w drzewie.
Wykonywane są następujące operacje:
K01: p ← r ; rozpoczynamy od korzenia K02: Dla i = 0,1,...,|k|-1: ; przeglądamy litery wykonuj kroki K03...K05 ; poszukiwanego klucza k K03: c ← kod(k[i])-65; ; pozycja litery klucza w triref[] K04: Jeśli p→triref[c] = nil, ; jest węzeł Tri dla litery? to idź do kroku K08 K05: p ← p→triref[c] ; tak, przechodzimy do węzła K06: Jeśli p→prefend ≠ true, ; ostatnia litera? to idź do kroku K08 ; brak klucza k K07: Zakończ z wynikiem p K08: Zakończ z wynikiem nil
Usuwanie klucza z drzewa Trie jest trochę bardziej skomplikowane. Musimy tutaj rozważyć kilka przypadków.
Brzmi to nieco skomplikowanie, ale zobaczmy na przykłady:

W drzewie TRIE znajdują się klucze:
Ostatni węzeł klucza zaznaczony jest kolorem żółtym tła oraz czerwonym litery. Chcemy usunąć z drzewa klucz BARKA. Jednakże takiego klucza brak w drzewie. Zatem nic nie robimy.
Tym razem chcemy usunąć klucz AGATA. Klucz ten jest w drzewie TRIE i nie jest on ani częścią innego klucza, ani sam nie zawiera jako prefiks innego klucza:

W takiej sytuacji usuwamy wszystkie węzły tego klucza:



Usuwamy klucz BAT, który jest prefiksem klucza BATALION. W tym wypadku ustawiamy pole prefend w węźle ostatniej litery na wartość false:


W efekcie w drzewie nie ma już klucza BAT, gdyż w węźle litery T nie kończy się żaden klucz.
Usuwamy klucz DERKACZ. Klucz ten posiada wspólny prefiks z kluczem DERKA. W tym wypadku usuwamy, idąc od końca, wszystkie węzły aż do osiągnięcia najdłuższego wspólnego prefiksu:



W algorytmie usuwania klucza wykorzystuje się sprawdzanie, czy węzeł drzewa Trie nie wskazuje następnego węzła Trie (lub węzłów Trie). Operacja polega na przeglądnięciu tablicy triref[ ] węzła. Jeśli którykolwiek z jej elementów zawiera wskazanie węzła, to zwracamy logiczne false (węzeł Trie nie jest pusty). Jeśli wszystkie jej elementy zawierają wskazania puste nil, to zwracamy logiczne true (węzeł Trie jest pusty).
K01: Dla i = 0,1,..., 25: ; Przeglądamy tablicę triref[] wykonuj krok K02 K02: Jeśli triref[] ≠ nil, ; Wskazanie węzła? to zakończ z wynikiem false K03: Zakończ z wynikiem true
Usuwanie klucza wykonywane jest rekurencyjnie.
K01: Jeśli r = nil, ; sprawdzamy, czy węzeł r istnieje to zakończ z wynikiem nil ; jeśli nie, kończymy K02: Jeśli d < |k|, ; ostatni znak klucza? to idź do kroku K08 ; jeśli nie, idź dalej K03: r→prefend ← false ; zerujemy znacznik końca K04: Jeśli trie_empty(r) = false, to idź do kroku K07 K05: Usuń węzeł r z pamięci ; pusty węzeł K06: r ← nil K07: Zakończ z wynikiem r K08: c ← kod(k[d])-65 ; obliczamy pozycję litery klucza K09: r→triref[c] ← trie_delete(r→triref[c],k,d+1) ; rekurencja K10: Jeśli trie_empty(r) = true i r→prefend = false, to idź do kroku K05 Inaczej idź do kroku K07
Procedura posiada dwa parametry:
trie_traversal(r, k)
r : wskazanie bieżącego węzła drzewa Trie.
k : tworzony klucz.
Procedurę wywołujemy ze wskazaniem korzenia drzewa Trie oraz pustym kluczem k. W procedurze trie_traverse( ) sprawdzamy najpierw, czy wskaźnik r wskazuje węzeł Trie. Jeśli nie, to procedurę kończymy. Następnie sprawdzamy, czy pole prefend węzła r ma stan true. Jeśli tak, to parametr k jest znalezionym kluczem i możemy go przetworzyć. Następnie przeglądamy tablicę triref[ ]. Dla każdego elementu tej tablicy wywołujemy rekurencyjnie procedurę trie_traverse( ) z elementem tablicy triref[ ] oraz kluczem k zwiększonym o literę odpowiadającą elementowi tablicy triref[ ]. Po przetworzeniu wszystkich elementów triref[ ], kończymy.
Procedurę wywołujemy ze wskazaniem korzenia drzewa Trie i pustym łańcuchem klucza k.
K01: Jeśli r = nil, ; puste wskazanie? to zakończ K02: Jeśli r→prefend = true, ; koniec klucza? przetwarzaj k ; w tym miejscu można również ; przetwarzać węzeł r, który jest powiązany ; z ostatnią literą klucza k K03: Dla i = 0,1,...,25: wykonuj ; przeglądamy triref[] trie_traverse(r→triref[i],k+chr(i+65)) ; rekurencja K04: Zakończ
Procedurę wywołujemy ze wskazaniem korzenia drzewa Trie. Po zakończeniu operacji korzeń można usunąć z pamięci.
K01: Jeśli r = nil to zakończ K02: Dla i = 0,1,...,25: ; przeglądamy triref[] wykonuj kroki K03...K06 K03: Jeśli r→triref[i] = nil, ; pomijamy puste wskazania to następny obieg pętli K01 K04: Jeśli tri_empty(r→triref[i]) = false, ; jeśli węzeł nie jest pusty, to tri_remove(r→triref[i]) ; to rekurencyjnie usuwamy jego zawartość K05: Usuń węzeł r→triref[i] ; usuwamy sam węzeł z pamięci K06: r→triref[i] ← nil K07: Zakończ
|
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. |
| W programie tworzone jest puste drzewo Trie, po czym zostają na nim umieszczone 10 razy klucze z puli 16 zdefiniowanych w programie, Następnie program sprawdza 10 losowych kluczy z puli, czy znajdują się na drzewie. Na koniec program usuwa z drzewa 8 razy klucze losowane z puli. Za każdym razem wyświetlana jest zawartość drzewa. |
Pascal// Drzewo TRIE
// Data: 30.10.2024
// (C)2024 mgr Jerzy Wałaszek
//---------------------------
program trie;
// Węzeł Trie
type
PTRInode = ^TRInode;
TRInode = record
prefend : Boolean;
triref : array[0..25] of PTRInode;
end;
// Inicjuje węzeł Trie
//--------------------
procedure tri_init(p : PTRInode);
var
i : integer;
begin
p^.prefend := false;
for i := 0 to 25 do
p^.triref[i] := nil;
end;
// Sprawdza, czy węzeł jest pusty
// r - wskazanie węzła
// Wynik:
// true - węzeł jest pusty
// false - węzeł nie jest pusty
//-------------------------------
function tri_empty(r : PTRInode)
: boolean;
var
i : integer;
begin
for i := 0 to 25 do
if r^.triref[i] <> nil then
exit(false);
tri_empty := true;
end;
// Wstawia klucz k do drzewa r
// r - korzeń drzewa
// k - klucz
// Zwraca ostatni węzeł klucza
//----------------------------
function tri_insert(r : PTRInode;
k : string)
: PTRInode;
var
p : PTRInode;
i, c : integer;
begin
p := r;
for i := 1 to length(k) do
begin
c := ord(k[i])-65;
if p^.triref[c] = nil then
begin
new(p^.triref[c]);
tri_init(p^.triref[c]);
end;
p := p^.triref[c];
end;
p^.prefend := true;
tri_insert := p
end;
// Wyszukuje klucz k w drzewie r
// r - korzeń
// k - szukany klucz
// Zwraca ostatni węzeł klucza lub nil
//------------------------------------
function tri_find(r : PTRInode;
k : string)
: PTRInode;
var
p : PTRInode;
i,c : integer;
begin
p := r;
for i := 1 to length(k) do
begin
c := ord(k[i])-65;
if p^.triref[c] = nil then exit(nil);
p := p^.triref[c];
end;
if p^.prefend = false then exit(nil);
tri_find := p;
end;
// Usuwa klucz z drzewa r
// r - wskazanie korzenia
// k - usuwany klucz
// d - pozycja znaku usuwanego klucza.
// Zwraca wskazanie węzła
//------------------------------------
function tri_delete(r : PTRInode;
k : string;
d : integer)
: PTRInode;
var
c : integer;
begin
if r = nil then exit(nil);
if d = length(k)+1 then
begin
r^.prefend := false;
if tri_empty(r) = true then
begin
dispose(r);
exit(nil);
end;
exit(r);
end;
c := ord(k[d])-65;
r^.triref[c] :=
tri_delete(r^.triref[c],k,d+1);
if (tri_empty(r) = true) and
(r^.prefend = false) then
begin
dispose(r);
exit(nil);
end;
exit(r);
end;
// Przechodzi przez drzewo TRIE
// r - korzeń
// k - klucz
//-----------------------------
procedure tri_traverse(r : PTRInode;
k : string);
var
i : integer;
begin
if r = nil then exit();
if r^.prefend = true then
writeln(k);
for i := 0 to 25 do
tri_traverse(r^.triref[i],k+chr(i+65));
end;
// Usuwa drzewo TRIE
// r - korzeń
//------------------
procedure tri_remove(r : PTRInode);
var
i : integer;
begin
if r <> nil then
for i := 0 to 25 do
begin
if r^.triref[i] = nil then continue;
if tri_empty(r^.triref[i]) = false then
tri_remove(r^.triref[i]);
dispose(r^.triref[i]);
r^.triref[i] := nil;
end;
end;
// Program główny
//---------------
var
// Klucze
keys : array[0..15] of string =
('ALGA', 'ALGORYTM',
'ALT', 'ARGON',
'BRAMA', 'BRAWO',
'KOMAR','KOC',
'KOCZKODAN','LAWETA',
'LAWA','LEN',
'MORZE','MORA',
'MAT','MATA');
i,j : integer;
root : PTRInode;
begin
randomize();
// Tworzymy puste drzewo TRIE
new(root);
tri_init(root);
// W drzewie umieszczamy 10 losowych kluczy
writeln('DODAJEMY:');
for i := 1 to 10 do
begin
j := random(16);
writeln(keys[j]);
tri_insert(root,keys[j])
end;
writeln;
writeln('DRZEWO TRIE:');
tri_traverse(root,'');
writeln;
// Szukamy 10 losowych kluczy
for i := 1 to 10 do
begin
j := random(16);
write('KLUCZ ',keys[j],' ');
if tri_find(root,keys[j]) = nil then
write('NIE');
writeln('OBECNY');
end;
writeln;
// Usuwamy 8 losowych kluczy
writeln('USUWAMY:');
for i := 1 to 8 do
begin
j := random(16);
writeln(keys[j]);
root := tri_delete(root,keys[j],1);
end;
writeln;
writeln('DRZEWO TRIE:');
tri_traverse(root,'');
writeln;
// Usuwamy drzewo
tri_remove(root);
dispose(root);
end. |
// Drzewo TRIE
// Data: 30.10.2024
// (C)2024 mgr Jerzy Wałaszek
//---------------------------
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
// Węzeł Trie
struct TRInode
{
bool prefend;
TRInode * triref[26];
};
// Inicjuje węzeł Trie
//--------------------
void tri_init(TRInode * p)
{
int i;
p->prefend = false;
for(i = 0; i < 26; i++)
p->triref[i] = nullptr;
}
// Sprawdza, czy węzeł jest pusty
// r - wskazanie węzła
// Wynik:
// true - węzeł jest pusty
// false - węzeł nie jest pusty
//-------------------------------
bool tri_empty(TRInode * r)
{
int i;
for(i = 0; i < 26; i++)
if(r->triref[i]) return false;
return true;
}
// Wstawia klucz k do drzewa r
// r - korzeń drzewa
// k - klucz
// Zwraca ostatni węzeł klucza
//----------------------------
TRInode * tri_insert(TRInode * r,
string k)
{
TRInode * p;
int i, c;
p = r;
for(i = 0; i < (int) k.length(); i++)
{
c = k[i]-65;
if(!p->triref[c])
{
p->triref[c] = new(TRInode);
tri_init(p->triref[c]);
}
p = p->triref[c];
}
p->prefend = true;
return p;
}
// Wyszukuje klucz k w drzewie r
// r - korzeń
// k - szukany klucz
// Zwraca ostatni węzeł klucza lub nil
//------------------------------------
TRInode * tri_find(TRInode * r,
string k)
{
TRInode * p;
int i, c;
p = r;
for(i = 0; i < (int)k.length(); i++)
{
c = k[i]-65;
if(!p->triref[c]) return nullptr;
p = p->triref[c];
}
if(!p->prefend) return nullptr;
return p;
}
// Usuwa klucz z drzewa r
// r - wskazanie korzenia
// k - usuwany klucz
// d - pozycja znaku usuwanego klucza.
// Zwraca wskazanie węzła
//------------------------------------
TRInode * tri_delete(TRInode * r,
string k,
int d)
{
int c;
if(!r) return nullptr;
if(d == (int)k.length())
{
r->prefend = false;
if(tri_empty(r))
{
delete r;
return nullptr;
}
return r;
}
c = k[d]-65;
r->triref[c] =
tri_delete(r->triref[c],k,d+1);
if(tri_empty(r) && !r->prefend)
{
delete r;
return nullptr;
}
return r;
}
// Przechodzi przez drzewo TRIE
// r - korzeń
// k - klucz
//-----------------------------
void tri_traverse(TRInode * r,
string k)
{
int i;
if(!r) return;
if(r->prefend)
cout << k << endl;
for(i = 0; i < 26; i++)
tri_traverse(r->triref[i],k+char(i+65));
}
// Usuwa drzewo TRIE
// r - korzeń
//------------------
void tri_remove(TRInode * r)
{
int i;
if(r)
for(i = 0; i < 26; i++)
{
if(!r->triref[i]) continue;
if(!tri_empty(r->triref[i]))
tri_remove(r->triref[i]);
delete r->triref[i];
r->triref[i] = nullptr;
}
}
// Program główny
//---------------
main()
{
// Klucze
string keys[16] =
{"ALGA","ALGORYTM",
"ALT", "ARGON",
"BRAMA","BRAWO",
"KOMAR","KOC",
"KOCZKODAN","LAWETA",
"LAWA","LEN",
"MORZE","MORA",
"MAT","MATA"};
int i,j;
TRInode * root;
// Inicjujemy generator pseudolosowy
srand(time(NULL));
// Tworzymy puste drzewo TRIE
root = new(TRInode);
tri_init(root);
// W drzewie umieszczamy 10 losowych kluczy
cout << "DODAJEMY:" << endl;
for(i = 0; i < 10; i++)
{
j = rand() % 16;
cout << keys[j] << endl;
tri_insert(root,keys[j]);
}
cout << endl
<< "DRZEWO TRIE:" << endl;
tri_traverse(root,"");
cout << endl;
// Szukamy 10 losowych kluczy
for(i = 0; i < 10; i++)
{
j = rand() % 16;
cout << "KLUCZ " << keys[j] << " ";
if(!tri_find(root,keys[j]))
cout << "NIE";
cout << "OBECNY" << endl;
}
// Usuwamy 8 losowych kluczy
cout << endl
<< "USUWAMY:" << endl;
for(i = 0; i < 8; i++)
{
j = rand() % 16;
cout << keys[j] << endl;
root = tri_delete(root,keys[j],0);
}
cout << endl
<< "DRZEWO TRIE:" << endl;
tri_traverse(root,"");
cout << endl;
// Usuwamy drzewo
tri_remove(root);
delete root;
}
|
Basic' Drzewo TRIE
' Data: 30.10.2024
' (C)2024 mgr Jerzy Wałaszek
'---------------------------
' Węzeł Trie
Type TRInode
prefend As Boolean
triref(0 To 25) As TRInode Ptr
End Type
' Inicjuje węzeł Trie
'--------------------
Sub tri_init(ByVal p As TRInode Ptr)
Dim i As Integer
p->prefend = False
For i = 0 To 25
p->triref(i) = 0
Next
End Sub
' Sprawdza, czy węzeł jest pusty
' r - wskazanie węzła
' Wynik:
' true - węzeł jest pusty
' false - węzeł nie jest pusty
'-------------------------------
Function tri_empty(ByVal r As TRInode Ptr) _
As Boolean
Dim i As Integer
For i = 0 To 25
If r->triref(i) <> 0 Then Return False
Next
Return True
End Function
' Wstawia klucz k do drzewa r
' r - korzeń drzewa
' k - klucz
' Zwraca ostatni węzeł klucza
'----------------------------
Function tri_insert(ByVal r As TRInode Ptr,_
ByVal k As String) _
As TRInode Ptr
Dim p As TRInode Ptr
Dim As Integer i, c
p = r
For i = 0 To Len(k) - 1
c = k[i] - 65
If p->triref(c) = 0 Then
p->triref(c) = New TRInode
tri_init(p->triref(c))
End If
p = p->triref(c)
Next
p->prefend = True
Return p
End Function
' Wyszukuje klucz k w drzewie r
' r - korzeń
' k - szukany klucz
' Zwraca ostatni węzeł klucza lub 0
'----------------------------------
Function tri_find(ByVal r As TRInode Ptr, _
ByVal k As String) _
As Trinode Ptr
Dim p As TRInode Ptr
Dim As Integer i, c
p = r
For i = 0 To Len(k) - 1
c = k[i] - 65
If p->triref(c) = 0 Then Return 0
p = p->triref(c)
Next
If p->prefend = False Then Return 0
Return p
End Function
' Usuwa klucz z drzewa r
' r - wskazanie korzenia
' k - usuwany klucz
' d - pozycja znaku usuwanego klucza.
' Zwraca wskazanie węzła
'------------------------------------
Function tri_delete(ByVal r As TRInode Ptr, _
ByVal k As String, _
ByVal d As Integer) _
As TRInode Ptr
Dim c As Integer
If r = 0 Then Return 0
If d = Len(k) Then
r->prefend = False
If tri_empty(r) = True Then
Delete r
Return 0
End If
Return r
End If
c = k[d] - 65
r->triref(c) = _
tri_delete(r->triref(c),k,d + 1)
If (tri_empty(r) = True) AndAlso _
(r->prefend = False) Then
Delete r
Return 0
End If
Return r
End Function
' Przechodzi przez drzewo TRIE
' r - korzeń
' k - klucz
'-----------------------------
Sub tri_traverse(ByVal r as TRInode Ptr, _
ByVal k As String)
Dim i As Integer
If r = 0 Then Return
If r->prefend = True Then _
Print k
For i = 0 To 25
tri_traverse(r->triref(i),k+chr(i+65))
Next
End Sub
' Usuwa drzewo TRIE
' r - korzeń
'------------------
Sub tri_remove(ByVal r As TRInode Ptr)
Dim i As Integer
If r <> 0 Then
For i = 0 To 25
If r->triref(i) = 0 Then Continue For
If tri_empty(r->triref(i)) = False Then _
tri_remove(r->triref(i))
Delete r->triref(i)
r->triref(i) = 0
Next
End If
End Sub
' Program główny
'---------------
' Klucze
Dim As String keys(15) = _
{"ALGA","ALGORYTM",_
"ALT", "ARGON",_
"BRAMA","BRAWO",_
"KOMAR","KOC",_
"KOCZKODAN","LAWETA",_
"LAWA","LEN",_
"MORZE","MORA",_
"MAT","MATA"}
Dim As Integer i,j
Dim root As TRInode Ptr
' Inicjujemy generator pseudolosowy
Randomize
' Tworzymy puste drzewo TRIE
root = new TRInode
tri_init root
' W drzewie umieszczamy 10 losowych kluczy
Print "DODAJEMY:"
For i = 1 To 10
j = Int(Rnd * 16)
Print keys(j)
tri_insert root,keys(j)
Next
Print
Print "DRZEWO TRIE:"
tri_traverse root,""
Print
' Szukamy 10 losowych kluczy
For i = 1 To 10
j = Int(Rnd * 16)
Print "KLUCZ "; keys(j);" ";
If tri_find(root,keys(j)) = 0 Then _
Print "NIE";
Print "OBECNY"
Next
Print
' Usuwamy 8 losowych kluczy
Print "USUWAMY:"
For i = 1 To 8
j = Int(Rnd * 16)
Print keys(j)
root = tri_delete(root,keys(j),0)
Next
Print
Print "DRZEWO TRIE:"
tri_traverse root,""
Print
' Usuwamy drzewo
tri_remove root
Delete root
End
|
Python
(dodatek)# Drzewo TRIE
# Data: 30.10.2024
# (C)2024 mgr Jerzy Wałaszek
#---------------------------
import random
# węzeł TRI
class TRInode:
def __init__(self):
self.prefend = False
self.triref = [None] * 26
# Sprawdza, czy węzeł jest pusty
# r - wskazanie węzła
# Wynik:
# true - węzeł jest pusty
# false - węzeł nie jest pusty
#-------------------------------
def tri_empty(r):
for i in range(26):
if r.triref[i]:
return False
return True
# Wstawia klucz k do drzewa r
# r - korzeń drzewa
# k - klucz
# Zwraca ostatni węzeł klucza
def tri_insert(r, k):
p = r
for i in range(len(k)):
c = ord(k[i]) - 65
if not p.triref[c]:
p.triref[c] = TRInode()
p = p.triref[c]
p.prefend = True
return p
# Wyszukuje klucz k w drzewie r
# r - korzeń
# k - szukany klucz
# Zwraca ostatni węzeł klucza lub 0
def tri_find(r, k):
p = r
for i in range(len(k)):
c = ord(k[i]) - 65
if not p.triref[c]:
return None
p = p.triref[c]
if not p.prefend:
return None
return p
# Usuwa klucz z drzewa r
# r - wskazanie korzenia
# k - usuwany klucz
# d - pozycja znaku usuwanego klucza.
# Zwraca wskazanie węzła
def tri_delete(r, k, d):
if not r: return None
if d == len(k):
r.prefend = False
if tri_empty(r):
del r
r = None
return r
c = ord(k[d]) - 65
r.triref[c] = tri_delete(r.triref[c],k,d+1)
if tri_empty(r) and not r.prefend:
del r
r = None
return r
# Przechodzi przez drzewo TRIE
# r - korzeń
# k - klucz
def tri_traverse(r, k):
if not r: return
if r.prefend: print(k)
for i in range(26):
tri_traverse(r.triref[i],k+chr(i+65))
# Usuwa drzewo TRIE
# r - korzeń
def tri_remove(r):
if r:
for i in range(26):
if not r.triref[i]: continue
if not tri_empty(r.triref[i]):
tri_remove(r.triref[i])
r.triref[i] = None
# Program główny
#---------------
# Klucze
keys = ["ALGA","ALGORYTM",
"ALT", "ARGON",
"BRAMA","BRAWO",
"KOMAR","KOC",
"KOCZKODAN","LAWETA",
"LAWA","LEN",
"MORZE","MORA",
"MAT","MATA"]
root = TRInode()
# W drzewie umieszczamy 10 losowych kluczy
print("DODAJEMY:")
for i in range(10):
j = random.randrange(16)
print(keys[j])
tri_insert(root, keys[j])
print()
print("DRZEWO TRIE:")
tri_traverse(root, "")
print()
# Szukamy 10 losowych kluczy
for i in range(10):
j = random.randrange(16)
print("KLUCZ", keys[j], end=" ")
if not tri_find(root,keys[j]):
print("NIE", end="")
print("OBECNY")
print()
print("USUWAMY:")
for i in range(8):
j = random.randrange(16)
print(keys[j])
root = tri_delete(root, keys[j],0)
print()
print("DRZEWO TRIE:")
tri_traverse(root, "")
print()
tri_remove(root)
del root
|
| Wynik: |
DODAJEMY: ALGORYTM BRAMA KOC BRAWO KOCZKODAN KOMAR KOCZKODAN MORZE ARGON KOCZKODAN DRZEWO TRIE: ALGORYTM ARGON BRAMA BRAWO KOC KOCZKODAN KOMAR MORZE KLUCZ MATA NIEOBECNY KLUCZ ARGON OBECNY KLUCZ LAWA NIEOBECNY KLUCZ MORZE OBECNY KLUCZ ARGON OBECNY KLUCZ BRAWO OBECNY KLUCZ ALGA NIEOBECNY KLUCZ MAT NIEOBECNY KLUCZ BRAWO OBECNY KLUCZ LEN NIEOBECNY USUWAMY: ARGON ALGORYTM KOMAR KOCZKODAN ALGORYTM LEN KOCZKODAN BRAMA DRZEWO TRIE: BRAWO KOC MORZE |
![]() |
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.