lOMoARcPSD| 60729183
BỘ GIÁO DỤC VÀ ĐÀO TẠO
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
ĐỀ TÀI 1: ỨNG DỤNG DANH SÁCH LIÊN KẾT ĐƠN
VÀO QUẢN LÝ DANH SÁCH SỐ NGUYÊN
Sinh viên thực
hiện
Lớp
Khóa
Lê Khả Anh
DCCNTT14.C.1
K14
Trần Thanh Thế
DCCNTT14.C.1
K14
Phạm Tùng Dương
DCCNTT14.C.1
K14
Nguyễn Văn Hiếu
DCCNTT14.C.1
K14
DCCNTT14.C.1
K14
Bắc Ninh, năm 2024
lOMoARcPSD| 60729183
MỤC LỤC
CHƯƠNG 1. TỔNG QUAN VỀ ĐỀ TÀI.......................................................................2
1.1. Giới thiệu....................................................................................................................2
1.2. Phân công công việc...................................................................................................3
CHƯƠNG 2. LƯU ĐỒ THUẬT TOÁN VÀ BỘ MẪU DỮ LIỆU................................4
2.1. Lưu đồ thuật toán........................................................................................................4
2.1.1. Lưu đồ thuật toán nhập một danh sách cho đến khi nhập dấu "$"...........................4
2.1.2. Lưu đồ thuật toán sắp xếp danh sách theo chiều tăng dần của điểm Toán..............5
2.1.3. Lưu đồ thuật toán sắp xếp danh sách theo chiều tăng dần của điểm trung bình......6
2.1.4. Lưu đồ thuật toán tìm sinh viên có điểm trung bình Max/Min.................................7
2.1.5. Lưu đồ thuật toán in ra môn học có điểm trung bình Max/Min...............................8
2.2. Bộ dữ liệu mẫu............................................................................................................9
CHƯƠNG 3. CÀI ĐẶT..................................................................................................10
3.1. Module 1: Nhập 1 danh sách cho đến khi nhập dấu “$” vo tên đối tượng...............10
3.2. Module 2. Sắp xếp danh sách theo chiều tăng dn của điểm toán.............................12
3.3. Module 3. Sắp xếp danh sách theo chiều tăng dn của điểm trung bình...................13
3.4. Module 4. Tìm sinh viên có điểm trung bình Max/Min............................................15
3.5. Module 5 . In ra môn học có điểm trung bình Max/Min...........................................16
3.3. Kết quả......................................................................................................................18
KẾT LUẬN.....................................................................................................................22
1. Kết quả đạt được..........................................................................................................22
2. Hướng phát triển..........................................................................................................22
DANH MỤC TÀI LIỆU THAM KHẢO......................................................................24
lOMoARcPSD| 60729183
CHƯƠNG 1. TỔNG QUAN VỀ ĐỀ TÀI
1.1. Giới thiệu
- Yêu cu của đề ti
Đề ti "Ứng dụng danh sách liên kết đơn vo quản lý danh sách số" đặt ra mục tiêu
áp dụng cấu trúc dữ liệu danh sách liên kết đơn để quản các số nguyên trong một hệ
thống. Đây l một phn của việc học v áp dụng cấu trúc dữ liệu trong lập trình, nơi m
các sinh viên có cơ hội thực hnh các khái niệm lý thuyết thnh thạo v áp dụng chúng vo
các bi toán thực tế.
Đu tiên, trong đề ti ny, quá trình bắt đu bằng việc tạo ra một danh sách số từ dữ
liệu nhập vo từ người dùng. Quá trình nhập sẽ tiếp tục cho đến khi người dùng nhập
tự "#" để kết thúc việc nhập liệu. Mỗi số nguyên được nhập sẽ được thêm vo cuối danh
sách, tạo thnh một cấu trúc dữ liệu đơn giản nhưng mạnh mẽ để quản lý dữ liệu.
Sau khi tạo danh sách ban đu, người dùng có thể lựa chọn vị trí muốn thêm một số
nguyên mới vo. Điều ny cho phép họ thực hiện các thao tác như chèn một số vo đu
danh sách, cuối danh sách hoặc bất kỳ vị trí no m họ mong muốn, tăng tính linh hoạt v
sự kiểm soát của người dùng đối với dữ liệu.
Một yêu cu quan trọng trong đề ti l đếm số lượng các phn tử trong danh sách
giá trị bằng một số nguyên k cho trước (k khác 0). Đây l một ththách không chỉ về
mặt thuật toán m n yêu cu người thực hiện đảm bảo tính chính xác của kết quả v hiệu
suất của thuật toán đối với tập dữ liệu lớn.
Một trong những bi toán thú vị khác l kiểm tra xem trong danh sách có tồn tại ba
số chẵn dương liên tiếp hay không. Nếu có, chương trình sẽ xuất ra vị trí của các số ny
trong danh sách. Đây l một ví dụ điển hình cho việc áp dụng các kỹ thuật duyệt danh sách
v kiểm tra điều kiện.
Đối với các số chẵn dương trong danh sách, yêu cu l đếm số lượng chúng v tính
trung bình cộng giá trị của chúng. Đây l một phn của quá trình thống kê v phân tích dữ
liệu, nâng cao khả năng phân tích v xử lý thông tin của người lập trình.
lOMoARcPSD| 60729183
Cuối cùng, chương trình sẽ hiển thị một số thông tin đặc biệt về danh sách số như
số dương đu tiên, số âm cuối cùng, dãy số dương tăng dn v dãy số âm giảm dn. Điều
ny giúp người dùng có cái nhìn tổng quát v chi tiết về cấu trúc v nội dung của danh sách
m họ đang lm việc.
.
1.2. Phân công công việc
Bảng 1: Bảng phân công công việc
STT
Tên đầu
việc
Công việc
chia đến nhỏ
nhất
Người thực
hiện
Kết
luận
1
1.1
- Tạo danh
sách
số
- quá trình
nhập sẽ dừng lại
khi nhập dấu “#”
Nguyên Van
A
2
3
4
5
CHƯƠNG 2. LƯU ĐỒ THUẬT TOÁN VÀ BỘ MẪU DỮ LIỆU
2.1. Lưu đồ thuật toán
2.1.1. Lưu đồ thuật toán tạo danh sách số, quá trình nhập sẽ dừng lại khi
nhập dấu “#”.
lOMoARcPSD| 60729183
2.1.2. Lưu đồ thuật toán thêm môt phn tử vào danh sách, vị trí thêm và
do ta lựa chn.
lOMoARcPSD| 60729183
2.1.3. Lưu đồ thuật toán nhập vào môt số k ( 0), đếm xem trong dãy
bao nhiêu số giá trị = k. Số lượng các số tìm được chia hết cho 3 hay không?
lOMoARcPSD| 60729183
2.1.4. Lưu đồ thuật toán kiểm tra xem trong dãy có 3 số chẵn dương đứng
cạnh nhau hay không? Nếu có hãy in ra vị trí của các số này.
lOMoARcPSD| 60729183
2.1.5. Lưu đồ thuật toán đếm scác phn tử giá trị số chẵn dương. Tính
trung bình công các số.
lOMoARcPSD| 60729183
2.1.6. Lưu đồ thuật toán đếm scác phn tử giá trị số chẵn dương. Tính
trung bình công các số.
lOMoARcPSD| 60729183
2.2. Bộ dữ liệu mẫu
Bảng 2: Bảng dữ liệu mẫu
Bộ
Input 1
Input 2
Input 3
Mong muốn
Kết quả
chương
trình
Tính
đúng
1
Nhap lua
chon: 1
Nhap ma can
bo (<= 0 de
dung): 1
Nhap
ho
dem:
3
Ma can bo: 1
Ho dem: 3
Ten can bo: 2
Ma can bo:
1
Ho dem: 3
Ten can bo:
2
Đúng
lOMoARcPSD| 60729183
2
1,2,3,4,5
0
0
Kets qua hien thi
cau 1 mong muon
la : 1,2,3,4,5
1,2,3,4,5
Đúng
3
-5
-10
-3
-3
-3
Đúng
4
30
25
35
35
35
Đúng
5
12
18
15
18
18
Đúng
6
-8
-12
-6
-6
-6
Đúng
7
100
50
75
100
100
Đúng
8
7
7
7
7
7
Đúng
9
21
21
21
21
21
Đúng
10
-15
-20
-10
-10
-10
Đúng
CHƯƠNG 3. CÀI ĐẶT
3.1. Module 1: . Tạo danh sách số, quá trình nhập sẽ dừng lại khi nhập dấu
“#”.
lOMoARcPSD| 60729183
case 1:
// 1.1. Tạo danh sách số, quá trình nhập sẽ dừng lại khi nhập dấu
“#”. printf("Nhap cac so nguyen (ket thuc bang #):\n");
while (1) { scanf("%s", nhap); if (nhap[0] == '#') {
break;
}
giaTri = atoi(nhap);
Node* nutMoi = taoNutMoi(giaTri);
if (head == NULL) { head =
nutMoi; tail = nutMoi;
} else {
tail->next = nutMoi;
tail = nutMoi;
}
}
break;
3.2. Module 2 Thêm môt p ần tử vào danh sách, vị trí thêm vào do ta lựa
chọn.
// Định nghĩa cấu trúc của một nút trong danh sách liên kết đơn
typedef struct Node {
lOMoARcPSD| 60729183
int data; struct
Node* next; } Node;
// Hm tạo một nút mới
Node* taoNutMoi(int giaTri) {
Node* nutMoi =
(Node*)malloc(sizeof(Node)); nutMoi->data =
giaTri; nutMoi->next = NULL; return
nutMoi; }
// Hm thêm một phn tử vo vị trí bất kỳ trong danh
sách void themPhanTu(Node** head, int giaTri, int viTri)
{ Node* nutMoi = taoNutMoi(giaTri); if (viTri ==
0) { nutMoi->next = *head; *head = nutMoi;
return;
}
Node* hienTai = *head; for (int i = 0; i < viTri - 1
&& hienTai != NULL; i++) { hienTai = hienTai-
>next;
}
if (hienTai != NULL) { nutMoi-
>next = hienTai->next; hienTai-
>next = nutMoi;
} else {
lOMoARcPSD| 60729183
printf("Vi tri vuot qua danh sach.\n"); free(nutMoi);
}
}
3.3. Module 3. Nhập vào môt số k ( 0), đếm xem trong dãy có bao nhiêu số
có giá trị = k. Số lượng các số tìm được có chia hết cho 3 hay không?
// Hm sắp xếp danh sách liên kết kép sử dụng Bubble Sort
// Hm nhận tham số l con trỏ hm so sánh để sắp xếp theo tiêu chí khác nhau
void sap_xep(int (*compare)(SinhVien *, SinhVien *))
{ if (dau == NULL || dau->sau ==
NULL)
return;
int swapped;
do
{
swapped = 0;
SinhVien *ptr1 = dau;
SinhVien *ptr2 = dau->sau;
while (ptr2 != NULL)
{
if (compare(ptr1, ptr2) > 0)
{
swap(ptr1, ptr2);
// Cập nhật con trỏ trước v sau sau khi swap
if (ptr1->truoc != NULL)
lOMoARcPSD| 60729183
ptr1->truoc->sau =
ptr1; else dau
= ptr1;
if (ptr2->sau != NULL)
ptr2->sau->truoc = ptr2;
SinhVien *temp = ptr1;
ptr1 = ptr2; ptr2 =
temp; swapped = 1;
}
ptr1 = ptr1->sau;
ptr2 = ptr2->sau;
}
} while (swapped);
}
// Hm so sánh điểm trung bình của hai sinh viên int
compare_diem_trung_binh(SinhVien *a, SinhVien *b)
{ return (lay_diem_trung_binh(a) > lay_diem_trung_binh(b)) ? 1 : -
1; }
3.4. Module 4. Kiểm tra xem trong dãy có 3 số chẵn dương đứng cạnh nhau
hay không? Nếu có hãy in ra vị trí của các số này.
// Hm tìm sinh viên có điểm trung bình cao nhất v thấp nhất
void tim_sinh_vien_diem_max_min()
lOMoARcPSD| 60729183
{ if (dau ==
NULL)
return;
SinhVien *sv_max = dau, *sv_min = dau;
float max_tb = lay_diem_trung_binh(dau), min_tb =
lay_diem_trung_binh(dau);
for (SinhVien *i = dau->sau; i != NULL; i = i->sau)
{
float tb = lay_diem_trung_binh(i);
if (tb > max_tb)
{
max_tb = tb;
sv_max = i;
} if (tb <
min_tb)
{
min_tb = tb;
sv_min = i;
}
}
printf("Sinh vien co diem trung binh cao nhat: %s (%.2f)\n", sv_max->ten,
max_tb); printf("Sinh vien co diem trung binh thap nhat: %s (%.2f)\n", sv_min->ten,
min_tb);
}
lOMoARcPSD| 60729183
3.5. Module 5 . Đếm số các phần tử có giá trị là số chẵn dương. Tính trung
bình công các số.
// Hm tìm môn học có điểm trung bình cao nhất v thấp nhất
void tim_mon_hoc_diem_max_min()
{
if (dau == NULL)
{
return;
}
float diem_mon_hoc[MAX_MONHOC] = {0}; // Mùng lưu tổng điểm của từng môn
int so_luong_sinh_vien_mon_hoc[MAX_MONHOC] = {0}; // Mảng lưu số lượng sinh
viên học từng môn
// Duyệt qua danh sách sinh viên
for (SinhVien *sv = dau; sv != NULL; sv = sv->sau)
{
// Duyệt qua các môn học của mỗi sinh viên
for (int i = 0; i < MAX_MONHOC; i++)
{
diem_mon_hoc[i] += sv->monhoc[i].diem;
so_luong_sinh_vien_mon_hoc[i]++;
}
}
float max_tb = -1, min_tb = 101;
int mon_max = 0, mon_min = 0;
// Tìm môn học có điểm trung bình cao nhất v thấp nhất
for (int i = 0; i < MAX_MONHOC; i++)
{
if (so_luong_sinh_vien_mon_hoc[i] > 0)
lOMoARcPSD| 60729183
{
float tb = diem_mon_hoc[i] / so_luong_sinh_vien_mon_hoc[i];
if (tb > max_tb)
{
max_tb = tb;
mon_max = i;
}
if (tb < min_tb)
{
min_tb = tb;
mon_min = i;
}
}
}
printf("Mon hoc co diem trung binh cao nhat: %s (%.2f)\n", dau-
>monhoc[mon_max].ten, max_tb);
printf("Mon hoc co diem trung binh thap nhat: %s (%.2f)\n",
dau>monhoc[mon_min].ten, min_tb); }
3.6. Module 6 Hiển thị số dương đầu danh sách, số âm cuối danh sách, dãy số
dương tăng dần, dãy số âm giảm dần.
// Hm hiển thị danh sách void
hienThiDanhSach(Node* head) {
printf("Danh sach: "); while (head
!= NULL) { printf("%d ", head-
>data); head = head->next;
}
printf("\n");
}
lOMoARcPSD| 60729183
3.3. Kết quả
- Mebu lựa chọn
- Lựa chọn 1
- Lựa chọn 2

