Mục tiêu của đoạn code là xây dựng cấu trúc dữ liệu và các hàm để quản lý thông tin sinh viên trong một danh sách liên kết đơn.I.4.. Hàm CreateNode nhận đối số là một biến kiểu SV sinh v
Trang 1NGÂN HÀNG NHÀ NƯỚC VIỆT NAM BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC NGÂN HÀNG TP HỒ CHÍ MINH
-BÀI TẬP NHÓM
Giảng Viên: Nguyễn Văn ThọLớp: ITS724_2321_10_L17Khoá học: 2022-2026Môn học: Giải thuật ứng dụng trong kinh doanh
Trang 2Trần Trà My 050610221092
Tìm kiếm sinhviên, tìm kiếm sinhviên có điểm trungbình lớn nhất, xuấttên sinh viên cóđiểm trung bìnhlớn hơn 5Nguyễn Phi Tấn
Làm báo cáo tổnghợp
Nguyễn Phạm
Sắp xếp danh sáchtăng dần theo điểmtrung bình, hàmmain, cảm nhậncủa môn học
Võ Lê Anh Kiệt 050610221009 Xoá sinh viên đầu
danh sách, xoásinh viên cuối
Trang 3danh sách, xoátoàn bộ danh sách,
bổ sung nhữngthông tin còn thiếu
Trang 4DANH SÁCH THÀNH VIÊN NHÓM 1
MỤC LỤC 3
PHẦN 1: MÔ TẢ CHƯƠNG TRÌNH 4
PHẦN 2: NỘI DUNG CHƯƠNG TRÌNH VÀ CÁC THUẬT TOÁN 5
I Các tác vụ 5
1 Định nghĩa sinh viên 5
2 Khởi tạo 6
3 Tác vụ kiểm tra rỗng 6
4 Tác vụ tạo nút 7
5 Tác vụ Insert First 8
6 Tác vụ Insert After 10
7 Tác vụ Insert Last 13
II Các chức năng 17
1 Nhập 1 sinh viên 17
2 Nhập danh sách sinh viên 19
3 Xuất 1 sinh viên 23
4 Tác vụ showlist 24
5 Xuất thông tin sinh viên có điểm trung bình > 5 27
6 Tìm kiếm sinh viên 31
7 Tìm sinh viên có điểm trung bình lớn nhất 36
8 Sắp xếp danh sách tăng dần theo điểm trung bình 41
9 Xoá sinh viên đầu danh sách 45
10.Xoá sinh viên cuối danh sách 48
11.Xoá toàn bộ danh sách 52
12.Hàm main 55
PHẦN 3: NHẬN XÉT MÔN HỌC 59
Trang 5PHẦN 1: MÔ TẢ CHƯƠNG TRÌNH
Viết chương trình quản lý sinh viên (sử dụng danh liên kết), thông tin mỗi sinhviên gồm:
Mã SV – Kiểu số nguyên
Họ và Tên – Kiểu chuỗi tối đa 40 kí tự
Điểm trung bình – Kiểu số thực
Chương trình thực hiện có thiết kế menu bao gồm các chức năng sau:
1 Tạo 1 danh sách gồm n sinh viên (n là nhập từ bàn phìm, thông tin của mỗisinh viên nhập từ bàn phím)
2 Xuất danh sách sinh viên
3 Xuất thông tin các sinh viên có điểm trung bình lớn hơn hoặc bằng 5
4 Tìm sinh viên có tên là X
5 Tìm sinh viên có điểm trung bình lớn nhất
6 Sắp xếp danh sách tăng dần theo điểm trung bình
7 Xoá sinh viên đầu danh sách
8 Xoá sinh viên cuối danh sách
9 Xoá toàn bộ danh sách
Mở rộng, ngoài ra, chương trình cần phải đảm bảo các yếu tố kiểm tra đầu vào, tối
ưu hoá đầu ra và các vấn đề mở rộng phát sinh ví dụ:
- Tìm sinh viên có tên X, nếu nhiều hơn 1 sinh viên có tên X, phải xuất thôngtin tất cả sinh viên tên X
- Tìm sinh viên có điểm trung bình lớn nhất nhưng nếu có nhiều sinh viên đạtđiểm cao nhất cũng phải xuất thông tin của các sinh viên đó
- Sắp xếp tăng dần theo điểm trung bình, nếu có nhiều hơn 1 sinh viên trùngđiểm sẽ sắp xếp theo mã số sinh viên
Trang 6PHẦN 2: NỘI DUNG CHƯƠNG TRÌNH VÀ CÁC THUẬT TOÁN
typedef struct SinhVien SV;
typedef struct node
{
SV info; //luu thông tin 1 SV
struct node* next; //luu dia chi nut tiep theo
}Node;
typedef Node* NodeSV;
I.1 Lỗi và sửa lỗi: Giải thuật không có lỗi
I.2 Diễn giải:
Định nghĩa cấu trúc SinhVien để lưu trữ thông tin của mỗi sinh viên bao gồm mã sinh viên (masv), họ tên (hoten) và điểm trung bình (dtb)
Sử dụng typedef để tạo định danh cho cấu trúc SinhVien và cấu trúc node
Định nghĩa cấu trúc node để lưu trữ thông tin của mỗi nút trong danh sách liên kết đơn Mỗi nút bao gồm một biến kiểu SinhVien và một con trỏ đến nút tiếp theo
Sử dụng typedef để tạo định danh cho con trỏ đến Node, gọi là NodeSV
I.3 Mục tiêu
Trang 7Mục tiêu của đoạn code là xây dựng cấu trúc dữ liệu và các hàm để quản lý thông tin sinh viên trong một danh sách liên kết đơn.
I.4 Độ phức tạp: Độ phức tạp của phần khởi tạo danh sách là O(1) I.5 Nhận xét:
Sử dụng typedef cho cấu trúc SinhVien và node giúp tạo ra các định danh tiện lợi, dễ đọc và dễ sử dụng lại trong mã nguồn
Trang 8int IsEmpty(NodeSV phead){
Trang 9Hàm CreateNode nhận đối số là một biến kiểu SV (sinh viên) được gọi
là x, chứa thông tin của sinh viên cần thêm vào nút mới
Trong hàm này, một con trỏ p được cấp phát bộ nhớ để tạo ra một nút mới trong danh sách liên kết đơn
Thông tin của sinh viên x được gán vào trường info của nút mới.Trường next của nút mới được gán giá trị NULL, đánh dấu rằng nút nàychưa có liên kết với nút nào khác
Sau đó, con trỏ p được trả về để biểu diễn nút mới đã được tạo
Đầu tiên, hàm tạo một nút mới bằng cách gọi hàm CreateNode(x), tạo một nút chứa thông tin sinh viên x
Trang 10Cuối cùng, con trỏ phead được cập nhật để trỏ đến nút mới, biểu thị rằng nút mới đã trở thành nút đầu tiên của danh sách.
5.3.Sơ đồ khối:
Trang 11- Code dễ hiểu, chỉ chèn một nút mới vào đầu danh sách.
- Thời gian thực thi nhanh: Do độ phức tạp O(1), thời gian thực thi củahàm là nhanh chống, không phụ thuộc vào kích thước của danh sách.Nhược điểm:
- Không kiểm tra trạng thái hợp lệ: Hàm không kiểm tra xem con trỏphead có hợp lệ hay không trước khi chèn nút mới Nếu phead làNULL, quá trình chèn vẫn tiếp tục, dẫn đến lỗi khi truy cập một con trỏkhông hợp lệ
Trang 12B1: Khai báo hàm:
void InsertAfter(NodeSV &p, SV x){
Hàm InsertAfter nhận vào một tham chiếu đến con trỏ p, là con trỏ đến nút trong danh sách liên kết mà sau đó nút mới sẽ được chèn vào sau, và một đối tượng SV là thông tin của sinh viên cần chèn vào danh sách.B2: Kiểm tra điều kiện:
if (p != NULL) {
Trước khi chèn nút mới, ta cần kiểm tra xem con trỏ p có trỏ đến một nút hợp lệ không Nếu p không rỗng (tức là không trỏ đến NULL), ta tiến hành chèn nút mới vào sau nút p
B5: Liên kết nút p với nút mới:
p->next = tam;
Con trỏ next của nút p được gán bằng con trỏ của nút mới (tam) Điều này có nghĩa là nút p bây giờ trỏ đến nút mới thay vì trỏ đến nút tiếp theo trong danh sách liên kết
Trang 136.3.Sơ đồ khối
Trang 146.4.Mục tiêu của đoạn code:
Chức năng của đoạn code là chèn một nút mới vào sau một nút đã cho trong danh sách liên kết đơn
6.5.Đánh giá độ phức tạp:
Độ phức tạp của hàm InsertAfter là O(1) trong trường hợp trung bình, tuy nhiên, trong trường hợp tồi tệ nhất khi nút cần chèn là nút cuối cùng, độphức tạp có thể là O(n) với n là số lượng nút trong danh sách
Trang 157.1.Lỗi và sữa lỗi: Giải thuật không có lỗi.
7.2.Diễn giải:
B1: Khai báo hàm:
void InsertLast(NodeSV &phead, SV x){
Hàm InsertLast nhận vào một tham chiếu đến con trỏ phead, là con trỏ đến đầu của danh sách liên kết, và một đối tượng SV là thông tin của sinh viên cần chèn vào danh sách
B2: Tạo nút mới:
NodeSV tam = CreateNode(x);
Sử dụng hàm CreateNode(x) để tạo một nút mới và trả về con trỏ đến nút này
Thông tin của sinh viên x được chuyển vào hàm CreateNode để lưu vàonút mới
B3: Duyệt danh sách để tìm nút cuối cùng:
NodeSV ptemp = phead;
while (ptemp->next != NULL)
Trang 16- Trong trường hợp danh sách không rỗng, một con trỏ ptemp được sử dụng để duyệt từ đầu danh sách đến nút cuối cùng (nút có con trỏ next là NULL).
- Khi ptemp đến được nút cuối cùng, nút mới (tam) được chèn vào sau nút cuối cùng bằng cách gán con trỏ next của nút cuối cùng bằng con trỏ của nút mới
Trang 177.3.Sơ đồ khối
Trang 187.4.Mục tiêu của đoạn code:
Chức năng của đoạn code là chèn một nút mới vào cuối danh sách liênkết đơn
printf("\n Masv: "); gets(x.masv);
printf("\n Ho ten: "); gets(x.hoten);
printf("\n Diem TB: "); float t;
Trang 19Sử dụng hàm scanf để nhập điểm trung bình của sinh viên.Sau đó, giá trị điểm trung bình được gán vào trường dtb của biến x
1.3.Sơ đồ khối:
Trang 201.4.Mục tiêu của đoạn code:
Chức năng của đoạn code là nhập thông tin của một sinh viên từ ngườidùng
- Chức năng đơn giản và hiệu quả: Hàm cung cấp chức năng cần thiết
để nhập thông tin của một sinh viên từ người dùng
- Dễ hiểu và sử dụng: Code ngắn gọn và dễ hiểu, sử dụng các hàm nhậpchuẩn của ngôn ngữ để thuận tiện cho người dùng
Nhược điểm:
- Không kiểm tra đầu vào: Hàm không kiểm tra xem dữ liệu nhập vào
có hợp lệ hay không, ví dụ như kiểm tra mã sinh viên có đúng định dạnghay không, điềm trung bình có nằm trong khoảng giá trị hợp lệ không Điềunày có thể dẫn đến việc nhập dữ liệu không đúng và gây lỗi trong quá trình
xử lý dữ liệu
2 Nhập danh sách sinh viên
2.1.Lỗi và sửa lỗi:
//Nhap danh sach sinh vien
void nhapds(NodeSV &phead)
int n; SV x;
printf("Nhap so luong sinh vien: "); scanf("%d", &n);
Trang 21for(int i=0; i<n; i++)
CreateNode(x);
// Nếu danh sách rỗng, tạo nút đầu tiên
} else {InsertLast(phead, x);
// Thêm sinh viên vào cuối danh sách
} } }Lỗi: Chưa kiểm tra xem đủ bộ nhớ chưa
Sửa lỗi: Kiểm tra xem có đủ bộ nhớ để cấp phát nút mới không Nếu không đủ bộ nhớ, thông báo lỗi sẽ được in ra và hàm sẽ kết thúc
2.2.Diễn giải:
Hàm “nhapds” nhận vào một tham chiếu phead đến con trỏ đầu danhsách liên kết và thực hiện việc nhập danh sách sinh viên từ người dùng.Đầu tiên, người dùng sẽ được yêu cầu nhập số lượng sinh viên cần nhậpthông tin
Tiếp theo, vòng lặp for sẽ chạy để nhập thông tin của từng sinh viên.Trong mỗi lần lặp, hàm nhap1SV được gọi để nhập thông tin của sinh
Trang 242.4.Mục tiêu của đoạn code:
Chức năng của đoạn code là nhập danh sách sinh viên từ ngườidùng
- Không kiểm tra đầu vào: Tương tự như hàm nhap1SV, hàmnhapds cũng không kiểm tra đầu vào, điều này có thể dẫn đến việc nhập
dữ liệu không đúng và gây lỗi trong quá trình xử lý dữ liệu
- Không xử lý trường hợp lỗi: Hàm không xử lý các trường hợplỗi như nhập số lượng sinh viên âm hoặc không thể chèn sinh viên vàodanh sách, do đó có thể dẫn đến lỗi trong quá trình thực thi
3 Xuất 1 sinh viên:
Trang 25Diễn giải cách thức thực hiện đoạn code:
Hàm xuat1SV nhận vào một biến x kiểu SV, đại diện cho thông tincủa sinh viên cần xuất ra
Sử dụng các hàm printf và puts để xuất thông tin của sinh viên ramàn hình, bao gồm mã sinh viên, họ tên và điểm trung bình
3.3.Mục tiêu của đoạn code:
Chức năng của đoạn code là xuất thông tin của một sinh viên ra mànhình
4.1.Lỗi và sửa lỗi
return;
}
Trang 26- Lỗi: Chưa có lệnh kết thúc vòng lặp dẫn đến lặp không cần thiết.
- Chữa lỗi: Thêm lệnh return để vòng lặp kết thúc
4.2.Diễn giải:
- Hàm ShowList nhận vào một con trỏ phead đến đầu danh sách liênkết và thực hiện việc duyệt qua danh sách để hiển thị thông tin của từngsinh viên
- Đầu tiên, kiểm tra xem danh sách có rỗng không Nếu danh sáchrỗng (phead == NULL), xuất thông báo “Danh sách bị rỗng” ra màn hình
- Nếu danh sách không rỗng, thì dùng một vòng lặp while để duyệtqua danh sách từ đầu đến cuối
- Trong mỗi lần lặp, hàm xuat1SV được gọi để xuất thông tin củasinh viên ra màn hình, sau đó con trỏ p được di chuyển tới nút tiếp theotrong danh sách
Trang 274.3.Sơ đồ khối:
Trang 284.4.Mục tiêu của đoạn code:
Chức năng của đoạn code là hiển thị danh sách sinh viên ra màn hình
4.5.Đánh giá về độ phức tạp:
Độ phức tạp của hàm ShowList phụ thuộc vào số lượng sinh viêntrong danh sách, với mỗi sinh viên trong danh sách, ta phải gọi hàmxuat1SV một lần, do đó độ phức tạp là O(n), với n là số lượng sinh viêntrong danh sách
- Không kiểm tra đầu vào: Hàm không kiểm tra xem danh sách có hợp
lệ hay không trước khi hiển thị Điều này có thể dẫn đến việc truy cập mộtdanh sách không hợp lệ và gây lỗi trong quá trình hiển thị
5 Xuất thông tin sinh viên có điểm trung bình >5:
5.1.Lỗi và cách sửa lỗi:
void GreaterThan5 (NodeSV phead)
else { for(p=phead;p!
Trang 29} }
Lỗi cần khắc phục:
Đoạn code này ban đầu thiếu “else”
Cách sửa lỗi:
Thêm else vào đoạn code Nếu chúng ta không sử dụng else, việc
xử lý chỉ sẽ chạy khi điều kiện p == NULL thỏa mãn, trong khi trường hợp không thoả mãn không có xử lý rõ ràng Bằng cách thêm else, chắc chắn rằng dữ liệu sẽ được xử lý đúng cách trong cả hai trường hợp
Trường hợp không thêm “else” vào đoạn code thì phải return hoặc exit hàm này khi p == NULL
B2.3 Nếu điểm của phần data tại NODE hiện tại lớn hơn 5=> In
ra màn hình data của node sinh viên đang duyệt
B2.4 Gán NODE hiện tại khác NULL
B2.5 Nếu NODE hiện tại khác NULL.Quay lại bước B2.3
Trang 305.3.Sơ đồ khối
Trang 32 Tìm kiếm điểm trung bình lớn hơn 5 trong danh sách.
Xuất thông tin của những sinh viên có điểm trung bình lớn hơn
Với mỗi sinh viên trong danh sách, mã code chỉ thực hiện một phép
so sánh để kiểm tra xem điểm trung bình có lớn hơn 5 hay không Do đó,hiệu suất của mã code này là tốt
Nhược điểm:
Mã code không kiểm tra nếu phead là một danh sách sinh viên hợp
lệ Nếu phead không phải là danh sách sinh viên hợp lệ, chương trình cóthể gặp lỗi
Mã code chỉ kiểm tra phead có rỗng hay không sau khi đã gánp=phead Điều này có thể dẫn đến lỗi nếu phead rỗng, vì vòng lặp vẫn sẽđược thực thi ít nhất một lần trước khi kiểm tra
6 Tìm kiếm sinh viên
6.1.Lỗi và sửa lỗi
Trang 33NodeSV FindS(NodeSV phead, char
if (p==NULL) printf("Khong tim
thay sinh vien trong danh sach");
printf("\nDanh sach bi rong\n");
return NULL;
} while (p != NULL) {
if (strcmp(p->info.hoten, s)
== 0) { printf("\nDa tim thay sinh vien: ");
xuat1SV(p->info); return p;
}
p = p->next;
} printf("\nKhong tim thay sinh vien trong danh sach\n");
Trang 34 Thêm return vì hàm này chưa trả về giá trị mặc định (defaultvalue)
Có thể dùng strcmp để so sánh hai chuỗi a.hoten và s
Cách sửa lỗi:
Bằng cách thực hiện return NULL; ngay sau khi in ra thông báo
"Danh sách bị rỗng", chương trình sẽ kết thúc việc thực thi của hàmFindS tại thời điểm đó và trả về giá trị NULL ngay lập tức
Thay đổi từ lệnh break sang return p phản ánh rõ ràng hơn ýnghĩa của việc kết thúc vòng lặp và trả về giá trị p
Thêm return NULL; cuối cùng, chúng ta đảm bảo rằng sau khiduyệt hết danh sách mà không tìm thấy sinh viên cần tìm, hàm sẽ trả vềgiá trị NULL như một giá trị mặc định
B3.1 Khởi tạo node mới bằng NodeSV
B3.2 Khởi tạo vòng lặp while với giá trị bắt đầu là NODE p làNODE đầu tiên của danh sách, điều kiện vòng lặp là p khácNULL, qua mỗi vòng lặp, p được trỏ về NODE kế tiếp
B3.3 Nếu điều kiện của vòng lặp đúng
B3.3.1 Khởi tạo biến kiểu SinhVien và gán giá trị là phần datacủa NODE hiện tại
B3.3.2 Thực hiện hàm so sánh chuỗi strcmp giữa tên nhập vào
và tên của sinh viên tại NODE hiện tại
Trang 35 Nếu hàm trả về giá trị 0 thì tên tìm kiếm và tên của sinh viêntại NODE hiện tại là giống nhau.
Thêm sinh viên tại NODE này vào 1 danh sách tạm thời.B3.4 Ngược lại nếu điều kiện lặp là sai, kết thúc vòng lặp.B3.5 Nếu danh sách tạm thời bằng NULL
B3.5.1 Thông báo không có sinh viên này trong danh sách.B3.6 Ngược lại
B3.6.1 In số lượng sinh viên có tên giống như tên cần tìm.B3.6.2 In thông tin sinh viên từ danh sách tạm thời
Trang 366.3.Sơ đồ khối
Trang 376.4.Mục tiêu:
- Tìm sinh viên có điểm trung bình lớn hơn 5 trong danh sách
- Xuất thông tin có điểm trung bình lớn hơn 5 vừa tìm được
- Cung cấp thông báo sau khi thực hiện tìm kiếm:
Nếu tìm thấy sinh viên có tên tương ứng, in ra thông tin củasinh viên đó
Nếu không tìm thấy sinh viên, thông báo rằng không có sinhviên trong danh sách
6.5.Đánh giá độ khó:
Việc duyệt qua danh sách liên kết yêu cầu kiến thức về cấu trúc
dữ liệu và các phương pháp duyệt qua danh sách như sử dụng vònglặp while
Sử dụng hàm so sánh chuỗi strcmp yêu cầu so sánh chuỗi vàcách sử dụng hàm trong ngôn ngữ lập trình cụ thể
Xử lý các trường hợp đặc biệt như danh sách rỗng
6.6.Nhân xét:
Ưu điểm:
Đoạn code này chỉ cần duyệt qua danh sách một lần, nếu tìmthấy sinh viên cần tìm, nó sẽ dừng vòng lặp ngay lập tức bằng cách
sử dụng lệnh break, giúp tăng hiệu suất
Sử dụng con trỏ p để duyệt danh sách là một cách hiệu quả đểtránh việc duyệt lại từ đầu danh sách
Nhược điểm:
Hàm không trả về node của sinh viên đó, điều này có thể hạnchế tính tái sử dụng của hàm Thay vào đó, nó chỉ in ra thông tin của