#include “stdafx.h”
#include “stdio.h”
#include “conio.h”
#include “iostream”
#define MSSV 9
#define Ho_Ten 30
#define NamSinh 5
struct SinhVien
{
char strMSSV[MSSV];
char strHoTen[Ho_Ten];
char strNamSinh[NamSinh];
float fDiemTrungBinh;
};
struct SinhVienNode
{
SinhVien info;
SinhVienNode * pNext;
};
struct List
{
SinhVienNode * pHead, * pTail;
};
SinhVienNode * getHead(List & l);
// Hàm khởi tạo danh sách
void init(List & l)
{
l.pHead = l.pTail = NULL;
}
// Hàm thiết lập thông tin cho sinh viên
SinhVien setInfo()
{
SinhVien info;
// Nhập MSSV
fflush(stdin);
printf("Nhap vao MSSV: ");
gets_s(info.strMSSV);
// Nhập họ và tên
fflush(stdin);
printf("Nhap vao ho va ten: ");
gets_s(info.strHoTen);
// Nhập năm sinh
fflush(stdin);
printf("Nhap vao nam sinh: ");
gets_s(info.strNamSinh);
// Nhập điểm trung bình
fflush(stdin);
printf("Nhap vao diem trung binh: ");
scanf_s("%f", & info.fDiemTrungBinh);
return info;
}
// Hàm tạo ra một node sinh viên hoàn chỉnh
SinhVienNode * getNode(SinhVien info)
{
SinhVienNode * p = new SinhVienNode;
if(p == NULL) // Cấp phát động không thành công
{
return NULL;
}
p->info = info;
p->pNext = NULL;
return p;
}
// Hàm chỉ sắp xếp sinh viên có sẵn vào đầu danh sách
void addHead(List & l, SinhVienNode * p)
{
if(l.pHead == NULL) // Nếu danh sách rỗng
{
l.pHead = l.pTail = p; // p vừa là đầu, vừa là cuối
return;
}
p->pNext = l.pHead;
l.pHead = p;
}
// Hàm chỉ sắp xếp sinh viên có sẵn vào cuối danh sách
void addTail(List & l, SinhVienNode * p)
{
if(l.pHead == NULL) // Nếu danh sách rỗng
{
l.pHead = l.pTail = p; // p vừa là đầu, vừa là cuối
return;
}
l.pTail->pNext = p;
l.pTail = p;
}
// Hàm nhận thông tin sinh viên và sắp xếp vào vị trí đầu danh sách
SinhVienNode * insertHead(List & l, SinhVien info)
{
SinhVienNode * p = getNode(info); // Nhận sinh viên
if(p == NULL) // Nếu cấp phát động thất bại
{
return NULL; // Báo thêm thất bại
}
addHead(l, p); // Thêm vào đầu danh sách
return p; // Báo thêm thành công
}
// Hàm nhận thông tin sinh viên và sắp xếp vào vị trí cuối danh sách
SinhVienNode * insertTail(List & l, SinhVien info)
{
SinhVienNode * p = getNode(info); // Nhận sinh viên
if(p == NULL) // Nếu cấp phát động thất bại
{
return NULL; // Báo thêm thất bại
}
addTail(l, p); // Thêm vào cuối danh sách
return p; // Báo thêm thành công
}
// Hàm thêm sinh viên vào giữa danh sách
SinhVienNode * insertAfter(List & l, SinhVienNode * q, SinhVien info)
{
SinhVienNode * p = getNode(info); // Nhận sinh viên
if(p == NULL) // Nếu cấp phát động thất bại
{
return NULL; // Báo thêm thất bại
}
if(q == NULL) // Nếu danh sách rỗng
{
addHead(l, p); // Thêm vào đầu danh sách
}
else
{
p->pNext = q->pNext;
q->pNext = p;
if(l.pTail == q) // Nếu q là sinh viên cuối danh sách
{
l.pTail = p; // Cập nhập lại p là sinh viên cuối danh sách
}
}
return p; // Báo thêm thành công
}
// Tạo một danh sách
void createList(List & l)
{
int iSoLuong; // Số lượng sinh viên muốn thêm
do
{
printf("Nhap vao so luong sinh vien muon then: ");
scanf_s("%d", & iSoLuong);
}
while(iSoLuong < 1); // Số lượng sinh viên ít nhất là 1
for(int i = 1; i <= iSoLuong; i++)
{
printf("\n\n\n");
printf("Sinh vien thu %d:\n\n", i);
if( insertTail( l, setInfo() ) == NULL) // Không đủ bộ nhớ
{
printf("Khong du bo nho!");
break;
}
}
}
// Hàm tìm sinh viên theo mã số sinh viên
SinhVienNode * searchMSSV(List l, char strMSSV[MSSV])
{
SinhVienNode * p;
// Duyệt từ đầu đến cuối danh sách
for(p = l.pHead; p != NULL; p = p->pNext)
{
if( strcmp(p->info.strMSSV, strMSSV) == 0 ) // Tìm thấy
{
return p;
}
}
return NULL; // Không tìm thấy
}
// Hàm tách sinh viên theo mã số sinh viên
SinhVienNode * getMSSV(List l, char strMSSV[MSSV])
{
SinhVienNode * k = l.pHead;
if( strcmp(l.pHead->info.strMSSV, strMSSV) == 0 ) // Tìm thấy là sinh viên đầu danh sách
{
return getHead(l);
}
// Duyệt từ đầu đến cuối danh sách
for(SinhVienNode * p = l.pHead->pNext; p != NULL; p = p->pNext)
{
if( strcmp(p->info.strMSSV, strMSSV) == 0 ) // Tìm thấy
{
k->pNext = p->pNext; // Nối lại liên kết chổ bị tháo
p->pNext = NULL;
return p;
}
k = k->pNext; // Đảm bảo k đứng trước p để có thể nối lại liên kết
}
return NULL; // Không tìm thấy
}
// Hàm tìm điểm trung bình cao nhất
float findMax(List l)
{
float fMax;
fMax = l.pHead->info.fDiemTrungBinh; // Gán mặc định điểm cao nhất của sinh viên đầu
for(SinhVienNode * p = l.pHead; p != NULL; p = p->pNext)
{
if(fMax < p->info.fDiemTrungBinh) // Nếu có sinh viên khác cao điểm hơn
{
fMax = p->info.fDiemTrungBinh; // Cập nhập lại điểm cao nhất
}
}
return fMax;
}
// Xuất ra thông tin một sinh viên
void showSinhVien(SinhVienNode * p)
{
printf("%s - %s - %s - %.1f", p->info.strMSSV, p->info.strHoTen, p->info.strNamSinh, p->info.fDiemTrungBinh);
}
// Xuất ra danh sách thông tin sinh viên
void showList(List l)
{
printf(“Danh sach thong tin sinh vien”);
int i = 1;
// Duyệt từ đầu danh sách đến cuối danh sách
for(SinhVienNode * p = l.pHead; p != NULL; p = p->pNext)
{
printf("\n\n\n");
printf("Sinh vien thu %d\n", i);
showSinhVien(p); // Xuất ra thông tin mỗi sinh viên
i++;
}
}
// Tách sinh viên đầu ra khỏi danh sách
SinhVienNode * getHead(List & l)
{
SinhVienNode * p = NULL;
if(l.pHead != NULL) // Danh sách không rỗng
{
p = l.pHead; // p giữ sinh viên đầu danh sách
l.pHead = l.pHead->pNext; // Cập nhập lại đầu danh sách
p->pNext = NULL;
if(l.pHead = NULL) // Nếu danh sách rỗng
{
l.pTail = NULL; // Cập nhập lại cuối danh sách
}
}
return p;
}
// Tách sinh viên giữa ra khỏi danh sách
SinhVienNode * getAfter(List & l, SinhVienNode * q)
{
SinhVienNode * p = NULL;
if(q != NULL)
{
p = q->pNext; // p giữ sinh viên cần tách
if(p != NULL) // Nếu q không phải cuối danh sách
{
q->pNext = p->pNext; // Nối lại liên kết chổ sắp tách
p->pNext = NULL;
}
if (p == l.pTail) // Nếu p là sinh viên cuối danh sách
{
l.pTail = q; // Cập nhập lại cuối danh sách
}
}
else
{
p = getHead(l);
}
return p;
}
// Xóa sinh viên
void delSinhVien(SinhVienNode * p)
{
//SinhVien info;
//info = p->info; // Giữ thông tin sinh viên sẽ xóa
delete p; // Xóa sinh viên
//return info;
}
// Xóa danh sách
void delList(List & l)
{
SinhVienNode * p;
while(l.pHead != NULL) // Lắp đến khi hết danh sách
{
p = l.pHead; // p giữ sinh viên đầu cần xóa
l.pHead = l.pHead->pNext; // Cập nhập lại đầu danh sách
delete p; // Xóa sinh viên
}
l.pTail = NULL;
}
void main()
{
List Lop18TH01;
int iChoise;
int iA;
float fMax;
char strMSSV_Del[MSSV];
char strMSSV_Find[MSSV];
init(Lop18TH01);
SinhVienNode * p = Lop18TH01.pHead;
createList(Lop18TH01);
while(1)
{
system("cls");
printf("1 - Xuat danh sach thong tin sinh vien\n");
printf("2 - Them sinh vien vao dau danh sach\n");
printf("3 - Them sinh vien vao giua danh sach\n");
printf("4 - Them sinh vien vao cuoi danh sach\n");
printf("5 - Xoa sinh vien dau danh sach\n");
printf("6 - Xoa sinh vien giua danh sach\n");
printf("7 - Xoa sinh vien theo MSSV\n");
printf("8 - Tim sinh vien theo MSSV\n");
printf("9 - Tim sinh vien co diem trung binh cao nhat\n");
printf("0 - Thoat\n\n");
printf("Chon: ");
scanf_s("%d", & iChoise);
system("cls");
switch(iChoise)
{
case 0:
return;
case 1:
showList(Lop18TH01);
break;
case 2:
insertHead( Lop18TH01, setInfo() );
break;
case 3:
printf("Nhap vao vi tri muon them: ");
scanf_s("%d", & iA);
if(iA == 1)
{
insertHead( Lop18TH01, setInfo() );
}
else
{
for(int i = 2; i < iA; i++)
{
p = p->pNext;
}
insertAfter( Lop18TH01, p, setInfo() );
}
break;
case 4:
insertTail( Lop18TH01, setInfo() );
break;
case 5:
delSinhVien( getHead(Lop18TH01) );
printf("Da xoa thanh cong!");
break;
case 6:
break;
case 7:
fflush(stdin);
printf("Nhap vao MSSV can xoa: ");
gets_s(strMSSV_Del);
if( getMSSV(Lop18TH01, strMSSV_Del) == NULL )
{
printf("Khong tim thay!");
}
else
{
delSinhVien( getMSSV(Lop18TH01, strMSSV_Del) );
printf("Da xoa thanh cong!");
}
break;
case 8:
fflush(stdin);
printf("Nhap vao MSSV can tim: ");
gets_s(strMSSV_Find);
if( searchMSSV(Lop18TH01, strMSSV_Find) == NULL )
{
printf("Khong tim thay!");
}
else
{
showSinhVien( searchMSSV(Lop18TH01, strMSSV_Find) );
}
break;
case 9:
fMax = findMax(Lop18TH01);
printf("Sinh vien co diem trung binh cao nhat");
for(SinhVienNode * p = Lop18TH01.pHead; p != NULL; p = p->pNext)
{
if(p->info.fDiemTrungBinh == fMax)
{
printf("\n\n\n");
showSinhVien(p);
}
}
break;
}
_getch();
}
}