Preview text:

lOMoAR cPSD| 60729183
BỘ GIÁO DỤC VÀ ĐÀO TẠO
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
ĐỀ TÀI 1: ỨNG DỤNG DANH SÁCH LIÊN KẾT ĐƠN
VÀO QUẢN LÝ DANH SÁCH SỐ NGUYÊN Sinh viên thực Lớp Khóa hiện Lê Khả Anh DCCNTT14.C.1 K14 Trần Thanh Thế DCCNTT14.C.1 K14 Phạm Tùng Dương DCCNTT14.C.1 K14 Nguyễn Văn Hiếu DCCNTT14.C.1 K14 DCCNTT14.C.1 K14 Bắc Ninh, năm 2024 lOMoAR cPSD| 60729183 MỤC LỤC
CHƯƠNG 1. TỔNG QUAN VỀ ĐỀ TÀI.......................................................................2
1.1. Giới thiệu....................................................................................................................2
1.2. Phân công công việc...................................................................................................3
CHƯƠNG 2. LƯU ĐỒ THUẬT TOÁN VÀ BỘ MẪU DỮ LIỆU................................4
2.1. Lưu đồ thuật toán........................................................................................................4
2.1.1. Lưu đồ thuật toán nhập một danh sách cho đến khi nhập dấu "$"...........................4
2.1.2. Lưu đồ thuật toán sắp xếp danh sách theo chiều tăng dần của điểm Toán..............5
2.1.3. Lưu đồ thuật toán sắp xếp danh sách theo chiều tăng dần của điểm trung bình......6
2.1.4. Lưu đồ thuật toán tìm sinh viên có điểm trung bình Max/Min.................................7
2.1.5. Lưu đồ thuật toán in ra môn học có điểm trung bình Max/Min...............................8
2.2. Bộ dữ liệu mẫu............................................................................................................9
CHƯƠNG 3. CÀI ĐẶT..................................................................................................10
3.1. Module 1: Nhập 1 danh sách cho đến khi nhập dấu “$” vào tên đối tượng...............10
3.2. Module 2. Sắp xếp danh sách theo chiều tăng dần của điểm toán.............................12
3.3. Module 3. Sắp xếp danh sách theo chiều tăng dần của điểm trung bình...................13
3.4. Module 4. Tìm sinh viên có điểm trung bình Max/Min............................................15
3.5. Module 5 . In ra môn học có điểm trung bình Max/Min...........................................16
3.3. Kết quả......................................................................................................................18
KẾT LUẬN.....................................................................................................................22
1. Kết quả đạt được..........................................................................................................22
2. Hướng phát triển..........................................................................................................22
DANH MỤC TÀI LIỆU THAM KHẢO......................................................................24 lOMoAR cPSD| 60729183
CHƯƠNG 1. TỔNG QUAN VỀ ĐỀ TÀI 1.1. Giới thiệu
- Yêu cầu của đề tài
Đề tài "Ứng dụng danh sách liên kết đơn vào quản lý danh sách số" đặt ra mục tiêu
áp dụng cấu trúc dữ liệu danh sách liên kết đơn để quản lý các số nguyên trong một hệ
thống. Đây là một phần của việc học và áp dụng cấu trúc dữ liệu trong lập trình, nơi mà
các sinh viên có cơ hội thực hành các khái niệm lý thuyết thành thạo và áp dụng chúng vào các bài toán thực tế.
Đầu tiên, trong đề tài này, quá trình bắt đầu bằng việc tạo ra một danh sách số từ dữ
liệu nhập vào từ người dùng. Quá trình nhập sẽ tiếp tục cho đến khi người dùng nhập ký
tự "#" để kết thúc việc nhập liệu. Mỗi số nguyên được nhập sẽ được thêm vào cuối danh
sách, tạo thành một cấu trúc dữ liệu đơn giản nhưng mạnh mẽ để quản lý dữ liệu.
Sau khi tạo danh sách ban đầu, người dùng có thể lựa chọn vị trí muốn thêm một số
nguyên mới vào. Điều này cho phép họ thực hiện các thao tác như chèn một số vào đầu
danh sách, cuối danh sách hoặc bất kỳ vị trí nào mà họ mong muốn, tăng tính linh hoạt và
sự kiểm soát của người dùng đối với dữ liệu.
Một yêu cầu quan trọng trong đề tài là đếm số lượng các phần tử trong danh sách
có giá trị bằng một số nguyên k cho trước (k khác 0). Đây là một thử thách không chỉ về
mặt thuật toán mà còn yêu cầu người thực hiện đảm bảo tính chính xác của kết quả và hiệu
suất của thuật toán đối với tập dữ liệu lớn.
Một trong những bài toán thú vị khác là kiểm tra xem trong danh sách có tồn tại ba
số chẵn dương liên tiếp hay không. Nếu có, chương trình sẽ xuất ra vị trí của các số này
trong danh sách. Đây là một ví dụ điển hình cho việc áp dụng các kỹ thuật duyệt danh sách
và kiểm tra điều kiện.
Đối với các số chẵn dương trong danh sách, yêu cầu là đếm số lượng chúng và tính
trung bình cộng giá trị của chúng. Đây là một phần của quá trình thống kê và phân tích dữ
liệu, nâng cao khả năng phân tích và xử lý thông tin của người lập trình. lOMoAR cPSD| 60729183
Cuối cùng, chương trình sẽ hiển thị một số thông tin đặc biệt về danh sách số như
số dương đầu tiên, số âm cuối cùng, dãy số dương tăng dần và dãy số âm giảm dần. Điều
này giúp người dùng có cái nhìn tổng quát và chi tiết về cấu trúc và nội dung của danh sách mà họ đang làm việc. .
1.2. Phân công công việc
Bảng 1: Bảng phân công công việc Công việc Tên đầu Người thực Kết STT chia đến nhỏ Đánh giá việc hiện luận nhất - Tạo danh sách số Nguyên Van 1 1.1 - quá trình A nhập sẽ dừng lại khi nhập dấu “#” 2 3 4 5
CHƯƠNG 2. LƯU ĐỒ THUẬT TOÁN VÀ BỘ MẪU DỮ LIỆU
2.1. Lưu đồ thuật toán
2.1.1. Lưu đồ thuật toán tạo danh sách số, quá trình nhập sẽ dừng lại khi
nhập dấu “#”. lOMoAR cPSD| 60729183
2.1.2. Lưu đồ thuật toán thêm môt phần tử vào danh sách, vị trí thêm vàọ
do ta lựa chọn. lOMoAR cPSD| 60729183
2.1.3. Lưu đồ thuật toán nhập vào môt số k (ḳ 0), đếm xem trong dãy có
bao nhiêu số có giá trị = k. Số lượng các số tìm được có chia hết cho 3 hay không? lOMoAR cPSD| 60729183
2.1.4. Lưu đồ thuật toán kiểm tra xem trong dãy có 3 số chẵn dương đứng
cạnh nhau hay không? Nếu có hãy in ra vị trí của các số này. lOMoAR cPSD| 60729183
2.1.5. Lưu đồ thuật toán đếm số các phần tử có giá trị là số chẵn dương. Tính
trung bình công các số.̣ lOMoAR cPSD| 60729183
2.1.6. Lưu đồ thuật toán đếm số các phần tử có giá trị là số chẵn dương. Tính
trung bình công các số.̣ lOMoAR cPSD| 60729183
2.2. Bộ dữ liệu mẫu
Bảng 2: Bảng dữ liệu mẫu Bộ Input 1 Input 2 Input 3 Mong muốn Kết quả Tính chương đúng trình 1 Nhap lua Nhap ma can Nhap Ma can bo: 1 Ma can bo: Đúng chon: 1 bo (<= 0 de ho Ho dem: 3 1 dung): 1 dem: Ten can bo: 2 Ho dem: 3 3 Ten can bo: 2 lOMoAR cPSD| 60729183 2 1,2,3,4,5 0 0 Kets qua hien thi 1,2,3,4,5 Đúng cau 1 mong muon la : 1,2,3,4,5 3 -5 -10 -3 -3 -3 Đúng 4 30 25 35 35 35 Đúng 5 12 18 15 18 18 Đúng 6 -8 -12 -6 -6 -6 Đúng 7 100 50 75 100 100 Đúng 8 7 7 7 7 7 Đúng 9 21 21 21 21 21 Đúng 10 -15 -20 -10 -10 -10 Đúng
CHƯƠNG 3. CÀI ĐẶT
3.1. Module 1: . Tạo danh sách số, quá trình nhập sẽ dừng lại khi nhập dấu “#”. lOMoAR cPSD| 60729183 case 1:
// 1.1. Tạo danh sách số, quá trình nhập sẽ dừng lại khi nhập dấu
“#”. printf("Nhap cac so nguyen (ket thuc bang #):\n");
while (1) { scanf("%s", nhap); if (nhap[0] == '#') { break; } giaTri = atoi(nhap);
Node* nutMoi = taoNutMoi(giaTri); if (head == NULL) { head = nutMoi; tail = nutMoi; } else { tail->next = nutMoi; tail = nutMoi; } } break;
3.2. Module 2 Thêm môt pḥ
ần tử vào danh sách, vị trí thêm vào do ta lựa chọn.
// Định nghĩa cấu trúc của một nút trong danh sách liên kết đơn typedef struct Node { lOMoAR cPSD| 60729183 int data; struct Node* next; } Node;
// Hàm tạo một nút mới Node* taoNutMoi(int giaTri) { Node* nutMoi =
(Node*)malloc(sizeof(Node)); nutMoi->data =
giaTri; nutMoi->next = NULL; return nutMoi; }
// Hàm thêm một phần tử vào vị trí bất kỳ trong danh
sách void themPhanTu(Node** head, int giaTri, int viTri)
{ Node* nutMoi = taoNutMoi(giaTri); if (viTri ==
0) { nutMoi->next = *head; *head = nutMoi; return; }
Node* hienTai = *head; for (int i = 0; i < viTri - 1
&& hienTai != NULL; i++) { hienTai = hienTai- >next; }
if (hienTai != NULL) { nutMoi-
>next = hienTai->next; hienTai- >next = nutMoi; } else { lOMoAR cPSD| 60729183
printf("Vi tri vuot qua danh sach.\n"); free(nutMoi); } }
3.3. Module 3. Nhập vào môt số k (ḳ 0), đếm xem trong dãy có bao nhiêu số
có giá trị = k. Số lượng các số tìm được có chia hết cho 3 hay không?
// Hàm sắp xếp danh sách liên kết kép sử dụng Bubble Sort
// Hàm nhận tham số là con trỏ hàm so sánh để sắp xếp theo tiêu chí khác nhau
void sap_xep(int (*compare)(SinhVien *, SinhVien *))
{ if (dau == NULL || dau->sau == NULL) return; int swapped; do { swapped = 0; SinhVien *ptr1 = dau; SinhVien *ptr2 = dau->sau; while (ptr2 != NULL) {
if (compare(ptr1, ptr2) > 0) { swap(ptr1, ptr2);
// Cập nhật con trỏ trước và sau sau khi swap if (ptr1->truoc != NULL) lOMoAR cPSD| 60729183 ptr1->truoc->sau = ptr1; else dau = ptr1; if (ptr2->sau != NULL)
ptr2->sau->truoc = ptr2; SinhVien *temp = ptr1; ptr1 = ptr2; ptr2 = temp; swapped = 1; } ptr1 = ptr1->sau; ptr2 = ptr2->sau; } } while (swapped); }
// Hàm so sánh điểm trung bình của hai sinh viên int
compare_diem_trung_binh(SinhVien *a, SinhVien *b)
{ return (lay_diem_trung_binh(a) > lay_diem_trung_binh(b)) ? 1 : - 1; }
3.4. Module 4. Kiểm tra xem trong dãy có 3 số chẵn dương đứng cạnh nhau
hay không? Nếu có hãy in ra vị trí của các số này.
// Hàm tìm sinh viên có điểm trung bình cao nhất và thấp nhất
void tim_sinh_vien_diem_max_min() lOMoAR cPSD| 60729183 { if (dau == NULL) return;
SinhVien *sv_max = dau, *sv_min = dau;
float max_tb = lay_diem_trung_binh(dau), min_tb = lay_diem_trung_binh(dau);
for (SinhVien *i = dau->sau; i != NULL; i = i->sau) {
float tb = lay_diem_trung_binh(i); if (tb > max_tb) { max_tb = tb; sv_max = i; } if (tb < min_tb) { min_tb = tb; sv_min = i; } }
printf("Sinh vien co diem trung binh cao nhat: %s (%.2f)\n", sv_max->ten,
max_tb); printf("Sinh vien co diem trung binh thap nhat: %s (%.2f)\n", sv_min->ten, min_tb); } lOMoAR cPSD| 60729183
3.5. Module 5 . Đếm số các phần tử có giá trị là số chẵn dương. Tính trung
bình công các số.̣
// Hàm tìm môn học có điểm trung bình cao nhất và thấp nhất
void tim_mon_hoc_diem_max_min() { if (dau == NULL) { return; }
float diem_mon_hoc[MAX_MONHOC] = {0}; // Mùng lưu tổng điểm của từng môn
int so_luong_sinh_vien_mon_hoc[MAX_MONHOC] = {0}; // Mảng lưu số lượng sinh viên học từng môn
// Duyệt qua danh sách sinh viên
for (SinhVien *sv = dau; sv != NULL; sv = sv->sau) {
// Duyệt qua các môn học của mỗi sinh viên
for (int i = 0; i < MAX_MONHOC; i++) {
diem_mon_hoc[i] += sv->monhoc[i].diem;
so_luong_sinh_vien_mon_hoc[i]++; } }
float max_tb = -1, min_tb = 101; int mon_max = 0, mon_min = 0;
// Tìm môn học có điểm trung bình cao nhất và thấp nhất
for (int i = 0; i < MAX_MONHOC; i++) {
if (so_luong_sinh_vien_mon_hoc[i] > 0) lOMoAR cPSD| 60729183 {
float tb = diem_mon_hoc[i] / so_luong_sinh_vien_mon_hoc[i]; if (tb > max_tb) { max_tb = tb; mon_max = i; } if (tb < min_tb) { min_tb = tb; mon_min = i; } } }
printf("Mon hoc co diem trung binh cao nhat: %s (%.2f)\n", dau-
>monhoc[mon_max].ten, max_tb);
printf("Mon hoc co diem trung binh thap nhat: %s (%.2f)\n",
dau>monhoc[mon_min].ten, min_tb); }
3.6. Module 6 Hiển thị số dương đầu danh sách, số âm cuối danh sách, dãy số
dương tăng dần, dãy số âm giảm dần.
// Hàm hiển thị danh sách void hienThiDanhSach(Node* head) {
printf("Danh sach: "); while (head != NULL) { printf("%d ", head-
>data); head = head->next; } printf("\n"); } lOMoAR cPSD| 60729183 3.3. Kết quả - Mebu lựa chọn - Lựa chọn 1 - Lựa chọn 2