You are on page 1of 14

Tìm hiểu cấu trúc dữ liệu tập hợp

Giới thiệu

Khái niệm:

+ Cấu trúc dữ liệu tập hợp (Set Data Structure) là một cấu trúc dữ liệu được sử
dụng để lưu trữ một tập hợp các phần tử duy nhất. Một tập hợp không có các
phần tử trùng lập và không có thứ tự định sẳn của các phần tử.
+ Cấu trúc dữ liệu tập hợp bao gồm các hoạt động như thêm phần tử mới vào
tập hợp, xóa phần tử khỏi tập hợp, tìm kiếm phần tử trong tập hợp, kiểm tra
xem tập hợp có rỗng hay không, lấy số lượng các phần tử trong tập hợp, lấy
toàn bộ các phần tử trong tập hợp,…
+ Cấu trúc dữ liệu tập hợp được sử dụng rội rãi trong các ứng dụng như các
thuật toán tìm kiếm, phân tích dữ liệu, xử lý hình ảnh và quản lý bộ nhớ
cache của các trình duyệt.

Ứng dụng của cấu trúc dữ liệu tập hợp

Cấu trúc dữ liệu tập hợp là một cấu trúc dữ liệu dùng để lưu trữ một tập các phần
tử không trùng nhau. Có nhiều cách để cài đặt cấu trúc dữ liệu này, như sử dụng
cây nhị phân tìm kiếm, bảng băm, hoặc danh sách liên kết. Cấu trúc dữ liệu tập hợp
có nhiều ứng dụng trong lập trình và giải thuật, ví dụ như:

+ Đếm số phần tử khác nhau trong một mảng hoặc một danh sách. Bằng cách
chèn các phần tử vào tập hợp, ta có thể loại bỏ các phần tử trùng lặp và lấy
kích thước của tập hợp làm kết quả.
+ Kiểm tra xem một phần tử có thuộc một tập hợp hay không. Bằng cách sử
dụng các phép toán tìm kiếm trên tập hợp, ta có thể kiểm tra nhanh chóng
xem một phần tử có nằm trong tập hợp hay không.
+ Lưu trữ dữ liệu phân cấp, như là cấu trúc thư mục trên máy tính, cấu trúc của
một tổ chức, hay dữ liệu XML/HTML. Bằng cách sử dụng cây nhị phân làm
cấu trúc dữ liệu tập hợp, ta có thể biểu diễn được các quan hệ cha-con giữa
các phần tử.
+ Thực hiện các phép toán hợp, giao, bù của hai tập hợp. Bằng cách duyệt qua
các phần tử của hai tập hợp và so sánh chúng với nhau, ta có thể tạo ra một
tập hợp mới chứa các phần tử thuộc hoặc không thuộc hai tập hợp ban đầu.

Bài tập minh họa

Bài 1: Đếm số lượng phần tử khác nhau trong mảng số nguyên.

#include <bits/stdc++.h>

using namespace std;

