lOMoARcPSD| 60729183
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ ĐÔNG Á
KHOA CÔNG NGHỆ THÔNG TIN
BÀI TẬP LỚN
HỌC PHẦN: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
MÃ ĐỀ THI 02: XÂY DỰNG BÀI TOÁN QUẢN LÝ NHÂN VIÊN
SỬ DỤNG DANH SÁCH LIÊN KẾT ĐƠN
LỚP TÍN CHỈ: CTDLVGT.03.K13.01.LH.C04.1_LT.1_TH
Giảng viên hướng dẫn: Mai Văn Linh
Danh sách sinh viên thực hiện: Nhóm 4
TT
Mã sinh viên
Sinh viên thực hiện
Lớp hành chính
1
20211692
Lã Văn Bảo
DCCNTT12.10.6
2
20223733
Trần Đình Thịnh
DCCNTT13.10.20
3
20211725
Chu Hải Huy
DCCNTT12.10.6
Bắc Ninh – 2025
lOMoARcPSD| 60729183
MỤC LỤC
CHƯƠNG 1: TỔNG QUAN MÔN HỌC CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
KIẾN THỨC CƠ BẢN VỀ HỌC PHẦN ................. Lỗi! Th đánh du không đưc xác đnh.
1.1.Giới thiệu về môn học ...................................................................................................... 5
1.2. Mục tiêu của môn học ..................................................................................................... 5
1.3. Nội dung chính của học phần ......................................................................................... 5
1.4. Ứng dụng thực tiễn .......................................................................................................... 5
CHƯƠNG 2: TỔNG QUAN VỀ ĐỀ TÀI ..................................................................................... 5
2.1. Giới thiệu đề tài ............................................................................................................... 5
2.2. Phân tích đề tài ................................................................................................................ 6
CHƯƠNG 3: PHÂN TÍCH CHƯƠNG TRÌNH ........................................................................ 13
3.1. Cu trúc dữ liệu ............................................................................................................. 13
3.2. Khởi tạo nút ................................................................................................................... 14
3.3. Nhập dữ liệu ................................................................................................................... 14
3.4. Hiển th danh sách ......................................................................................................... 16
3.5. Thêm vào đầu danh sách............................................................................................... 17
3.6. Chèn vào cuối danh sách ............................................................................................... 17
3.7. Xóa nhân viên theo mã .................................................................................................. 18
3.8. Xóa nhân viên theo tên .................................................................................................. 19
3.9. Đếm số lưng nhân viên có lương dưới 5 triệu ........................................................... 19
3.10. Tìm kiếm nhân viên theo mã NV ............................................................................... 20
3.11. Tính lương trung bình của danh sách nhân viên ...................................................... 20
3.13. Ghi danh sách nhân viên vào tệp ............................................................................... 21
3.14. Sắp xếp danh sách nhân viên theo lương tăng dần .................................................. 21
3.15. Thoát khỏi chương trình ............................................................................................. 22
CHƯƠNG 4: MÃ NGUỒN CHƯƠNG TRÌNH ........................................................................ 24
4.1. Đnh nghĩa cu trúc và hàm tạo node .......................................................................... 24
4.2. Thêm Nhân Viên ............................................................................................................ 24
4.3. Xóa Nhân Viên ............................................................................................................... 25
4.4. Hiển th danh sách Nhân Viên ...................................................................................... 26
4.5. Tìm kiếm Nhân Viên ...................................................................................................... 26
4.6. Đếm Nhân Viên có lương dưới 5 tr .............................................................................. 27
4.7. Tính lương trung bình ................................................................................................... 28
4.8. Sắp xếp tăng theo lương ................................................................................................ 28
lOMoARcPSD| 60729183
CHƯƠNG 5: KẾT LUẬN ............................................................................................................ 29
TÀI LIỆU THAM KHẢO ........................................................................................................... 30
lOMoARcPSD| 60729183
LỜI NÓI ĐẦU
Trong thời đại công nghệ thông tin phát triển mạnh mẽ, việc xử và quản lý dữ liệu
một cách hiệu quả đóng vai trò cùng quan trọng trong hầu hết các lĩnh vực, đặc biệt
trong quản nhân sự. Quản nhân viên một bài toán thực tế thường gặp trong c
doanh nghiệp, tổ chức, quan, nơi thông tin nhân sự cần được u trữ, truy xuất
cập nhật một cách linh hoạt, chính xác và nhanh chóng.
Trong khuôn khổ học phần cấu trúc dữ liệu và giải thuật, việc lựa chọn cấu trúc dữ
liệu phù hợp để giải quyết các bài toán quản yếu tố then chốt đtối ưu hóa hiệu suất
chương trình. Trong số các cấu trúc phổ biến, danh sách liên kết đơn là một lựa chọn hiệu
quả nhờ khả năng cấp phát bộ nhlinh hoạt dễ dàng trong thao tác thêm, xóa phần tử
mà không cần dịch chuyển dữ liệu như trong mảng tĩnh.
Xuất phát từ những do trên, em đã chọn đề tài “Xây dựng bài toán quản nhân
viên sử dụng danh sách liên kết đơn” nhằm áp dụng kiến thức thuyết vào thực hành, đồng
thời rèn luyện kỹ năng lập trình và duy thuật toán. Tiểu luận này sẽ trình bày cách thiết
kế, xây dựng cài đặt chương trình quản danh sách nhân viên với các chức năng bản
như thêm, sửa, xóa, tìm kiếm hiển thị thông tin nhân viên, tất cả đều được xử lý trên nền
tảng danh sách liên kết đơn.
Em hy vọng bài tiểu luận sẽ góp phần củng cố kiến thức về cấu trúc dữ liệu, đồng
thời là nền tảng để phát triển các ứng dụng quản lý phức tạp hơn trong tương lai.
CHƯƠNG 1: TỔNG QUAN MÔN HỌC CẤU TRÚC DỮ LIỆU GIẢI THUẬT
VÀ KIẾN THỨC CƠ BẢN VỀ HỌC PHẦN
lOMoARcPSD| 60729183
1.1.Giới thiu vmôn học
Cấu trúc dữ liệu giải thuật (Data Structures and Algorithms - DSA) một trong
những môn học quan trọng trong lĩnh vực Khoa học máy tính Công nghệ thông tin. Môn
học này cung cấp kiến thức nền tảng về cách tổ chức, lưu trữ dữ liệu hiệu quả cũng như các
thuật toán giúp xử lý, tìm kiếm và sắp xếp dữ liệu tối ưu.
1.2. Mục tiêu của môn học
Hiểu và vận dụng các cấu trúc dữ liệu cơ bản như mảng, danh sách liên kết, cây, đồ
thị, hàng đợi, ngăn xếp, bảng băm.
Nắm vững các thuật toán tìm kiếm, sắp xếp và xử lý dữ liệu.
Phát triển tư duy thuật toán và khả năng tối ưu hóa giải thuật.
Ứng dụng kiến thức vào lập trình thực tế, tối ưu hiệu suất chương trình.
1.3. Nội dung chính của học phần
Cấu trúc dữ liệu cơ bản: Mảng, danh sách liên kết, ngăn xếp, hàng đợi.
Cấu trúc dữ liệu nâng cao: Cây, đồ thị, bảng băm.
Thuật toán tìm kiếm: Tìm kiếm tuần tự, m kiếm nhị phân, tìm kiếm trên đồ thị
(BFS, DFS).
Thuật toán sắp xếp: Bubble Sort, Quick Sort, Merge Sort, Heap Sort.
Độ phức tạp thuật toán: Phân tích Big-O, đánh giá hiệu suất thuật toán.
1.4. Ứng dụng thực tin
Tối ưu hóa truy vấn và xử lý dữ liệu trong hệ thống phần mềm.
Phát triển thuật toán cho trí tuệ nhân tạo, phân tích dữ liệu.
Xây dựng hệ thống tìm kiếm, mạng xã hội, thương mại điện tử.
CHƯƠNG 2: TỔNG QUAN VỀ ĐỀ TÀI
2.1. Giới thiệu đề tài
Trong nh vực quản dữ liệu, việc xây dựng các hệ thống quản lý thông tin nhân
sự đóng vai trò quan trọng giúp các tổ chức, doanh nghiệp theo dõi, cập nhật xử thông
tin một cách hiệu quả. Bài toán quản nhân viên không chỉ đơn thuần lưu trữ dliệu,
lOMoARcPSD| 60729183
còn đòi hỏi khả năng xử linh hoạt như thêm, sửa, xóa tìm kiếm thông tin nhanh
chóng.
Trong đề tài này, chúng em lựa chọn danh sách liên kết đơn làm cấu trúc dữ liệu chính để
cài đặt chương trình quản lý nhân viên. Khác với mảng tĩnh có giới hạn kích thước và kém
linh hoạt khi thay đổi dữ liệu, danh sách liên kết đơn cho phép thao c thêm hoặc xóa phần
tử một cách linh động mà không cần cấp phát lại bộ nhớ cho toàn bộ danh sách. Đây là một
ưu điểm phù hợp với các ứng dụng có dữ liệu biến động thường xuyên như hệ thống quản
lý nhân sự.
Đề tài tập trung vào việc xây dựng một chương trình đơn giản nhưng đầy đủ chức năng cơ
bản của một hệ thống quản lý nhân viên, bao gồm: thêm nhân viên mới, hiển thị danh sách,
tìm kiếm, cập nhật xóa thông tin nhân viên. Thông qua đó, đề tài không chỉ giúp rèn
luyện kỹ năng lập trình duy thuật toán, mà còn giúp sinh viên hiểu hơn về cách ứng
dụng cấu trúc dữ liệu trong thực tế.
2.2. Phân tích đề tài
2.2.1. Dữ liệu lưu trữ
Dữ liệu cần quản lý và lưu trữ về nhân viên gồm:
nhân viên (int): Là số định danh duy nhất cho mỗi nhân viên trong hệ thống,
giúp dễ dàng tìm kiếm và xử lý.
Họ tên (char[]): Họ và tên đầy đủ của nhân viên, dùng để hiển thị và tìm kiếm.
Lương (double): Mức lương bản của nhân viên, phục vụ cho việc tính toán, thống
kê và sắp xếp.
Bộ dữ liệu được lưu trong tệp văn bản tên nhanvien.txt lần ợt gồm c thông tin (mã nhân
viên, tên nhân viên,lương nhân viên) của 10 nhân viên như sau:
1,Bao,4000000.00
2,Thinh,7000000.00
3,Huy,10000000.00
4,c,5000000.00
5,z,3000000.00
6,d,5000000.00
lOMoARcPSD| 60729183
7,k,5007000.00
8,y2,5500000.00
9,mm,5000000.00
10,cm,5600000.00
2.2.2. Cu trúc dữ liệu
Giới thiệu về danh sách liên kết đơn
Danh sách liên kết đơn (Singly Linked List) một cấu trúc dữ liệu bao gồm nhiều nút
(node), trong đó mỗi nút chứa hai phần:
Dữ liệu (data): Giá trị của phần tử trong danh sách.
Con trỏ (next): Trỏ đến nút tiếp theo trong danh sách.
Danh sách liên kết đơn khác với mảng ở chỗ:
Các phần tử không lưu trữ liên tiếp trong bộ nhớ.
Không cần cấp phát kích thước cố định như mảng.
Chèn/xóa phần tử nhanh hơn so với mảng.
Cấu trúc danh sách liên kết đơn
Mỗi nút trong danh sách liên kết đơn được định nghĩa bằng một cấu trúc (struct) trong
C/C++:
struct Node {
int data; // Dữ liệu của nút
Node* next; // Con trỏ trỏ đến nút tiếp theo
};
Head → [10 | *] → [20 | *] → [30 | *] → NULL
Các thao tác trên danh sách liên kết đơn
Khởi tạo danh sách liên kết đơn:
Node* createNode(int value) {
Node* newNode = new Node();
newNode->data = value;
newNode->next = nullptr;
return newNode;
}
lOMoARcPSD| 60729183
Duyệt danh sách liên kết đơn: void
traverse(Node* head) {
Node* temp = head; while
(temp != nullptr) { cout
<< temp->data << " → ";
temp = temp->next;
}
cout << "NULL" << endl;
}
Chèn phần tử vào danh sách liên kết
đơn: void insertAtHead(Node*& head, int
value) { Node* newNode =
createNode(value); newNode-
>next = head; head = newNode;
}
Chèn vào cuối danh sách void
insertAtTail(Node*& head, int value) {
Node* newNode =
createNode(value); if (head
== nullptr) { head = newNode;
return;
}
Node* temp = head;
while (temp->next != nullptr) {
temp = temp->next;
}
temp->next = newNode;
}
lOMoARcPSD| 60729183
Chèn vào vị trí bất kỳ: void insertAtPosition(Node*&
head, int value, int position) { if (position == 0) {
insertAtHead(head, value);
return;
}
Node* temp = head;
for (int i = 0; i < position - 1 && temp != nullptr;
i++) temp = temp->next; if (temp
== nullptr) return; Node* newNode =
createNode(value); newNode->next = temp-
>next; temp->next = newNode;
}
}
Xóa phần tử trong danh sách liên kết đơn void
deleteHead(Node*& head) { if (head == nullptr)
return; Node* temp = head; head =
head->next; delete temp;
}
Xóa nút cuối cùng
void deleteTail(Node*& head) {
if (head == nullptr) return;
if (head->next == nullptr) {
delete head; head =
nullptr; return;
}
Node* temp = head;
while (temp->next->next != nullptr)
lOMoARcPSD| 60729183
temp = temp->next; delete temp-
>next; temp->next = nullptr;
}
Xóa nút tại vị trí bất kỳ void deleteAtPosition(Node*& head, int position) {
if (head == nullptr) return; if (position == 0) {
deleteHead(head); return; }
Node* temp = head;
for (int i = 0; i < position - 1 && temp->next != nullptr;
i++) temp = temp->next; if (temp->next ==
nullptr) return; Node* toDelete = temp->next; temp-
>next = temp->next->next; delete toDelete;
}
Tìm kiếm phần tử trong danh sách
bool search(Node* head, int key) {
Node* temp = head; while
(temp != nullptr) { if (temp->data
== key) return true; temp =
temp->next;
}
return false;
}
Ứng dụng của danh sách liên kết đơn
Quản lý bộ nhớ động: Cấu trúc dữ liệu động giúp tiết kiệm bộ nhớ.
Cấu trúc dữ liệu Stack Queue: Stack (ngăn xếp), Queue (hàng đợi) thể triển
khai bằng danh sách liên kết.
Undo/Redo trong phần mềm: Sử dụng danh sách liên kết để lưu lịch sử thao tác.
Hệ thống tệp tin: Hệ điều hành dùng danh sách liên kết để quản lý tệp.
Đồ thị và cây: Danh sách liên kết giúp lưu trữ danh sách kề trong đồ thị.
lOMoARcPSD| 60729183
Cấu trúc dữ liệu sử dụng trong bài toán đề tài
struct NhanVien { int
maNV; char
hoTen[100]; double
luong; struct
NhanVien* next;
};
2.2.3. Các chức năng
Hiển thị danh sách
Lấy danh sách các điện thoại từ tệp nhanvien.txt ra danh sách đơn. Sau đó hiển
thị danh sách ra màn hình
Thêm vào đầu danh sách
Cho người dùng nhập vào:
- Mã nhân viên
- Tên nhân viên
- Mức lương
Sau đó cho thông tin nhân viên đó vào đầu danh sách
Chèn vào cuối danh sách
Cho người dùng nhập vào:
- Mã nhân viên
- Tên nhân viên
- Mức lương
Sau đó cho thông tin nhân viên đó vào cuối danh sách
Xóa nhân viên theo mã nhân viên
Cho người dùng nhập vào 1 mã nhân viên bất kỳ
Sau đó xóa nhân viên có mã vừa nhập đi
Xóa nhân viên theo tên nhân viên
Cho người dùng nhập vào 1 tên nhân viên bất kỳ
Sau đó xóa nhân viên có tên vừa nhập đi
Đếm nhân viên lương < 5tr
lOMoARcPSD| 60729183
Hiển thị thông tin danh sách nhân viên lương < 5tr
Tìm theo mã NV
Cho người dùng nhập vào 1 mã nhân viên
Nếu tìm thấy thì hiển thị thông tin nhân viên này
Nếu không tìm thấy thì thông báo “Không tìm thấy nhân viên có mã …!”
Hien thi ds nhan vien
Tim kiem theo khoang luong
Ghi danh sach vao tep
Tinh luong trung binh
Sap xep tang theo luong
Thoat
2.2.4. Thiết kế menu
---------CAC CHUC NANG QUAN LY NHAN VIEN---------
1. Doc du lieu tu tep
2. Them vao dau danh sach
3. Chen vao cuoi danh sach
4. Xoa nhan vien theo ma
5. Xoa nhan vien theo ten
6. Dem nhan vien luong < 5tr
7. Tim theo ma NV
8. Hien thi ds nhan vien
9. Tim kiem theo khoang luong
10. Ghi danh sach vao tep 11.
Tinh luong trung binh
12. Sap xep tang theo luong
13. Thoat
Chon chuc nang:
lOMoARcPSD| 60729183
CHƯƠNG 3: PHÂN TÍCH CHƯƠNG TRÌNH
3.1. Cu trúc dữ liu
struct NhanVien {
int maNV;
char hoTen[100;
double luong;
struct NhanVien* next
};
maNV : Dùng để định danh và tìm kiếm nhân viên. hoTen : Lưu tên nhân viên.
luong : Lưu thông tin về mức lương. next : Trỏ đến phần tử tiếp theo trong danh
sách, hoặc NULL nếu là phần tử cuối.
Các thao tác đã cài đặt :
themDau(), themCuoi()
Thêm nhân viên vào đầu/cuối danh sách
xoaTheoMa(), xoaTheoTen()
Xóa nhân viên dựa trên mã hoặc tên
timTheoMa(),
timTheoKhoang()
Tìm nhân viên theo mã hoặc theo
khoảng lương
inDanhSach()
Hiển thị toàn bộ danh sách
demLuongNhoHon(),
tinhLuongTB()
Đếm số nhân viên lương dưới mức,
tính lương trung bình
lOMoARcPSD| 60729183
sapXepLuong()
Sắp xếp danh sách theo lương tăng dần
(Bubble Sort)
ghiFile(), docFile()
Ghi và đọc danh sách từ file
giaiPhong()
Giải phóng toàn bộ danh sách để tránh rò
rỉ bộ nhớ
3.2. Khởi tạo nút
struct NhanVien* taoNhanVien(int ma, char* ten, double luong) { struct
NhanVien* nv = (struct NhanVien*)malloc(sizeof(struct NhanVien)); nv-
>maNV = ma; strcpy(nv->hoTen, ten); nv->luong =
luong; nv->next = NULL; return nv;
}
Việc dùng malloc() giúp cấp phát bộ nhớ động, cho phép danh sách mở rộng không giới
hạn số phần tử, không cần khai báo kích thước trước như mảng.
Mỗi t đều chứa con trỏ next trỏ tới phần tử tiếp theo, tạo thành một chuỗi liên kết dễ dàng
chèn, xóa mà không cần dịch chuyển dữ liệu.
nv->next = NULL; đảm bảo nút mới được thêm vào luôn xác định được điểm kết thúc nếu
nó chưa liên kết với nút nào khác.
Hàm taoNhanVien() có thể được gọi ở nhiều nơi (thêm đầu, thêm cuối) mà không cần viết
lại mã cấp phát.
3.3. Nhập dliu
Chức năng nhập dữ liệu cho phép người dùng thêm các nhân viên vào danh sách liên
kết
Nhập từ bàn phím: người dùng nhập thủ công thông tin nhân viên.
Đọc từ tệp (file): chương trình tự động nạp danh sách nhân viên từ tệp
nhanvien.txt.
Modul mã nguồn
Nhập từ bàn phím :
if (nguon == 1) {
int soLuong;
lOMoARcPSD| 60729183
printf("Nhap so nhan vien: ");
scanf("%d", &soLuong); getchar(); for
(int i = 0; i < soLuong; i++) {
printf("Nhan vien %d:\n", i + 1);
printf("Ma: "); scanf("%d", &ma); getchar();
printf("Ten: "); fgets(ten, 100, stdin); ten[strcspn(ten, "\n")] = 0;
printf("Luong: "); scanf("%lf", &luong); themCuoi(&ds, ma,
ten, luong);
}
}
Đọc từ file(docFile())
void docFile(struct NhanVien** head, const char* filename) {
FILE* f = fopen(filename, "r");
if (!f) {
printf("Khong tim thay tep!\n");
return;
} int ma;
char ten[100];
double luong;
while (fscanf(f, "%d,%99[^,],%lf\n", &ma, ten, &luong) == 3)
themCuoi(head, ma, ten, luong);
fclose(f);
printf("Da doc danh sach tu tep.\n");
}
Màn hình hiển thị
----- CHON NGUON DU LIEU ----- 1.
Nhap danh sach nhan vien bang tay
2. Doc danh sach nhan vien tu tep
Lua chon: 1
Nhap so nhan vien: 2
lOMoARcPSD| 60729183
Nhan vien 1:
Ma: 101
Ten: Bao
Luong: 7000000
Nhan vien 2:
Ma: 102
Ten: Thinh
Luong: 8500000
Nếu chọn đọc từ file:
----- CHON NGUON DU LIEU -----
1. Nhap danh sach nhan vien bang tay
2. Doc danh sach nhan vien tu tep
Lua chon: 2
Da doc danh sach tu tep.
3.4. Hiển th danh sách
Chức năng hiển thị danh sách giúp người dùng xem toàn bộ thông tin của nhân viên đang
được lưu trong danh sách liên kết đơn.
Dữ liệu được in ra theo định dạng:
Ma: <Mã NV> | Ten: <Họ tên> | Luong: <Mức lương>
Modul mã nguồn :
void inDanhSach(struct NhanVien* head) {
if (!head) {
printf("Danh sach rong!\n");
return;
}
printf("\nDanh sach nhan vien:\n");
while (head) {
printf("Ma: %d | Ten: %s | Luong: %.2lf\n",
lOMoARcPSD| 60729183
head->maNV, head->hoTen, head->luong);
head = head->next;
}
}
3.5. Thêm vào đầu danh sách
Mô tả chức năng
Chức năng thêm vào đầu danh sách cho phép người dùng nhập thông tin một
nhân viên mới và chèn nút đó vào đầu danh sách liên kết đơn.
Khi thực hiện, nút mới sẽ trở thành nút đầu tiên và trỏ đến nút cũ trước đó.
Giúp thêm nhanh một nhân viên mà không cần duyệt hết danh sách.
Modul mã nguồn:
void themDau(struct NhanVien** head, int ma, char* ten, double luong) {
struct NhanVien* nv = taoNhanVien(ma, ten, luong); nv->next =
*head;
*head = nv;
}
3.6. Chèn vào cuối danh sách
Mô tả chức năng
Chức năng chèn vào cuối danh sách cho phép thêm một nhân viên mới vào vị trí
cuối cùng của danh sách liên kết.
Chương trình sẽ duyệt từ đầu đến cuối danh sách, tìm nút cuối (có next = NULL)
và gắn nút mới vào đó.
Nếu danh sách đang rỗng (head == NULL), nút mới sẽ trở thành nút đầu.
Modul mã nguồn:
void themCuoi(struct NhanVien** head, int ma, char* ten, double luong) {
struct NhanVien* nv = taoNhanVien(ma, ten, luong); if (*head ==
NULL) { // Nếu danh sách rỗng
*head = nv;
} else {
struct NhanVien* temp = *head;
lOMoARcPSD| 60729183
while (temp->next != NULL) // Duyệt đến nút cuối
temp = temp->next;
temp->next = nv; // Gắn nút mới vào cuối
}
}
3.7. Xóa nhân viên theo mã
Mô tả chức năng
Chức năng xóa nhân viên theo mã cho phép người dùng nhập vào một nhân
viên (maNV).
Chương trình sẽ duyệt qua danh sách liên kết, tìm nút có maNV trùng khớp.
Nếu tìm thấy, nút đó sẽ bị gỡ ra khỏi danh sách bộ nhớ của được giải phóng.
Nếu không tìm thấy, chương trình thông báo "Không tìm thấy mã...".
Modul mã nguồn:
void xoaTheoMa(struct NhanVien** head, int ma) {
struct NhanVien *temp = *head, *prev = NULL;
while (temp && temp->maNV != ma) {
prev = temp;
temp = temp->next;
} if
(!temp) {
printf("Khong tim thay ma %d\n", ma);
return;
} if
(!prev)
*head = temp->next;
else
prev->next = temp->next;
free(temp);
printf("Da xoa nhan vien co ma %d\n", ma);
lOMoARcPSD| 60729183
}
3.8. Xóa nhân viên theo tên
Mô tả chức năng
Chức năng này cho phép người dùng nhập vào tên nhân viên cần xóa.
Chương trình sẽ duyệt danh sách liên kết để tìm nhân viên có hoTen trùng khớp.
Nếu tìm thấy, nút đó bị xóa khỏi danh sách và giải phóng bộ nhớ.
Nếu không tìm thấy, hiển thị thông báo "Không tìm thấy tên...".
Modul mã nguồn:
void xoaTheoTen(struct NhanVien** head, char* ten) {
struct NhanVien *temp = *head, *prev = NULL;
while (temp && strcmp(temp->hoTen, ten) != 0) {
prev = temp; temp = temp->next;
} if
(!temp) {
printf("Khong tim thay ten %s\n", ten);
return;
} if
(!prev)
*head = temp->next;
else
prev->next = temp->next;
free(temp);
printf("Da xoa nhan vien ten %s\n", ten);
}
3.9. Đếm số lưng nhân viên có lương dưới 5 triệu
Mô tả chức năng
Chức năng này duyệt qua toàn bộ danh sách liên kết, đếm số nhân viên có luong
nhỏ hơn 5.000.000.
Kết quả được trả về là một số nguyên và in ra màn hình.
lOMoARcPSD| 60729183
Modul mã nguồn: int demLuongNhoHon(struct NhanVien* head,
double muc) { int dem = 0; while (head) { if (head->luong <
muc) dem++; head = head->next;
}
return dem;
}
3.10. Tìm kiếm nhân viên theo mã NV
Mô tả chức năng
Chức năng này cho phép người dùng nhập vào mã nhân viên (maNV) cần tìm.
Chương trình sẽ duyệt danh sách liên kết để so sánh mã từng nhân viên.
Nếu tìm thấy, in ra thông tin nhân viên. Nếu không tìm thấy, thông báo không
tồn tại.
Modul mã nguồn:
void timTheoMa(struct NhanVien* head, int ma) {
while (head) {
if (head->maNV == ma) {
printf("Tim thay: %d - %s - %.2lf\n", head->maNV, head->hoTen, head-
>luong);
return;
}
head = head->next;
}
printf("Khong tim thay nhan vien co ma %d\n", ma);
}
3.11. Tính lương trung bình của danh sách nhân viên
Mô tả chức năng
Chức năng này sẽ duyệt toàn bộ danh sách liên kết, cộng dồn lương của các nhân
viên và đếm số lượng nhân viên.
Sau đó tính lương trung bình = (Tổng lương) / (Số lượng nhân viên).
Nếu danh sách rỗng, kết quả trả về là 0.

Preview text:

lOMoAR cPSD| 60729183
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ ĐÔNG Á
KHOA CÔNG NGHỆ THÔNG TIN BÀI TẬP LỚN
HỌC PHẦN: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
MÃ ĐỀ THI 02: XÂY DỰNG BÀI TOÁN QUẢN LÝ NHÂN VIÊN
SỬ DỤNG DANH SÁCH LIÊN KẾT ĐƠN
LỚP TÍN CHỈ: CTDLVGT.03.K13.01.LH.C04.1_LT.1_TH
Giảng viên hướng dẫn: Mai Văn Linh
Danh sách sinh viên thực hiện: Nhóm 4 TT Mã sinh viên
Sinh viên thực hiện Lớp hành chính 1 20211692 Lã Văn Bảo DCCNTT12.10.6 2 20223733 Trần Đình Thịnh DCCNTT13.10.20 3 20211725 Chu Hải Huy DCCNTT12.10.6 Bắc Ninh – 2025 lOMoAR cPSD| 60729183 MỤC LỤC
CHƯƠNG 1: TỔNG QUAN MÔN HỌC CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT VÀ
KIẾN THỨC CƠ BẢN VỀ HỌC PHẦN ................. Lỗi! Thẻ đánh dấu không được xác định.
1.1.Giới thiệu về môn học ...................................................................................................... 5
1.2. Mục tiêu của môn học ..................................................................................................... 5
1.3. Nội dung chính của học phần ......................................................................................... 5
1.4. Ứng dụng thực tiễn .......................................................................................................... 5
CHƯƠNG 2: TỔNG QUAN VỀ ĐỀ TÀI ..................................................................................... 5
2.1. Giới thiệu đề tài ............................................................................................................... 5
2.2. Phân tích đề tài ................................................................................................................ 6
CHƯƠNG 3: PHÂN TÍCH CHƯƠNG TRÌNH ........................................................................ 13
3.1. Cấu trúc dữ liệu ............................................................................................................. 13
3.2. Khởi tạo nút ................................................................................................................... 14
3.3. Nhập dữ liệu ................................................................................................................... 14
3.4. Hiển thị danh sách ......................................................................................................... 16
3.5. Thêm vào đầu danh sách............................................................................................... 17
3.6. Chèn vào cuối danh sách ............................................................................................... 17
3.7. Xóa nhân viên theo mã .................................................................................................. 18
3.8. Xóa nhân viên theo tên .................................................................................................. 19
3.9. Đếm số lượng nhân viên có lương dưới 5 triệu ........................................................... 19
3.10. Tìm kiếm nhân viên theo mã NV ............................................................................... 20
3.11. Tính lương trung bình của danh sách nhân viên ...................................................... 20
3.13. Ghi danh sách nhân viên vào tệp ............................................................................... 21
3.14. Sắp xếp danh sách nhân viên theo lương tăng dần .................................................. 21
3.15. Thoát khỏi chương trình ............................................................................................. 22
CHƯƠNG 4: MÃ NGUỒN CHƯƠNG TRÌNH ........................................................................ 24
4.1. Định nghĩa cấu trúc và hàm tạo node .......................................................................... 24
4.2. Thêm Nhân Viên ............................................................................................................ 24
4.3. Xóa Nhân Viên ............................................................................................................... 25
4.4. Hiển thị danh sách Nhân Viên ...................................................................................... 26
4.5. Tìm kiếm Nhân Viên ...................................................................................................... 26
4.6. Đếm Nhân Viên có lương dưới 5 tr .............................................................................. 27
4.7. Tính lương trung bình ................................................................................................... 28
4.8. Sắp xếp tăng theo lương ................................................................................................ 28 lOMoAR cPSD| 60729183
CHƯƠNG 5: KẾT LUẬN ............................................................................................................ 29
TÀI LIỆU THAM KHẢO ........................................................................................................... 30 lOMoAR cPSD| 60729183 LỜI NÓI ĐẦU
Trong thời đại công nghệ thông tin phát triển mạnh mẽ, việc xử lý và quản lý dữ liệu
một cách hiệu quả đóng vai trò vô cùng quan trọng trong hầu hết các lĩnh vực, đặc biệt là
trong quản lý nhân sự. Quản lý nhân viên là một bài toán thực tế thường gặp trong các
doanh nghiệp, tổ chức, cơ quan, nơi mà thông tin nhân sự cần được lưu trữ, truy xuất và
cập nhật một cách linh hoạt, chính xác và nhanh chóng.
Trong khuôn khổ học phần cấu trúc dữ liệu và giải thuật, việc lựa chọn cấu trúc dữ
liệu phù hợp để giải quyết các bài toán quản lý là yếu tố then chốt để tối ưu hóa hiệu suất
chương trình. Trong số các cấu trúc phổ biến, danh sách liên kết đơn là một lựa chọn hiệu
quả nhờ khả năng cấp phát bộ nhớ linh hoạt và dễ dàng trong thao tác thêm, xóa phần tử
mà không cần dịch chuyển dữ liệu như trong mảng tĩnh.
Xuất phát từ những lý do trên, em đã chọn đề tài “Xây dựng bài toán quản lý nhân
viên sử dụng danh sách liên kết đơn” nhằm áp dụng kiến thức lý thuyết vào thực hành, đồng
thời rèn luyện kỹ năng lập trình và tư duy thuật toán. Tiểu luận này sẽ trình bày cách thiết
kế, xây dựng và cài đặt chương trình quản lý danh sách nhân viên với các chức năng cơ bản
như thêm, sửa, xóa, tìm kiếm và hiển thị thông tin nhân viên, tất cả đều được xử lý trên nền
tảng danh sách liên kết đơn.
Em hy vọng bài tiểu luận sẽ góp phần củng cố kiến thức về cấu trúc dữ liệu, đồng
thời là nền tảng để phát triển các ứng dụng quản lý phức tạp hơn trong tương lai.
CHƯƠNG 1: TỔNG QUAN MÔN HỌC CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
VÀ KIẾN THỨC CƠ BẢN VỀ HỌC PHẦN lOMoAR cPSD| 60729183
1.1.Giới thiệu về môn học
Cấu trúc dữ liệu và giải thuật (Data Structures and Algorithms - DSA) là một trong
những môn học quan trọng trong lĩnh vực Khoa học máy tính và Công nghệ thông tin. Môn
học này cung cấp kiến thức nền tảng về cách tổ chức, lưu trữ dữ liệu hiệu quả cũng như các
thuật toán giúp xử lý, tìm kiếm và sắp xếp dữ liệu tối ưu.
1.2. Mục tiêu của môn học
• Hiểu và vận dụng các cấu trúc dữ liệu cơ bản như mảng, danh sách liên kết, cây, đồ
thị, hàng đợi, ngăn xếp, bảng băm.
• Nắm vững các thuật toán tìm kiếm, sắp xếp và xử lý dữ liệu.
• Phát triển tư duy thuật toán và khả năng tối ưu hóa giải thuật.
• Ứng dụng kiến thức vào lập trình thực tế, tối ưu hiệu suất chương trình.
1.3. Nội dung chính của học phần
• Cấu trúc dữ liệu cơ bản: Mảng, danh sách liên kết, ngăn xếp, hàng đợi.
• Cấu trúc dữ liệu nâng cao: Cây, đồ thị, bảng băm.
• Thuật toán tìm kiếm: Tìm kiếm tuần tự, tìm kiếm nhị phân, tìm kiếm trên đồ thị (BFS, DFS).
• Thuật toán sắp xếp: Bubble Sort, Quick Sort, Merge Sort, Heap Sort.
• Độ phức tạp thuật toán: Phân tích Big-O, đánh giá hiệu suất thuật toán.
1.4. Ứng dụng thực tiễn
• Tối ưu hóa truy vấn và xử lý dữ liệu trong hệ thống phần mềm.
• Phát triển thuật toán cho trí tuệ nhân tạo, phân tích dữ liệu.
• Xây dựng hệ thống tìm kiếm, mạng xã hội, thương mại điện tử.
CHƯƠNG 2: TỔNG QUAN VỀ ĐỀ TÀI
2.1. Giới thiệu đề tài
Trong lĩnh vực quản lý dữ liệu, việc xây dựng các hệ thống quản lý thông tin nhân
sự đóng vai trò quan trọng giúp các tổ chức, doanh nghiệp theo dõi, cập nhật và xử lý thông
tin một cách hiệu quả. Bài toán quản lý nhân viên không chỉ đơn thuần là lưu trữ dữ liệu, lOMoAR cPSD| 60729183
mà còn đòi hỏi khả năng xử lý linh hoạt như thêm, sửa, xóa và tìm kiếm thông tin nhanh chóng.
Trong đề tài này, chúng em lựa chọn danh sách liên kết đơn làm cấu trúc dữ liệu chính để
cài đặt chương trình quản lý nhân viên. Khác với mảng tĩnh có giới hạn kích thước và kém
linh hoạt khi thay đổi dữ liệu, danh sách liên kết đơn cho phép thao tác thêm hoặc xóa phần
tử một cách linh động mà không cần cấp phát lại bộ nhớ cho toàn bộ danh sách. Đây là một
ưu điểm phù hợp với các ứng dụng có dữ liệu biến động thường xuyên như hệ thống quản lý nhân sự.
Đề tài tập trung vào việc xây dựng một chương trình đơn giản nhưng đầy đủ chức năng cơ
bản của một hệ thống quản lý nhân viên, bao gồm: thêm nhân viên mới, hiển thị danh sách,
tìm kiếm, cập nhật và xóa thông tin nhân viên. Thông qua đó, đề tài không chỉ giúp rèn
luyện kỹ năng lập trình và tư duy thuật toán, mà còn giúp sinh viên hiểu rõ hơn về cách ứng
dụng cấu trúc dữ liệu trong thực tế.
2.2. Phân tích đề tài
2.2.1. Dữ liệu lưu trữ
Dữ liệu cần quản lý và lưu trữ về nhân viên gồm: •
Mã nhân viên (int): Là số định danh duy nhất cho mỗi nhân viên trong hệ thống,
giúp dễ dàng tìm kiếm và xử lý. •
Họ tên (char[]): Họ và tên đầy đủ của nhân viên, dùng để hiển thị và tìm kiếm. •
Lương (double): Mức lương cơ bản của nhân viên, phục vụ cho việc tính toán, thống kê và sắp xếp.
Bộ dữ liệu được lưu trong tệp văn bản tên nhanvien.txt lần lượt gồm các thông tin (mã nhân
viên, tên nhân viên,lương nhân viên) của 10 nhân viên như sau: 1,Bao,4000000.00 2,Thinh,7000000.00 3,Huy,10000000.00 4,c,5000000.00 5,z,3000000.00 6,d,5000000.00 lOMoAR cPSD| 60729183 7,k,5007000.00 8,y2,5500000.00 9,mm,5000000.00 10,cm,5600000.00
2.2.2. Cấu trúc dữ liệu
 Giới thiệu về danh sách liên kết đơn
Danh sách liên kết đơn (Singly Linked List) là một cấu trúc dữ liệu bao gồm nhiều nút
(node), trong đó mỗi nút chứa hai phần:
• Dữ liệu (data): Giá trị của phần tử trong danh sách.
• Con trỏ (next): Trỏ đến nút tiếp theo trong danh sách.
Danh sách liên kết đơn khác với mảng ở chỗ:
• Các phần tử không lưu trữ liên tiếp trong bộ nhớ.
• Không cần cấp phát kích thước cố định như mảng.
• Chèn/xóa phần tử nhanh hơn so với mảng.
 Cấu trúc danh sách liên kết đơn
Mỗi nút trong danh sách liên kết đơn được định nghĩa bằng một cấu trúc (struct) trong C/C++: struct Node {
int data; // Dữ liệu của nút
Node* next; // Con trỏ trỏ đến nút tiếp theo };
Head → [10 | *] → [20 | *] → [30 | *] → NULL
 Các thao tác trên danh sách liên kết đơn •
Khởi tạo danh sách liên kết đơn: Node* createNode(int value) { Node* newNode = new Node(); newNode->data = value; newNode->next = nullptr; return newNode; } lOMoAR cPSD| 60729183 •
Duyệt danh sách liên kết đơn: void traverse(Node* head) { Node* temp = head; while (temp != nullptr) { cout
<< temp->data << " → "; temp = temp->next; }
cout << "NULL" << endl; } •
Chèn phần tử vào danh sách liên kết
đơn: void insertAtHead(Node*& head, int value) { Node* newNode = createNode(value); newNode- >next = head; head = newNode; } •
Chèn vào cuối danh sách void
insertAtTail(Node*& head, int value) { Node* newNode = createNode(value); if (head == nullptr) { head = newNode; return; } Node* temp = head;
while (temp->next != nullptr) { temp = temp->next; } temp->next = newNode; } lOMoAR cPSD| 60729183
• Chèn vào vị trí bất kỳ: void insertAtPosition(Node*&
head, int value, int position) { if (position == 0) { insertAtHead(head, value); return; } Node* temp = head;
for (int i = 0; i < position - 1 && temp != nullptr; i++) temp = temp->next; if (temp == nullptr) return; Node* newNode = createNode(value); newNode->next = temp- >next; temp->next = newNode; } }
• Xóa phần tử trong danh sách liên kết đơn void deleteHead(Node*& head) { if (head == nullptr) return; Node* temp = head; head = head->next; delete temp; } • Xóa nút cuối cùng
void deleteTail(Node*& head) { if (head == nullptr) return;
if (head->next == nullptr) { delete head; head = nullptr; return; } Node* temp = head;
while (temp->next->next != nullptr) lOMoAR cPSD| 60729183 temp = temp->next; delete temp- >next; temp->next = nullptr; }
• Xóa nút tại vị trí bất kỳ void deleteAtPosition(Node*& head, int position) { if (head == nullptr) return; if (position == 0) { deleteHead(head); return; } Node* temp = head;
for (int i = 0; i < position - 1 && temp->next != nullptr; i++) temp = temp->next; if (temp->next == nullptr) return;
Node* toDelete = temp->next; temp-
>next = temp->next->next; delete toDelete; }
• Tìm kiếm phần tử trong danh sách
bool search(Node* head, int key) { Node* temp = head; while
(temp != nullptr) { if (temp->data == key) return true; temp = temp->next; } return false; }
 Ứng dụng của danh sách liên kết đơn
• Quản lý bộ nhớ động: Cấu trúc dữ liệu động giúp tiết kiệm bộ nhớ.
• Cấu trúc dữ liệu Stack và Queue: Stack (ngăn xếp), Queue (hàng đợi) có thể triển
khai bằng danh sách liên kết.
• Undo/Redo trong phần mềm: Sử dụng danh sách liên kết để lưu lịch sử thao tác.
• Hệ thống tệp tin: Hệ điều hành dùng danh sách liên kết để quản lý tệp.
• Đồ thị và cây: Danh sách liên kết giúp lưu trữ danh sách kề trong đồ thị. lOMoAR cPSD| 60729183
 Cấu trúc dữ liệu sử dụng trong bài toán đề tài struct NhanVien { int maNV; char hoTen[100]; double luong; struct NhanVien* next; };
2.2.3. Các chức năng  Hiển thị danh sách
• Lấy danh sách các điện thoại từ tệp nhanvien.txt ra danh sách đơn. Sau đó hiển
thị danh sách ra màn hình
 Thêm vào đầu danh sách
• Cho người dùng nhập vào: - Mã nhân viên - Tên nhân viên - Mức lương
• Sau đó cho thông tin nhân viên đó vào đầu danh sách
 Chèn vào cuối danh sách
• Cho người dùng nhập vào: - Mã nhân viên - Tên nhân viên - Mức lương
• Sau đó cho thông tin nhân viên đó vào cuối danh sách
 Xóa nhân viên theo mã nhân viên
• Cho người dùng nhập vào 1 mã nhân viên bất kỳ
• Sau đó xóa nhân viên có mã vừa nhập đi
 Xóa nhân viên theo tên nhân viên
• Cho người dùng nhập vào 1 tên nhân viên bất kỳ
• Sau đó xóa nhân viên có tên vừa nhập đi
 Đếm nhân viên lương < 5tr lOMoAR cPSD| 60729183
• Hiển thị thông tin danh sách nhân viên lương < 5tr  Tìm theo mã NV
• Cho người dùng nhập vào 1 mã nhân viên
• Nếu tìm thấy thì hiển thị thông tin nhân viên này
• Nếu không tìm thấy thì thông báo “Không tìm thấy nhân viên có mã …!”  Hien thi ds nhan vien
 Tim kiem theo khoang luong  Ghi danh sach vao tep  Tinh luong trung binh  Sap xep tang theo luong  Thoat
2.2.4. Thiết kế menu
---------CAC CHUC NANG QUAN LY NHAN VIEN--------- 1. Doc du lieu tu tep 2. Them vao dau danh sach 3. Chen vao cuoi danh sach 4. Xoa nhan vien theo ma 5. Xoa nhan vien theo ten
6. Dem nhan vien luong < 5tr 7. Tim theo ma NV 8. Hien thi ds nhan vien 9. Tim kiem theo khoang luong 10. Ghi danh sach vao tep 11. Tinh luong trung binh 12. Sap xep tang theo luong 13. Thoat Chon chuc nang: lOMoAR cPSD| 60729183
CHƯƠNG 3: PHÂN TÍCH CHƯƠNG TRÌNH
3.1. Cấu trúc dữ liệu struct NhanVien { int maNV; char hoTen[100; double luong; struct NhanVien* next };
maNV : Dùng để định danh và tìm kiếm nhân viên. hoTen : Lưu tên nhân viên.
luong : Lưu thông tin về mức lương. next : Trỏ đến phần tử tiếp theo trong danh
sách, hoặc NULL nếu là phần tử cuối.
Các thao tác đã cài đặt :
Thêm phần tử themDau(), themCuoi()
Thêm nhân viên vào đầu/cuối danh sách
Xóa phần tử xoaTheoMa(), xoaTheoTen() Xóa nhân viên dựa trên mã hoặc tên timTheoMa(),
Tìm nhân viên theo mã hoặc theo Tìm kiếm timTheoKhoang() khoảng lương
Duyệt & In inDanhSach()
Hiển thị toàn bộ danh sách
Đếm & Thống demLuongNhoHon(),
Đếm số nhân viên có lương dưới mức, tinhLuongTB() tính lương trung bình lOMoAR cPSD| 60729183
Sắp xếp danh sách theo lương tăng dần Sắp xếp sapXepLuong() (Bubble Sort) Lưu trữ ghiFile(), docFile()
Ghi và đọc danh sách từ file Giải phóng bộ
Giải phóng toàn bộ danh sách để tránh rò giaiPhong() nhớ rỉ bộ nhớ 3.2. Khởi tạo nút
struct NhanVien* taoNhanVien(int ma, char* ten, double luong) { struct
NhanVien* nv = (struct NhanVien*)malloc(sizeof(struct NhanVien)); nv-
>maNV = ma; strcpy(nv->hoTen, ten); nv->luong =
luong; nv->next = NULL; return nv; }
Việc dùng malloc() giúp cấp phát bộ nhớ động, cho phép danh sách mở rộng không giới
hạn số phần tử, không cần khai báo kích thước trước như mảng.
Mỗi nút đều chứa con trỏ next trỏ tới phần tử tiếp theo, tạo thành một chuỗi liên kết dễ dàng
chèn, xóa mà không cần dịch chuyển dữ liệu.
nv->next = NULL; đảm bảo nút mới được thêm vào luôn xác định được điểm kết thúc nếu
nó chưa liên kết với nút nào khác.
Hàm taoNhanVien() có thể được gọi ở nhiều nơi (thêm đầu, thêm cuối) mà không cần viết lại mã cấp phát.
3.3. Nhập dữ liệu
 Chức năng nhập dữ liệu cho phép người dùng thêm các nhân viên vào danh sách liên kết
• Nhập từ bàn phím: người dùng nhập thủ công thông tin nhân viên.
• Đọc từ tệp (file): chương trình tự động nạp danh sách nhân viên từ tệp nhanvien.txt.  Modul mã nguồn • Nhập từ bàn phím : if (nguon == 1) { int soLuong; lOMoAR cPSD| 60729183
printf("Nhap so nhan vien: ");
scanf("%d", &soLuong); getchar(); for
(int i = 0; i < soLuong; i++) {
printf("Nhan vien %d:\n", i + 1);
printf("Ma: "); scanf("%d", &ma); getchar();
printf("Ten: "); fgets(ten, 100, stdin); ten[strcspn(ten, "\n")] = 0;
printf("Luong: "); scanf("%lf", &luong); themCuoi(&ds, ma, ten, luong); } }
• Đọc từ file(docFile())
void docFile(struct NhanVien** head, const char* filename) {
FILE* f = fopen(filename, "r"); if (!f) {
printf("Khong tim thay tep!\n"); return; } int ma; char ten[100]; double luong;
while (fscanf(f, "%d,%99[^,],%lf\n", &ma, ten, &luong) == 3)
themCuoi(head, ma, ten, luong); fclose(f);
printf("Da doc danh sach tu tep.\n"); }  Màn hình hiển thị
----- CHON NGUON DU LIEU ----- 1.
Nhap danh sach nhan vien bang tay
2. Doc danh sach nhan vien tu tep Lua chon: 1 Nhap so nhan vien: 2 lOMoAR cPSD| 60729183 Nhan vien 1: Ma: 101 Ten: Bao Luong: 7000000 Nhan vien 2: Ma: 102 Ten: Thinh Luong: 8500000
 Nếu chọn đọc từ file:
----- CHON NGUON DU LIEU -----
1. Nhap danh sach nhan vien bang tay
2. Doc danh sach nhan vien tu tep Lua chon: 2 Da doc danh sach tu tep.
3.4. Hiển thị danh sách
Chức năng hiển thị danh sách giúp người dùng xem toàn bộ thông tin của nhân viên đang
được lưu trong danh sách liên kết đơn.
 Dữ liệu được in ra theo định dạng: Ma: | Ten: | Luong:  Modul mã nguồn :
void inDanhSach(struct NhanVien* head) { if (!head) { printf("Danh sach rong!\n"); return; }
printf("\nDanh sach nhan vien:\n"); while (head) {
printf("Ma: %d | Ten: %s | Luong: %.2lf\n", lOMoAR cPSD| 60729183
head->maNV, head->hoTen, head->luong); head = head->next; } }
3.5. Thêm vào đầu danh sách  Mô tả chức năng •
Chức năng thêm vào đầu danh sách cho phép người dùng nhập thông tin một
nhân viên mới và chèn nút đó vào đầu danh sách liên kết đơn. •
Khi thực hiện, nút mới sẽ trở thành nút đầu tiên và trỏ đến nút cũ trước đó. •
Giúp thêm nhanh một nhân viên mà không cần duyệt hết danh sách.  Modul mã nguồn:
void themDau(struct NhanVien** head, int ma, char* ten, double luong) {
struct NhanVien* nv = taoNhanVien(ma, ten, luong); nv->next = *head; *head = nv; }
3.6. Chèn vào cuối danh sách  Mô tả chức năng •
Chức năng chèn vào cuối danh sách cho phép thêm một nhân viên mới vào vị trí
cuối cùng của danh sách liên kết. •
Chương trình sẽ duyệt từ đầu đến cuối danh sách, tìm nút cuối (có next = NULL)
và gắn nút mới vào đó. •
Nếu danh sách đang rỗng (head == NULL), nút mới sẽ trở thành nút đầu.  Modul mã nguồn:
void themCuoi(struct NhanVien** head, int ma, char* ten, double luong) {
struct NhanVien* nv = taoNhanVien(ma, ten, luong); if (*head ==
NULL) { // Nếu danh sách rỗng *head = nv; } else {
struct NhanVien* temp = *head; lOMoAR cPSD| 60729183
while (temp->next != NULL) // Duyệt đến nút cuối temp = temp->next;
temp->next = nv; // Gắn nút mới vào cuối } }
3.7. Xóa nhân viên theo mã  Mô tả chức năng •
Chức năng xóa nhân viên theo mã cho phép người dùng nhập vào một mã nhân viên (maNV). •
Chương trình sẽ duyệt qua danh sách liên kết, tìm nút có maNV trùng khớp. •
Nếu tìm thấy, nút đó sẽ bị gỡ ra khỏi danh sách và bộ nhớ của nó được giải phóng. •
Nếu không tìm thấy, chương trình thông báo "Không tìm thấy mã...".  Modul mã nguồn:
void xoaTheoMa(struct NhanVien** head, int ma) {
struct NhanVien *temp = *head, *prev = NULL;
while (temp && temp->maNV != ma) { prev = temp; temp = temp->next; } if (!temp) {
printf("Khong tim thay ma %d\n", ma); return; } if (!prev) *head = temp->next; else
prev->next = temp->next; free(temp);
printf("Da xoa nhan vien co ma %d\n", ma); lOMoAR cPSD| 60729183 }
3.8. Xóa nhân viên theo tên  Mô tả chức năng •
Chức năng này cho phép người dùng nhập vào tên nhân viên cần xóa. •
Chương trình sẽ duyệt danh sách liên kết để tìm nhân viên có hoTen trùng khớp. •
Nếu tìm thấy, nút đó bị xóa khỏi danh sách và giải phóng bộ nhớ. •
Nếu không tìm thấy, hiển thị thông báo "Không tìm thấy tên...".  Modul mã nguồn:
void xoaTheoTen(struct NhanVien** head, char* ten) {
struct NhanVien *temp = *head, *prev = NULL;
while (temp && strcmp(temp->hoTen, ten) != 0) {
prev = temp; temp = temp->next; } if (!temp) {
printf("Khong tim thay ten %s\n", ten); return; } if (!prev) *head = temp->next; else
prev->next = temp->next; free(temp);
printf("Da xoa nhan vien ten %s\n", ten); }
3.9. Đếm số lượng nhân viên có lương dưới 5 triệu  Mô tả chức năng •
Chức năng này duyệt qua toàn bộ danh sách liên kết, đếm số nhân viên có luong nhỏ hơn 5.000.000. •
Kết quả được trả về là một số nguyên và in ra màn hình. lOMoAR cPSD| 60729183
 Modul mã nguồn: int demLuongNhoHon(struct NhanVien* head,
double muc) { int dem = 0; while (head) { if (head->luong <
muc) dem++; head = head->next; } return dem; }
3.10. Tìm kiếm nhân viên theo mã NV  Mô tả chức năng •
Chức năng này cho phép người dùng nhập vào mã nhân viên (maNV) cần tìm. •
Chương trình sẽ duyệt danh sách liên kết để so sánh mã từng nhân viên. •
Nếu tìm thấy, in ra thông tin nhân viên. Nếu không tìm thấy, thông báo không tồn tại.  Modul mã nguồn:
void timTheoMa(struct NhanVien* head, int ma) { while (head) { if (head->maNV == ma) {
printf("Tim thay: %d - %s - %.2lf\n", head->maNV, head->hoTen, head- >luong); return; } head = head->next; }
printf("Khong tim thay nhan vien co ma %d\n", ma); }
3.11. Tính lương trung bình của danh sách nhân viên  Mô tả chức năng •
Chức năng này sẽ duyệt toàn bộ danh sách liên kết, cộng dồn lương của các nhân
viên và đếm số lượng nhân viên. •
Sau đó tính lương trung bình = (Tổng lương) / (Số lượng nhân viên). •
Nếu danh sách rỗng, kết quả trả về là 0.