



















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,  kê  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.