int main(){

int t; cin >> t;

while(t--){

int n; cin >> n;

set<int> se;

for(int i = 0; i < n; i++){

int x; cin >> x;

se.insert(x);

cout << se.size() << endl;

return 0;
}

Bài 2: Cho một mảng số nguyên gồm n phần tử, với mỗi truy vấn này hãy kiểm tra
xem một số nào đó có nằm trong mảng hay không.

#include <bits/stdc++.h>

using namespace std;

int main(){

int t; cin >> t;

while(t--){

int n; cin >> n;

set<int> se;

for(int i = 0; i < n; i++){

int x; cin >> x;

se.insert(x);

int q; cin >> q;

while(q--){

int x; cin >> x;

if(se.count(x) == 1){

cout << "YES\n";


}

else cout << "NO\n";

return 0;

Cài đặt dữ liệu tập hợp bằng danh sách liên kết

• Khai báo

#include<stdlib.h>

#include<iostream>

typedef int ElementType;

typedef struct Node* NodeType;

struct Node {

ElementType Data;

NodeType Next;

};

typedef NodeType Position;


typedef Position SET;

●Khởi tạo tập hợp rỗng

void MakeNull(SET *A) {

(*A)=(NodeType)malloc(sizeof(struct Node));

(*A)->Next= NULL;

• Các phép toán cơ bản trong danh sách liên kết

Position First(SET A){

return A;

ElementType Retrieve(Position P, SET A) {

return P->Next->Data;

Position End(SET A){

Position p;

p = First(A);

while (p->Next !=NULL)

p=p->Next ;

return p;
}

Position Next(Position p, SET A) {

return p->Next;

• Kiểm tra X có thuộc tập A không?

int Member(ElementType X, SET A) {

Position P;

int Found = 0;

P = First(A);

while ((P != End(A)) && (Found == 0))

if (Retrieve(P, A) == X) Found = 1;

else P = Next(P, A);

return Found;

• Thêm một phần tử X vào đầu tập A

void Insert(ElementType X, SET *A) {

Position T;

T=(NodeType)malloc(sizeof(struct Node));

T->Data=X;
T->Next=(*A)->Next;

(*A)->Next=T;

• Phép hợp

void Union(SET A, SET B, SET *C) {

Position p;

MakeNull(C);

p=First(A);

while (p!=End(A)) {

Insert(Retrieve(p, A), C);

p=Next(p,A);

p=First(B);

while (p!=End(B)) {

if (!Member(Retrieve(p, B), *C))

Insert(Retrieve(p, B), C);

p=Next(p,B);

}
• Phép giao

void Intersection(SET A, SET B, SET *C) {

Position p;

MakeNull(C);

p=First(A);

while (p!=End(A)) {

if (Member(Retrieve(p,A),B))

Insert(Retrieve(p,A), C);

p=Next(p,A);

• Phép hiệu

void Difference(SET A, SET B, SET *C) {

Position p;

MakeNull(C);

p=First(A);

while (p!=End(A)) {

if (!Member(Retrieve(p,A),B))

Insert(Retrieve(p,A), C);
p=Next(p,A);

• Tạo Tập Hợp

void reads(ElementType x,SET *A){

MakeNull(A);

Position p;

int i=0,m;

printf("\nNhap so luong phan tu cua tap hop: ");scanf("%d",&m);

while(i!=m){

printf("\nNhap phan tu thu %d: ",i+1);scanf("%d",&x);

if(Member(x,*A)==0){

Insert(x,A);

i++;

else printf("\nphan tu da co trong tap hop nhap lai!");

• In Tập Hợp
void prin(SET C){

Position p;

ElementType x;

p = First(C);

printf("\nTap hop la: ");

printf("{ ");

while (p != End(C)){

x=p->Next->Data;

printf("%d ",x );

p= Next(p, C);

printf("}");

printf("\n");

• Hàm Main

int main() {

SET A;

SET B;

SET C;
ElementType x;

reads(x,&A);

prin(A);

reads(x,&B);

prin(B);

printf("\nHop cua hai tap hop la: ");

Union(A,B,&C);

prin(C);

printf("\nGiao cua hai tap hop la: ");

Intersection(A,B,&C);

prin(C);

printf("\nHieu cua tap hop A voi B la: ");

Difference(A,B,&C);

prin(C);

printf("\nHieu cua tap hop B voi A la: ");

Difference(B,A,&C);

prin(C);

return 0;

}
So sánh tập hợp với danh sách

Cả tập hợp và danh sách đều là cấu trúc dữ liệu được sử dụng để lưu trữ một tập
hợp các phần tử dữ liệu. Tuy nhiên, chúng có những điểm khác nhau sau:

 Tập hợp là một cấu trúc dữ liệu không có thứ tự, không chứa các phần tử trùng
lặp và được sắp xếp theo thứ tự tăng dần. Truy cập ngẫu nhiên vào phần tử
trong tập hợp là khả thi.

 Danh sách là một cấu trúc dữ liệu có thứ tự, có thể chứa các phần tử trùng lặp
và được sắp xếp theo thứ tự tuyến tính. Truy cập ngẫu nhiên vào phần tử trong
danh sách là không khả thi

1. Tập hợp có ưu điểm là:

 Truy cập ngẫu nhiên vào phần tử trong tập hợp là khả thi.
 Có thể thực hiện các phép toán như hợp, giao, hiệu và phép đối xứng giữa các
tập hợp.
 Có thể sử dụng các thuật toán tối ưu để tìm kiếm và sắp xếp các phần tử trong
tập hợp.

2. Danh sách có ưu điểm là:

 Có thể tăng hoặc giảm số lượng phần tử trong quá trình thực thi chương trình.
 Tối ưu dung lượng bộ nhớ.

3. Nhược điểm của tập hợp là:

 Không thể chứa các phần tử trùng lặp.


 Không thể sắp xếp các phần tử theo thứ tự khác ngoài thứ tự tăng dần.
 Không thể lưu trữ các phần tử có tính chất đối tượng.
4. Nhược điểm của danh sách liên kết là:

 Thời gian truy cập là tuyến tính và khó thực thi ống dẫn.
 Truy cập ngẫu nhiên vào phần tử trong danh sách là không khả thi

Danh sách thành viên và phân công công việc

STT Tên thành viên Nhiệm vụ


1 Tô Phước Đầy Ứng dụng cấu trúc tập hợp
2 Lê Phạm Minh Tấn So sánh tập hợp và danh sách
3 Đào Thanh Hào Cài đặt dữ liệu tập hợp
4 Trần Hữu Tài Giới thiệu và thiết kế Powerpoint
5 Ngô Tấn Phúc Bài tập minh họa

You might also like