BỘ CÔNG THƯƠNG TRƯỜNG DẠI HỌC CÔNG THƯƠNG TP.HỒ CHÍ MINHKHOA CÔNG NGHỆ THÔNG TIN ---o0o----TIỂU LUẬN HỌC PHẦN: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT TÊN ĐỀ TÀI: TÌM HIỂU TREESET TRONG JAVA - Ứ
Trang 1BỘ CÔNG THƯƠNG TRƯỜNG DẠI HỌC CÔNG THƯƠNG TP.HỒ CHÍ MINH
KHOA CÔNG NGHỆ THÔNG TIN
-o0o TIỂU LUẬN HỌC PHẦN: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
TÊN ĐỀ TÀI: TÌM HIỂU TREESET TRONG JAVA - ỨNG DỤNG CẤY NHỊ PHÂN TÌM KIẾM ĐỂ VIẾT CHƯƠNG TRÌNH TRÊN NGÔN NGỮ C/C++ HÃY THỰC HIỆN BÀI TOÁN QUẢN LÝ VIỆC CHO THUÊ
PHÒNG TRỌ CỦA MỘT HỘ GIA ĐÌNH.
NHÓM 16
Thành phố Hồ Chí Minh, tháng 05 năm 2025
Trang 2BỘ CÔNG THƯƠNG TRƯỜNG DẠI HỌC CÔNG THƯƠNG TP HỒ CHÍ MINH
KHOA CÔNG NGHỆ THÔNG TIN
-o0o TÊN ĐỀ TÀI: TÌM HIỂU TREESET TRONG JAVA - ỨNG DỤNG CẤY NHỊ PHÂN TÌM KIẾM ĐỂ VIẾT CHƯƠNG TRÌNH TRÊN NGÔN NGỮ C/C++ HÃY THỰC HIỆN BÀI TOÁN QUẢN LÝ VIỆC CHO THUÊ
PHÒNG TRỌ CỦA MỘT HỘ GIA ĐÌNH.
Trưởng nhóm: Nguyễn Thị Yến Nhi
Trang 3Thành phố Hồ Chí Minh, tháng 05 năm 2025
Trang 4BẢNG ĐÁNH GIÁ KẾT QUẢ THỰC HIỆN CÔNG VIỆC NHÓM
Nhiệm vụ được phân công
Đóng góp tỷ lệ
%
Nhóm đánh giá mức độ hoàn thành công việc được phân công
Trang 5LỜI CAM ĐOAN
Chúng em xin cam đoan đề tài: “TÌM HIỂU TREESET TRONG JAVA ỨNG DỤNG CẤY NHỊ PHÂN TÌM KIẾM ĐỂ VIẾT CHƯƠNG TRÌNHTRÊN NGÔN NGỮ C/C++ HÃY THỰC HIỆN BÀI TOÁN QUẢN LÝ VIỆCCHO THUÊ PHÒNG TRỌ CỦA MỘT HỘ GIA ĐÌNH” do nhóm 16 nghiêncứu và thực hiện
-Chúng em đã kiểm tra dữ liệu theo quy địn hiện hành
Kết quả bài làm của đề tài: “TÌM HIỂU TREESET TRONG JAVA ỨNG DỤNG CẤY NHỊ PHÂN TÌM KIẾM ĐỂ VIẾT CHƯƠNG TRÌNHTRÊN NGÔN NGỮ C/C++ HÃY THỰC HIỆN BÀI TOÁN QUẢN LÝ VIỆCCHO THUÊ PHÒNG TRỌ CỦA MỘT HỘ GIA ĐÌNH” là trung thực và khôngsao chép từ bất kì bài tập của nhóm khác
-Các tài liệu được sử dụng trong tiểu luận có nguồn gốc, xuất xứ rõ ràng
Đại diện nhóm trưởng (Đã ký và ghi rõ họ tên)
Trang 6LỜI CẢM ƠN
Lời đầu tiên, chúng em xin trân trọng gửi lời cảm ơn đến với cô Nguyễn Thị Thùy Trang, giáo viên hướng dẫn và đồng thời cũng là người đã tận tình giảng dạy trong suốt quá trình học tập cũng như giúp đỡ chúng em trong thời gian hoàn thành bài tập được giao
Xin gửi lời cảm ơn đến trường Đại học Công Thương TPHCM đã tạo điều kiện cho chúng em có thể hoàn thành bài tập cuối kì được giao
Xin chân thành gửi lời cảm ơn đến các thầy/cô của khoa Công nghệ thôngtin đã nhiệt tình cung cấp cho chúng em những thông tin cần thiết cũng như giúp đỡ trong suốt quá trình thực hiện
Lời cuối cùng, chúng em cũng xin cảm ơn đến gia đình, người thân, bạn
bè đã đồng hành luôn sẵn sàng giúp đỡ chúng em trong suốt quá trình thực hiện bài tập cuối kỳ
Đại diện nhóm trưởng (Đã ký và ghi rõ họ tên)
Trang 7DANH MỤC HÌNH ẢNH TRONG BÁO CÁO
Trang 8PHẦN 1 MỤC LỤC
Trang 9PHẦN 2 MỞ ĐẦU
1 Lời mở đầu
Trong thế giới dữ liệu ngày càng lớn mạnh, việc tìm kiếm và quản lýthông tin một cách hiệu quả trở thành một yêu cầu then chốt Cây nhị phântìm kiếm (Binary Search Tree - BST) là một trong những cấu trúc dữ liệumạnh mẽ, cung cấp khả năng tìm kiếm, chèn và xóa phần tử với hiệu suất
ấn tượng Bài tiểu luận này sẽ đi sâu vào tìm hiểu TreeSet trong Java vàứng dụng cây nhị phân tìm kiếm để viết chương trình trên ngôn ngữ C/C++thực hiện bài toán quản lý việc cho thuê phòng trọ của một hộ gia đình.
2 Mục tiêu của đề tài
Đề tài hướng đến mục tiêu xây dựng một hệ thống quản lý cho thuêphòng trọ có khả năng lưu trữ, quản lý thông tin phòng trọ như là số phòng,người ở, hóa đơn điện nước tối ưu hóa và nhanh chóng Cụ thể đó chính làứng dụng cấu trúc dữ liệu Binary Search Tree để thực hiện các nghiệp vụnhư thêm, tìm kiếm, cập nhật, xóa và theo dõi tình trạng thuê phòng mộtcách tối ưu nhất.
3 Lý do chọn đề tài
Hiện nay cho thấy các chủ trọ đang gặp khó khăn trong quản lý việcthuê phòng trọ tai hộ gia đình khi phải lưu trữ mọi dữ liệu một cách thủcông, không theo quy tắc Việc ứng dụng Binary Search Tree sẽ giúp chủtrọ nâng cao kỹ năng lập trình đồng, dễ dàng giám sát tình hình kinh doanhđồng thời giải quyết được nhiều bài toán thực tế trong quá trình cho thuêphòng.
4 Phạm vi thực hiện
Đề tài tập trung giải quyết các vấn đề cơ bản của một hệ thống quản
lý phòng trọ như:
- Quản lý danh sách phòng và hóa đơn.
- Thêm, xóa, tìm kiếm và hiển thị thông tin.
- Áp dụng thuật toán tìm kiếm trong cây BST, TreeSet để đảm bảohiệu suất.
Trang 10- So sánh hiệu suất giữa TreeSet và BST
- Kiểm tra hiệu suất trên dữ liệu lớn Tối ưu bộ nhớ.
5 Nội dung thực hiện
Nội dung thực hiện bao gồm phân tích yêu cầu, thiết kế mô hình dữliệu, cài đặt các hàm xử lý, thực hiện tìm kiếm bằng nhiều phương phápkhác nhau, từ đó đánh giá hiệu suất Đề tài cũng trình bày rõ ràng thuậttoán tìm kiếm hóa đơn theo số phòng, tìm phòng có nhiều người ở nhất,đồng thời phân tích cách hoạt động của các cấu trúc dữ liệu sử dụng trongchương trình.
Trang 11PHẦN 3 NỘI DUNG
1 KHÁI NIỆM VỀ NGÔN NGỮ LẬP TRÌNH JAVA VÀ TREESET
1.1 Khái niệm về ngôn ngữ lập trình Java:
1.1.1 Java là gì?
Java là ngôn ngữ lập trình hướng đối tượng (tựa C++) do SunMicrosystem đưa ra vào giữa thập niên 90
Chương trình viết bằng ngôn ngữ lập trình java có thể chạy trên bất
kỳ hệ thống nào có cài máy ảo java (Java Virtual Machine)
1.2.2 Lịch sử phát triển của ngôn ngữ lập trình Java
Ngôn ngữ lập trình Java do James Gosling và các công sự của Công
ty Sun Microsystem phát triển
Đầu thập niên 90, Sun Microsystem tập hợp các nhà nghiên cứuthành lập nên nhóm đặt tên là Green Team Nhóm Green Team có tráchnhiệm xây dựng công nghệ mới cho ngành điện tử tiêu dùng Để giải quyếtvấn đề này nhóm nghiên cứu phát triển đã xây dựng một ngôn ngữ lập trìnhmới đặt tên là Oak tương tự như C++ nhưng loại bỏ một số tính năng nguyhiểm của C++ và có khả năng chạy trên nhiều nền phần cứng khác nhạu.Cùng lúc đó world wide web bắt đầu phát triển và Sun đã thấy được tiềmnăng của ngôn ngữ Oak nên đã đầu tư cải tiến và phát triển Sau đó khônglâu ngôn ngữ mới với tên gọi là Java ra đời và được giới thiệu năm 1995
Java là tên gọi của một hòn đảo ở Indonexia, Đây là nơi nhómnghiên cứu phát triển đã chọn để đặt tên cho ngôn ngữ lập trình Java trongmột chuyến đi tham quan và làm việc trên hồn đảo này Hòn đảo Java này
là nơi rất nổi tiếng với nhiều khu vườn trồng cafe, đó chính là lý do chúng
ta thường thấy biểu tượng ly café trong nhiều sản phẩm phần mềm, công cụlập trình Java của Sun cũng như một số hãng phần mềm khác đưa ra
1.2.3 Sự phổ biến của ngôn ngữ lập trình Java
Trang 12Java là một trong những ngôn ngữ lập trình phổ biến nhất hiện nayvới 9 triệu người sử dụng Đây là ngôn ngữ lập trình hướng đối tượng vàđược viết trên cú pháp của C và C++ Nó còn được biết đến với tốc độ xử
lý cao trên các phần mềm, trò chơi máy tính và cả các ứng dụng trên máytính để bàn và thiết bị di động.
1.2.4 Một số đặc điểm nổi bậc của ngôn ngữ lập trình Java
*Thông dịch:
Java là một ngôn ngữ lập trinh vừa biên dịch vừa thông dịch.Chương trình nguồn viết băng ngôn ngữ lập trình Java có đuôi *.java đâutiên được biên dịch thành tập tin có đuôi *.class và sau đó sẽ được trìnhthông dịch thông dịch thành mã máy
*Hướng đối tượng:
Hướng đối tượng trong Java tương tự như C++ nhưng Java là mộtngôn ngữ lập trinh hướng đối tượng hoàn toàn Tất cả mọi thứ đề cập đếntrong Java đều liên quan đến các đối tượng được định nghĩa trước, thậm chíhàm chính của một chương trình viết bằng Java (đó là hàm main) cũng phảiđặt bên trong một lớp Hướng đối tượng trong Java không có tính đa kếthừa (multi inheritance) như trong C++ mà thay vào đó Java đưa ra kháiniệm interface để hỗ trợ tính đa kế thừa
*Đa nhiệm - đa luồng (MultiTasking - Multithreading):
Java hỗ trợ lập trình đa nhiệm, đa luồng cho phép nhiều tiến trình,tiểu trình có thể chạy song song cùng một thời điểm và tương tác với nhau
*Khả chuyển (Portable):
Trang 13Chương trình ứng dụng viết bằng ngôn ngữ Java chỉ cần chạy đượctrên máy ảo Java là có thể chạy được trên bất kỳ máy tính, hệ điều hànhnào có máy ảo Java "Viết một lần, chạy mọi nơi" (WORA)
*Hỗ trợ mạnh cho việc phát triển ứng dụng:
Công nghệ Java phát triển mạnh mẽ nhờ vào “đại gia sunMicrosystem" cung cấp nhiều công cụ, thư viện lập trình phong phú hỗ trợcho việc phát triển nhiều loại hình ứng dụng khác nhau cụ thể như: J2SE(Java 2 Standard Edition) hỗ trợ phát triển những ứng dụng đơn, ứng dụngclient-server; J2EE (Java 2 Enterprise Edition) hỗ trợ phát triển các ứngdụng thương mại, J2ME (Java 2 Micro Edition) hỗ trợ phát triển các ứngdụng trên các thiết bị di động, không dây
1.2 Tổng quan về TreeSet
TreeSet là một trong những triển khai quan trọng nhất của giao diệnSortedSet trong Java sử dụng Tree (cây đỏ – đen) để lưu trữ Thứ tự củacác phần tử được duy trì bởi một tập hợp bằng cách sử dụng thứ tự tựnhiên của chúng bất kể có cung cấp bộ so sánh rõ ràng hay không Điềunày phải nhất quán với equals nếu muốn triển khai đúng giao diện Set. TreeSet không cho phép các phần tử trùng lặp Bất kỳ nỗ lực nào để thêmphần tử trùng lặp sẽ bị bỏ qua
Nó không cho phép giá trị null và sẽ ném NullPointerException khiphần tử null được chèn vào
TreeSet triển khai giao diện NavigableSet và cung cấp các phươngthức bổ sung để điều hướng tập hợp
Nó không an toàn cho luồng Đối với truy cập đồng thời, nó phảiđược đồng bộ hóa bên ngoài bằng cách sử dụngCollections.synchronizedSet()
Nó cũng có thể được sắp xếp theo Comparator được cung cấp tạithời điểm tạo tập hợp, tùy thuộc vào hàm tạo nào được sử dụng TreeSettriển khai giao diện NavigableSet bằng cách kế thừa lớp AbstractSet
Trang 14Hình 1.1 Biểu đồ phân cấp của TreeSet
Có thể thấy rõ từ hình ảnh trên rằng tập hợp có thể điều hướng mởrộng giao diện tập hợp được sắp xếp Vì tập hợp không giữ nguyên thứ tựchèn, nên giao diện tập hợp có thể điều hướng cung cấp triển khai để điềuhướng qua Tập hợp Lớp triển khai tập hợp có thể điều hướng là TreeSet,
là triển khai của cây tự cân bằng Do đó, giao diện này cung cấp chochúng ta cách để điều hướng qua cây này
TreeSet về cơ bản là một triển khai của cây tìm kiếm nhị phân tựcân bàng như Cây Đỏ-Đen Do đó, các hoạt động như thêm, xóa và tìmkiếm mất thời gian O(log(N)) Lý do là trong cây tự cân bằng, người tađảm bảo rằng chiều cao của cây luôn là O(log(N)) cho tất cả các hoạtđộng Do đó, đây được coi là một trong những cấu trúc dữ liệu hiệu quảnhất để lưu trữ dữ liệu được sắp xếp khổng lồ và thực hiện các hoạt độngtrên đó Tuy nhiên, các hoạt động như in N phần tử theo thứ tự được sắpxếp mất thời gian O(N)
1.3 Các thao tác cơ bản của TreeSet trong Java
1.3.1 Khởi tạo TreeSet
TreeSet (): khởi tạo một tập hợp rỗng
TreeSet (Collection c): khởi tạo một tập hợp với cácphần tử của collection c
TreeSet (Comparator comparator): khởi tạo một tập hợprỗng mà các phần tử được xếp thứ tự theo bộ so sánhđược xác định bởi comparator
Hình 1.2 Hàm khởi tạo TreeSet trong Java
Trang 15Ở đây, chúng ta đã tạo một TreeSet mà không có bất kỳ đối số nào.Trong trường hợp này, các phần tử trong TreeSet được sắp xếp tự nhiên(thứ tự tăng dần).
Tuy nhiên, chúng ta có thể tùy chỉnh việc sắp xếp các phần tử bằngcách sử dụng Comparator inferface
1.3.2 Thêm các phần tử vào TreeSet
add (): thêm phần tử được chỉ định vào tập hợp
addAll (): thêm tất cả các phần tử của tập hợp được chỉđịnh vào tập hợp
Kết quả
Hình 1.3 Hàm thêm các phần tử vào TreeSet
1.3.3 Xóa các phần tử trong TreeSet
Trang 16 remove (): xóa phần tử được chỉ định khỏi tập hợp
removeAll (): xóa tất cả các phần tử khỏi tập hợp
Kết quả
Hình 1.4 Hàm xóa các phần tử trong TreeSet
1.3.3 Tìm kiếm thông tin trong TreeSet
Contains(Object o): kiểm tra phần tử cụ thể có tồn tại trong TreeSethay không Phương thức này trả về true nếu phần tử o có trong TreeSet vàtrả về false nếu không có
Trang 17Kết quả
Hình 1.5 Hàm tìm kiếm thông tin trong TreeSet
1.3.4 Duyệt các phần tử trong TreeSet
Để truy cập các phần tử của một tập cây, chúng ta có thể sử dụngiterator () Để sử dụng phương pháp này, chúng ta phải nhậpjava.util.Iterator
Kết quả
Trang 18Hình 1.6 Hàm duyệt các phần tử trong TreeSet
1.3.6 Phương pháp điều hướng trong TreeSet
Vì lớp TreeSet thực thi NavigableSet, nó cung cấp các phương thứckhác nhau để điều hướng qua các phần tử của tập cây
first (): trả về phần tử đầu tiên của tập hợp
last (): trả về phần tử cuối cùng của tập hợp
Kết quả
Hình 1.7 Hàm điều hướng trong TreeSet
higher (element): trả về phần tử thấp nhất trong số các phần tử lớnhơn giá trị được chỉ định element
Trang 19 lower (element): trả về phần tử lớn nhất trong số các phần tử lớn hơngiá trị được chỉ định element.
ceiling (element): trả về phần tử thấp nhất trong số các phần tử lớnhơn giá trị đã chỉ định thành phần Nếu element được truyền tồn tạitrong một tập hợp cây, nó trả về giá trị element được truyền dướidạng đối số
floor (element): Trả về phần tử lớn nhất trong số các phần tử nhỏhơn giá trị được chỉ định element Nếu element được truyền tồn tạitrong một tập hợp cây, nó trả về giá trị element được truyền dướidạng đối số
Kết quả
Hình 1.8 Hàm lưu trữ các số nguyên theo thứ tự tăng dần
pollFirst (): trả về và xóa phần tử đầu tiên khỏi tập hợp
Trang 20 pollLast (): trả về và xóa phần tử cuối cùng khỏi tập hợp
về tất cả các phần tử trước phần tử được chỉ định bao gồm phần tử được chỉ định
Trang 21Kết quả
Hình 1.10 Hàm tạo một tập hợp con chứa các phần tử nhỏ hơn (hoặc nhỏ
hơn hoặc bằng) một giá trị cho trước
2 So sánh hiệu suất giữa TreeSet và BST
Loại cấu trúc Cây đỏ-đen
(Red-Black Tree)
Cây nhị phân tìm kiếm đơn giản Cân bằng tự động Có (luôn giữ cân
tự động
Tốt nhất: O(logn) Xấu nhất: O(log n)
Xử lý dữ liệu mất cân
bằng
Tự động điều chỉnh Phải cài thủ công
(VD: Black)
Trang 22AVL/Red-Thứ tự phần tử Có (tự động sắp xếp) Có (nếu đúng quy tắc
BST) Mức độ tin cậy Rất cao (Java tối ưu
sẵn)
Phụ thuộc và người cài đặt
thực tế
Rất phù hợp Không khuyến khích
nếu chưa cân bằng
3 ỨNG DỤNG CẤY NHỊ PHÂN TÌM KIẾM ĐỂ VIẾT CHƯƠNG TRÌNH TRÊN NGÔN NGỮ C/C++ HÃY THỰC HIỆN BÀI TOÁN QUẢN LÝ VIỆC CHO THUÊ PHÒNG TRỌ CỦA MỘT HỘ GIA ĐÌNH.
3.1 Mô hình quản lý bài toán thuê phòng trọ
Bài toán đặt ra là phát triển một hệ thống quản lý cho thuê phòng trọdành cho hộ gia đình, với mục tiêu lưu trữ và xử lý thông tin một cáchhiệu quả, rõ ràng, cũng như thuận tiện trong việc tra cứu và thống kê Hệthống cần cung cấp các chức năng cơ bản như thêm, xóa, tìm kiếm thôngtin về phòng trọ, hóa đơn và người thuê, cùng với khả năng mở rộng chocác nghiệp vụ như lọc theo tiêu chí, thống kê doanh thu và cảnh báo thờigian thuê sắp hết Để đáp ứng những yêu cầu này, cấu trúc cây nhị phân tìmkiếm (Binary Search Tree - BST) đã được ứng dụng làm nền tảng lưu trữ
và xử lý dữ liệu BST không chỉ tối ưu hóa quy trình tìm kiếm, thêm và xóaphần tử với độ phức tạp trung bình là O(logn), mà còn hỗ trợ tổ chức dữliệu theo một thứ tự nhất định, giúp việc hiển thị và tra cứu trở nên dễ dàng
Trang 233.2 Định nghĩa cấu trúc dữ liệu
Đầu tiên, cần khai báo thư viện:
Hình 3.1 Thao tác khai báo thư viện
Hệ thống được xây dựng dựa trên các cấu trúc dữ liệu sau:
struct NguoiThue: Lưu trữ thông tin người thuê trọ như mã ngườithuê, họ tên, số điện thoại, CCCD, ngày bắt đầu thuê, mã phòngthuê
Hình 3.2 Định nghĩa cấu trúc cho người thuê
struct PhongTro: Mỗi phòng bao gồm mã phòng, diện tích, giá thuê,tiện nghi, tình trạng phòng (trống/đã thuê)
Trang 24Hình 3.3 Định nghĩa cấu trúc cho thông tin phòng trọ
struct HoaDon: Lưu thông tin số hóa đơn, mã người thuê, ngày lập, tổng tiền
Hình 3.4 Định nghĩa cấu trúc cho hóa đơn phòng trọ
struct Node: Cấu trúc node của BST, có thể được sử dụng để lưu danh sách phòng trọ, hóa đơn, hoặc người thuê theo từng cây riêng biệt
Trang 25Hình 3.5 Các thao tác định nghĩa node theo yêu cầu
3.3 Khởi tạo danh sách liên kết đơn
Hình 3.6 Khởi tạo danh sách liên kết đơn gồm người thuê, hóa đơn và chi
tiết hóa đơn
void initNguoiThue(SlistNguoiThue& dsl)
Hàm này khởi tạo một danh sách người thuê
dsl.Head = NULL; và dsl.Tail = NULL; nghĩa là danh sách rỗng – chưa có phần tử nào
3.4 Kiểm tra danh sách liên kết có rỗng hay không
Trang 26Hình 3.7 Hàm kiểm tra danh sách người thuê có rỗng hay không
Hàm này kiểm tra danh sách người thuê (SListNguoiThue)
if (dsl.Head == NULL): kiểm tra xem danh sách có phần tử đầu tiênkhông
Nếu Head == NULL danh sách rỗng trả về 1
Ngược lại danh sách không rỗng trả về 0
Hình 3.8 Hàm kiểm tra danh sách hóa đơn có rỗng hay không
Tương tự, nhưng áp dụng cho danh sách hóa đơn (SListHoaDon)
Hình 3.9 Hàm kiểm tra danh sách chi tiết hóa đơn có rỗng hay không
Như trên, áp dụng cho danh sách chi tiết hóa đơn (SListCTHoaDon)
Trang 27Hình 3.10 Hàm tạo một phòng mới
Cấp phát bộ nhớ để tạo một nút mới
Kiểm tra xem cấp phát có thành công hay không
o Nếu thất bại in ra dòng “Loi Cap Phat” và trả về NULL
Gán dữ liệu của phòng (x) vào nút mới
Đặt con trỏ trái và phải = NULL
Trả về nút mới đã tạo
3.6 Tạo một hóa đơn mới
Hình 3.11 Hàm tạo một hóa đơn mới 3.7 Show menu
Trang 28Hình 3.12 Thao tác tạo một menu quản lý phòng trọ
3.8 Đọc dữ liệu các tập chương trình
Thông tin người thuê được lưu trữ trong file NguoiThue.txt, thông tinphòng trọ được lưu trữ trong file PhongTro.txt; thông tin hóa đơn được lưutrữ trong file HoaDon.txt; chi tiết hóa đơn được lưu trữ trong fileCTHoaDon.txt
Hình 3.13 Hàm đọc dữ liệu từ tập NguoiThue.txt
Trang 29Hình 3.14 Hàm đọc dữ liệu từ tập PhongTro.txt
Hình 3.15 Hàm đọc dữ liệu từ tập HoaDon.txt