|
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 zaprojektować strukturę zbiorów rozłącznych opartą na tablicy. |
Struktura zbiorów rozłącznych (ang. disjoint sets structure) pozwala reprezentować zbiory, które nie posiadają części wspólnych. Podstawowym problemem jest określenie sposobu rozpoznawania przynależności elementu do jednego z podzbiorów. Otóż umówmy się, że w każdym z podzbiorów wybierzemy dokładnie jeden element. Element ten będzie reprezentantem danego podzbioru.

Na powyższym rysunku widzimy cztery rozłączne zbiory. W każdym ze zbiorów
jeden element jest reprezentantem i oznaczyliśmy go kolorem czerwonym. Teraz
możemy powiedzieć, że są to zbiory
W strukturze zbiorów rozłącznych definiuje się zwykle dwie operacje:

Strukturę zbiorów rozłącznych można prosto zrealizować w postaci dwóch tablic o tym samym rozmiarze. W jednej tablicy przechowujemy elementy. W drugiej tablicy przechowujemy reprezentantów podzbiorów, zawierających poszczególne elementy. Nazwijmy te tablice odpowiednio E (elementy) i R (reprezentanci). W naszym przykładzie tablice te posiadają następującą zawartość:
![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Operacja Find otrzymuje indeks elementu w tablicy E i zwraca element o tym
indeksie z tablicy R. Wykonywana jest zatem w czasie stałym
Operacja Union jest tutaj bardziej skomplikowana. Otrzymuje ona indeksy
elementów x i y w tablicy
E. Najpierw Union musi sprawdzić, czy oba elementy
należą do różnych podzbiorów. W tym celu wykonuje Find(x) i Find(y),
zapamiętując wyniki
Jeśli elementy tworzą spójny zbiór wartości, to można uprościć strukturę
zbiorów rozłącznych do jednej
![]() |
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
Operacja Find dla danego elementu (indeksu) zwraca
zawartość komórki tablicy R o tym indeksie, czyli zwraca reprezentanta
podzbioru, który zawiera dany element. Np.
Operacja Union(x, y) najpierw zapamiętuje w zmiennych
rx i ry odpowiednio
komórki
Na samym początku korzystania ze struktury zbiorów rozłącznych tablicę R należy odpowiednio zainicjować. W tym przypadku wystarczy wprowadzić do jej komórek ich indeksy. Będzie to odpowiadało utworzeniu n rozłącznych zbiorów jednoelementowych:
![]() |
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
K01: Zakończ z wynikiem R[x]
K01: rx ← R[x] ; znajdujemy reprezentanta zbioru, który zawiera element x K02: ry ← R[y] ; znajdujemy reprezentanta zbioru, który zawiera element y K03: Jeśli rx = ry, ; elementy x i y muszą być w rozłącznych zbiorach to zakończ K04: Dla i = 0, 1, …, n-1: wykonuj krok K05 K05: Jeśli R[i] = ry, ; zastępujemy reprezentanta ry przez to R[i] ← rx ; rx dla wszystkich elementów K06: 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. |
| Program tworzy tablicę R 10-cio elementową, inicjuje ją, a następnie losuje 10 razy pary elementów. Dla wylosowanych elementów wykonywana jest operacja Union, co powoduje połączenie zbiorów, które te elementy zawierają. Na końcu wypisana zostaje przynależność każdego elementu do określonego podzbioru, liczba podzbiorów oraz zawartość tych podzbiorów. |
Pascal// Struktura zbiorów rozłącznych
// Data: 25.03.2014
// (C)2014 mgr Jerzy Wałaszek
//---------------------------
program DSStruct;
const N = 10; // Liczba elementów
var
R : array [0..N-1] of integer;
// Łączy dwa podzbiory w jeden
//----------------------------
procedure Union(x, y : integer);
var
rx, ry, i : integer;
begin
rx := R[x]; // Wyznaczamy reprezentanta
// zbioru zawierającego x
ry := R[y]; // i reprezentanta zbioru
// zawierającego y
if rx <> ry then // Łączenie wymag
// różnych zbiorów
for i := 0 to N-1 do // Przeglądamy kolejne
// elementy tablicy R
if R[i] = ry then
R[i] := rx; // i zastępujemy w nich
// reprezentanta ry przez rx
end;
// **********************
// *** PROGRAM GŁÓWNY ***
// **********************
var
i, j, x, y, c : integer;
begin
Randomize;
for i := 0 to N-1 do
R[i] := i; // Ustawiamy tablicę R
for i := 1 to N do
begin
x := random(N); // Generujemy losowe x i y
y := random(N);
Union(x, y); // Łączymy zbiory
end;
c := 0; // Licznik podzbiorów w R
// Wyświetlamy wyniki
for i := 0 to N-1 do
begin
if R[i] = i then
inc(c); // Zliczamy reprezentantów
writeln(i, ' is in set ', R[i]);
end;
writeln;
writeln('Number of sets = ', c);
writeln;
for i := 0 to N-1 do
if R[i] = i then
begin
write('Set ', i, ' : ');
for j := 0 to N-1 do
if R[j] = i then write(j, ' ');
writeln;
end;
writeln;
end. |
// Struktura zbiorów rozłącznych
// Data: 25.03.2014
// (C)2014 mgr Jerzy Wałaszek
//---------------------------
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
const int N = 10; // Liczba elementów
int R[N];
// Łączy dwa podzbiory w jeden
//----------------------------
void Union(int x, int y)
{
int rx, ry, i;
rx = R[x]; // Wyznaczamy reprezentanta zbioru
// zawierającego x
ry = R[y]; // i reprezentanta zbioru
// zawierającego y
if(rx != ry) // Łączenie wymaga różnych zbiorów
for(i = 0; i < N; i++) // Przeglądamy kolejne
// elementy tablicy R
if(R[i] == ry)
R[i] = rx; // i zastępujemy w nich
// reprezentanta ry przez rx
}
// **********************
// *** PROGRAM GŁÓWNY ***
// **********************
int main()
{
int i, j, x, y, c;
srand(time(NULL));
for(i = 0; i < N; i++)
R[i] = i; // Ustawiamy tablicę R
for(i = 0; i < N; i++)
{
x = rand() % N; // Generujemy losowe x i y
y = rand() % N;
Union(x, y); // Łączymy zbiory
}
c = 0; // Licznik podzbiorów w R
// Wyświetlamy wyniki
for(i = 0; i < N; i++)
{
if(R[i] == i)
|
Basic' Struktura zbiorów rozłącznych
' Data: 25.03.2014
' (C)2014 mgr Jerzy Wałaszek
'---------------------------
const N = 10 ' Liczba elementów
Dim Shared As Integer R(0 To N-1)
' Łączy dwa podzbiory w jeden
'----------------------------
sub union_sets (ByVal x As Integer, _
ByVal y As Integer)
Dim As integer rx, ry, i
rx = R(x) ' Wyznaczamy reprezentanta
' zbioru zawierającego x
ry = R(y) ' i reprezentanta
' zbioru zawierającego y
If rx <> ry Then ' Łączenie wymaga
' różnych zbiorów
For i = 0 To N-1 ' Przeglądamy kolejne
' elementy tablicy R
If R(i) = ry Then _
R(i) = rx ' i zastępujemy w nich
' reprezentanta
' ry przez rx
Next
End If
End Sub
' **********************
' *** PROGRAM GŁÓWNY ***
' **********************
dim As Integer i, j, x, y, c
Randomize
For i = 0 To N-1
R(i) = i ' Ustawiamy tablicę R
Next
For i = 0 To N-1
x = Int(Rnd*N) ' Generujemy losowe x i y
y = Int(Rnd*N)
union_sets(x, y) ' Łączymy zbiory
Next
c = 0 ' Licznik podzbiorów w R
' Wyświetlamy wyniki
For i = 0 To N-1
If R(i) = i Then _
c += 1 ' Zliczamy reprezentantów
Print i;" is in set ";R(i)
Next
Print
Print "Number of sets =";c
Print
For i = 0 To N-1
If R(i) = i Then
Print "Set";i;":";
For j = 0 To N-1
if R(j) = i Then Print j;
Next
Print
End If
Next
Print
End |
Python
(dodatek)# Struktura zbiorów rozłącznych
# Data: 3.03.2024
# (C)2024 mgr Jerzy Wałaszek
#---------------------------
import random
N = 10 # Liczba elementów
# Łączy dwa podzbiory w jeden
#
#----------------------------
def union_sets(r, x, y):
# Wyznaczamy reprezentanta
# zbioru zawierającego x
rx = r[x]
# i reprezentanta
# zbioru zawierającego y
ry = r[y]
# Łączenie wymaga
# różnych zbiorów
if rx != ry:
# Przeglądamy kolejne
# elementy tablicy R
for i in range(N):
if r[i] == ry:
# i zastępujemy w nich
# reprezentanta
# ry przez rx
r[i] = rx
# **********************
# *** PROGRAM GŁÓWNY ***
# **********************
# Tworzymy zbiór
set_r = [i for i in range(N)]
for i in range(N):
# Generujemy losowe x i y
x = random.randrange(N)
y = random.randrange(N)
# Łączymy zbiory
union_sets(set_r, x, y)
# Licznik podzbiorów
c = 0
# Wyświetlamy wyniki
for i in range(N):
if set_r[i] == i:
c += 1 # Zliczamy reprezentantów
print(i, "is in set", set_r[i])
print()
print("Number of sets =", c)
print()
for i in range(N):
if set_r[i] == i:
print("Set", i, ": ", end="")
for j in range(N):
if set_r[j] == i:
print(j, "", end="")
print()
print()
|
| Wynik: |
0 is in set 0 1 is in set 8 2 is in set 6 3 is in set 8 4 is in set 8 5 is in set 5 6 is in set 6 7 is in set 6 8 is in set 8 9 is in set 8 Number of sets = 4 Set 0 : 0 Set 5 : 5 Set 6 : 2 6 7 Set 8 : 1 3 4 8 9 |
![]() |
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.