Professional Documents
Culture Documents
Báo cáo cấu trúc dữ liệu và giải thuật
Báo cáo cấu trúc dữ liệu và giải thuật
1
MỤC LỤC
I. XÁC ĐỊNH BÀI TOÁN.............................................................................................................3
II. XÁC ĐỊNH CTDL BIỂU DIỄN BÀI TOÁN...................................................................................3
III. XÁC ĐỊNH CÁC THUẬT TOÁN – CÁC CHỨC NĂNG................................................................5
IV. LẬP TRÌNH – CÀI ĐẶT..........................................................................................................6
4.1. Các Thuật Toán Chính Của Đối Tượng SACH:.............................................................................6
4.2. Các thuật toán chính của đối tượng DOCGIA:..........................................................................13
4.3. Các thuật toán chính của PHIEUMUON:...................................................................................20
V. KIỂM THỬ - LẬP BỘ TEST...................................................................................................29
5.1. Bộ test của SACH:...................................................................................................................29
5.2. Bộ test của DOCGIA:...............................................................................................................34
5.3. Bộ test của PHIEUMUON:........................................................................................................37
2
I. XÁC ĐỊNH BÀI TOÁN
Thư viện trường Đại học Mở Hà Nội có rất nhiều đầu sách gồm nhiều thể loại
khác nhau. Sinh viên đến thư viện muốn mượn sách cần cung cấp thông tin cá nhân
và để lại thẻ sinh viên. Thư viện khi cho sinh viên mượn sách sẽ cung cấp 1 phiếu
mượn sách. Đến khi sinh viên trả lại sách cần đưa lại phiếu mượn và số sách đã
mượn, sinh viên sẽ nhận lại thẻ sinh viên.
struct NodeS
{
SACH infor;
struct NodeS *next;
struct NodeS *previous;
};
struct ListS
{
NodeS *Head;
NodeS *Tail;
};
3
struct NodeDocGia *prev;
};
struct ListDocGia
{
NodeDocGia *Head;
NodeDocGia *Tail;
};
PHIẾU MƯỢN: số phiếu, , ngày mượn, số sách mượn, thông tin độc giả
mượn sách, danh sách các sách đã mượn.
struct NodePhieuMuon
{
PhieuMuon info;
struct NodePhieuMuon *next;
};
struct ListPhieuMuon
{
NodePhieuMuon *Head;
NodePhieuMuon *Tail;
};
4
III. XÁC ĐỊNH CÁC THUẬT TOÁN – CÁC CHỨC NĂNG
5
IV. LẬP TRÌNH – CÀI ĐẶT
4.1. Các Thuật Toán Chính Của Đối Tượng SACH:
//Tim sach co so luong lon nhat
void Sach_SLLonNhat(ListS DQ)
{
NodeS *p, *q;
int SLmax = 0;
char masach[10];
if (DQ.Head == NULL)
{
cout << "\n Danh sach rong!";
return;
}
for (p = DQ.Head; p != NULL; p = p->next)
{
if (p->infor.SLCoSan > SLmax)
SLmax = p->infor.SLCoSan;
}
cout << "\n SACH CO SO LUONG LON NHAT: ";
for (p = DQ.Head; p != NULL; p = p->next)
{
if (p->infor.SLCoSan == SLmax)
InSach(p->infor);
}
}
6
cout << setw(5) << "SL";
}
InSach(p->infor);
}
}
if (dem == 0)
cout << "\n Khong Co Sach Co So Luong > 10";
}
7
}
//Tinh tong so luong sach co trong cua hang
void TinhTongSoSach (ListS DQ)
{
int SoLuong=0;
NodeS *p;
if (DQ.Head == NULL)
{
cout << "\n Danh sach rong!";
return;
}
for(p=DQ.Head; p!=NULL; p=p->next)
{
SoLuong = SoLuong + p->infor.SLCoSan;
}
cout<<"\n TONG SO LUONG SACH TRONG CUA HANG LA: "<<SoLuong;
}
8
// Sua thong tin SACH dua tren ten
void SuaSach(ListS &DQ)
{
string k;
int dem = 0;
SACH x;
cout << "\n Nhap Ten Sach Can Sua: ";
fflush(stdin);
getline(cin, k);
NodeS *p;
for (p = DQ.Head; p != NULL; p = p->next)
if (p->infor.TenSach == k)
{
dem++;
NhapSach(x);
p->infor = x;
}
if (dem == 0)
cout << "\n Khong tim duoc sach";
else
{
cout << "\n Sua Thanh Cong!";
cout << "\n Danh Sach Da Sua: ";
InDSSach(DSSach);
}
}
9
else
{
if ((p == DQ.Head) && (p == DQ.Tail))
{
DQ.Head = NULL;
DQ.Tail = NULL;
}
else if (p == DQ.Head)
DQ.Head = p->next;
else if (p == DQ.Tail)
{
p->previous->next = NULL;
DQ.Tail = p->previous;
}
else
{
p->previous->next = p->next;
p->next->previous = p->previous;
}
free(p);
cout << "\n Xoa Thanh Cong!";
cout << "\n Danh Sach Da Xoa: ";
InDSSach(DSSach);
}
}
10
//Doc danh sach cac sach tu file sach.txt
void DocFile(ListS &DQ, FILE *df)
{
SACH s;
int i, n;
NodeS *dp;
df = fopen("Sach.txt", "rb");
fread(&n, sizeof(int), 1, df);
for (i = 0; i < n; i++)
{
fread(&s, sizeof(SACH), 1, df);
dp = Get_Node(s);
ChenCuoi(DQ, dp);
}
fclose(df);
cout << "\n Doc file thanh cong!";
InDSSach(DSSach);
}
11
break;
case 2:
InDSSach(DSSach);
break;
case 3:
Sach_SLLonNhat(DSSach);
break;
case 4:
InSach_SL10(DSSach);
break;
case 5:
SXSL_Giam(DSSach);
break;
case 6:
TK_TenTacGia(DSSach);
break;
case 7:
TinhTongSoSach(DSSach);
break;
case 8:
ThemSach(DSSach);
break;
case 9:
SuaSach(DSSach);
break;
case 10:
XoaSach_Ten(DSSach);
break;
case 11:
DocFile_Sach(DSSach, df);
break;
case 12:
GhiFile_Sach(DSSach, df);
break;
case 0:
return;
}
} while (chon != 0);
}
12
4.2. Các thuật toán chính của đối tượng DOCGIA:
// IN DOCGIA co lop = 2210A02
void inLop(ListDocGia DG)
{
NodeDocGia *p;
bool found = false;
if (!found)
{
cout << "\n Khong tim thay DOCGIA co lop 2210A02"<< endl;
}
}
13
// Sap xep danh sach DOCGIA tang dan theo maSV
void SX_DOCGIA_hoTen_tangdan(ListDocGia &DG)
{
NodeDocGia *p, *q;
DOCGIA tg;
for(p=DG.Head;p!=NULL;p=p->next)
{
for(q=p->next;q!=NULL;q=q->next)
{
if (strcmp(p->info.maSV, q->info.maSV) > 0)
{
tg= p->info;
p->info=q->info;
q->info=tg;
}
}
}
cout<<"\n Sap xep danh sach DOCGIA tang dan theo maSV thanh cong"<<endl;
inDSDG(DG);
}
14
//Xoa 1 DOCGIA theo maSV
void xoaDocGia(ListDocGia &DG, char maSVCanXoa[15])
{
if (DG.Head == NULL)
{
cout << "\n Danh sach doc gia rong!" << endl;
return;
}
NodeDocGia *p = DG.Head;
NodeDocGia *prev = NULL;
bool found = false;
if (found)
{
if (p == DG.Head)
{
DG.Head = DG.Head->next;
}
else if (p == DG.Tail)
{
prev->next = NULL;
DG.Tail = prev;
}
else
{
prev->next = p->next;
}
delete p;
cout << "\n Xoa doc gia co maSV " << maSVCanXoa << " thanh cong!" << endl;
}
else
{
cout << "\n Khong tim thay doc gia co maSV " << maSVCanXoa << " trong danh sach!" << endl;
}
}
//Chinh sua DOCGIA theo maSV
15
void chinhSuaDOCGIA_maSV(ListDocGia &DG, char maSVcansua[15])
{
NodeDocGia *p = timKiemMa(DG,maSVcansua);
if(p==NULL)
{
cout<<"\n Khong tim thay DOCGIA co ma: "<<maSVcansua;
return;
}
//Nhap thong tin DOCGIA moi
DOCGIA x;
nhapDG(x);
//Gan thong tin moi cho DOCGIA
p->info = x;
cout<<"\n Chinh sua DOCGIA theo ma: "<<maSVcansua<<" thanh cong";
}
// Ghi file
void GhiFile_DOCGIA(ListDocGia &DG, FILE *df)
{
int n = 0;
NodeDocGia *p;
df = fopen("DocGia.txt", "wb");
for (p = DG.Head; p != NULL; p = p->next)
n = n + 1;
fwrite(&n, sizeof(int), 1, df);
for (p = DG.Head; p != NULL; p = p->next)
{
fwrite(&(p->info), sizeof(DOCGIA), 1, df);
}
fclose(df);
cout << "\n Ghi file thanh cong" << endl;
}
16
// Doc danh sach cac doc gia tu file Docgia.txt
void DocFile_DOCGIA(ListDocGia &DG, FILE *df)
{
DOCGIA dg;
int i, n;
NodeDocGia *p;
df = fopen("DocGia.txt", "rb");
fread(&n, sizeof(int), 1, df);
for (i = 0; i < n; i++)
{
fread(&dg, sizeof(DOCGIA), 1, df);
p = getNodeDocGia(dg);
chenDauDocGia(DG, p);
}
fclose(df);
cout << "\n Doc file thanh cong!\n";
inDSDG(DG);
}
do
{
cout << "\n ________QUAN LY DOC GIA_________";
cout << "\n 1. Nhap danh sach hoa DOCGIA:";
cout << "\n 2. In danh sach DOCGIA:";
cout << "\n 3. In DOCGIA co lop = 2210A02";
cout << "\n 4. Tim kiem DOCGIA theo maSV";
cout << "\n 5. Tim kiem DOCGIA theo email";
cout << "\n 6. Sap xep danh sach DOCGIA tang dan theo maSV";
cout << "\n 7. Them 1 DOCGIA moi";
cout << "\n 8. Xoa 1 DOCGIA theo maSV";
cout << "\n 9. Chinh sua DOCGIA theo maSV";
cout << "\n 10. Dem so luong DOCGIA";
cout << "\n 11. Ghi file";
cout << "\n 12. Doc file";
cout << "\n 0. Quay lai Menu chinh";
cout << "\n Moi Ban Chon: ";
cin >> chon;
switch (chon)
17
{
case 1:
nhapDSDG(DG);
break;
case 2:
inDSDG(DG);
break;
case 3:
inLop(DG);
break;
case 4:
{
char maSVcantim[15];
cout << "\n Nhap ma sinh vien cua DOCGIA can tim: ";
cin.ignore();
cin.getline(maSVcantim, 15);
p = timKiemMa(DG, maSVcantim);
if (p == NULL)
{
cout << "\n Khong tim thay ma:" << maSVcantim << endl;
}
else
{
cout << "\n Thong tin DOCGIA co ma: " << maSVcantim << endl;
inDG(p->info);
}
}
break;
case 5:
{
char emailCantim[50];
cout << "\n Nhap email cua DOCGIA can tim: ";
cin.ignore();
cin.getline(emailCantim, 50);
p = timKiemEmail(DG, emailCantim);
if (p == NULL)
{
cout << "\n Khong tim thay email:" << emailCantim << endl;
}
else
{
cout << "\n Thong tin DOCGIA co email: " << emailCantim << endl;
inDG(p->info);
}
}
break;
case 6:
SX_DOCGIA_hoTen_tangdan(DG);
18
break;
case 7:
themDocGiaMoi(DG);
break;
case 8:
{
char maSVCanXoa[15];
cout << "\n Nhap maSV cua DOCGIA muon xoa: ";
cin.ignore();
cin.getline(maSVCanXoa, 15);
xoaDocGia(DG, maSVCanXoa);
}
break;
case 9:
{
char maSVCanchinhsua[15];
cout << "\n Nhap maSV cua DOCGIA can chinh sua: ";
cin.ignore();
cin.getline(maSVCanchinhsua, 15);
chinhSuaDOCGIA_maSV(DG, maSVCanchinhsua);
}
break;
case 10:
cout << "\n So luong DOCGIA la: " << demSoLuongDOCGIA(DG) << endl;
break;
case 11:
GhiFile_DOCGIA(DG, f);
break;
case 12:
DocFile_DOCGIA(DG, f);
break;
case 0:
return;
}
} while (chon != 0);
}
19
4.3. Các thuật toán chính của PHIEUMUON:
// IN DOCGIA co masv theo yeu cau
void inMaSV(ListPhieuMuon Q)
{
NodePhieuMuon *p;
bool found = false;
string h;
cout<<"Nhap masv can in: "; cin>> h;
for (p = Q.Head; p != NULL; p = p->next)
{
if (p->info.maSV == h)
{
inPhieuMuon(p->info);
cout << "\n ------------------------------" << endl;
found = true;
}
}
if (!found)
{
cout << "\n Khong tim thay DOCGIA co ma sv 22A1001D0048" << endl;
}
}
20
// Sap xep danh sach SV trong Phieu Muon tang dan theo So Luong Sach Muon
void SXSV_PHIEUMUON_soLuongSM_tangdan(ListPhieuMuon &Q)
{
NodePhieuMuon *p, *q;
PhieuMuon tg;
for (p = Q.Head; p != NULL; p = p->next)
{
for (q = p->next; q != NULL; q = q->next)
{
if (p->info.soSach > q->info.soSach)
{
tg = p->info;
p->info = q->info;
q->info = tg;
}
}
}
cout << "\n Sap xep danh sach SV trong PHIEUMUON tang dan theo So Luong Sach Muon thanh cong" << endl;
inDSPhieuMuon(Q);
}
//Sap xep danh sach SV trong Phieu Muon giam dan theo So Luong Sach Muon
void SXSV_PHIEUMUON_soLuongSM_giamdan(ListPhieuMuon &Q)
{
NodePhieuMuon *p, *q;
PhieuMuon tg;
for (p = Q.Head; p != NULL; p = p->next)
{
for (q = p->next; q != NULL; q = q->next)
{
if (p->info.soSach < q->info.soSach)
{
tg = p->info;
p->info = q->info;
q->info = tg;
}
}
}
cout << "\n Sap xep danh sach SV trong PHIEUMUON giam dan theo So Luong Sach Muon thanh cong" << endl;
inDSPhieuMuon(Q);
}
21
//Them 1 Phieu Muon moi
void themPhieuMuonMoi(ListPhieuMuon &Q)
{
PhieuMuon x;
nhapPhieuMuon(x);
NodePhieuMuon *p = GetNode(x);
if (Q.Head == NULL)
{
Q.Head = p;
Q.Tail = p;
}
else
{
p->next = Q.Head;
Q.Head = p;
}
cout << "\n Them PHIEU NHAP moi thanh cong!" << endl;
}
22
// Xoa 1 PHIEU MUON theo soPhieu
void xoaPhieuMuon_soPhieu(ListPhieuMuon &Q, string soPCX)
{
if (Q.Head == NULL)
{
cout << "\n Danh sach phieu muon rong!" << endl;
return;
}
NodePhieuMuon *p = Q.Head;
NodePhieuMuon *prev = NULL;
bool found = false;
while (p != NULL)
{
if (p->info.soPhieu == soPCX)
{
found = true;
break;
}
prev = p;
p = p->next;
}
if (found)
{
if (p == Q.Head)
{
Q.Head = Q.Head->next;
}
else if (p == Q.Tail)
{
prev->next = NULL;
Q.Tail = prev;
}
else
{
prev->next = p->next;
}
delete p;
cout << "\n Xoa phieu muon co soPhieu " << soPCX << " thanh cong!" << endl;
}
else
{
cout << "\n Khong tim thay phieu muon co soPhieu " << soPCX << " trong danh sach!" << endl;
}
}
// Xoa 1 PHIEU MUON theo MaSV
23
void xoaPhieuMuon_Masv(ListPhieuMuon &Q, string Masv)
{
if (Q.Head == NULL)
{
cout << "\n Danh sach phieu muon rong!" << endl;
return;
}
NodePhieuMuon *p = Q.Head;
NodePhieuMuon *prev = NULL;
bool found = false;
while (p != NULL)
{
if (p->info.maSV == Masv)
{
found = true;
break;
}
prev = p;
p = p->next;
}
if (found)
{
if (p == Q.Head)
{
Q.Head = Q.Head->next;
}
else if (p == Q.Tail)
{
prev->next = NULL;
Q.Tail = prev;
}
else
{
prev->next = p->next;
}
delete p;
cout << "\n Xoa phieu muon co Masv " << Masv << " thanh cong!" << endl;
}
else
{
cout << "\n Khong tim thay phieu muon co Masv " << Masv << " trong danh sach!" << endl;
}
}
//Ghi danh sach cac sach vao file sach.txt
void GhiFile(ListPhieuMuon &Q, FILE *df)
24
{
int n = 0;
NodePhieuMuon *dp;
df = fopen("Phieumuon.txt", "wb");
for (dp = Q.Head; dp != NULL; dp = dp->next)
n = n + 1;
fwrite(&n, sizeof(int), 1, df);
for (dp = Q.Head; dp != NULL; dp = dp->next)
{
fwrite(&(dp->info), sizeof(PhieuMuon), 1, df);
}
fclose(df);
cout << "\n Ghi file thanh cong" << endl;
}
25
//Menu cua Phieu Muon
void Menu_PhieuMuon()
{
FILE *f;
NodePhieuMuon *p;
int chon;
do
{
switch (chon)
{
case 1:
nhapDSPhieuMuon(dsPhieuMuon);
break;
case 2:
inDSPhieuMuon(dsPhieuMuon);
break;
case 3:
inMaSV(dsPhieuMuon);
break;
case 4:
{
string soPCT;
cout << "\n Nhap so phieu cua PHIEU MUON can tim: ";
cin.ignore();
getline(cin, soPCT);
p = timKiemSoPhieu(dsPhieuMuon, soPCT);
if (p == NULL)
26
{
cout << "\n Khong tim thay so phieu:" << soPCT << endl;
}
else
{
cout << "\n Thong tin PHIEU MUON co so phieu: " << soPCT << endl;
inPhieuMuon(p->info);
}
}
break;
case 5:
{
string Masv;
cout << "\n Nhap Masv cua PHIEU MUON can tim: ";
cin.ignore();
getline(cin, Masv);
p = timKiemMaSV(dsPhieuMuon, Masv);
if (p == NULL)
{
cout << "\n Khong tim thay so phieu:" << Masv << endl;
}
else
{
cout << "\n Thong tin PHIEU MUON co so phieu: " << Masv << endl;
inPhieuMuon(p->info);
}
}
break;
case 6:
SXSV_PHIEUMUON_soLuongSM_tangdan(dsPhieuMuon);
break;
case 7:
SXSV_PHIEUMUON_soLuongSM_giamdan(dsPhieuMuon);
break;
case 8:
themPhieuMuonMoi(dsPhieuMuon);
break;
case 9:
{
string soPCX;
cout << "\n Nhap soPhieu cua PHIEU NHAP muon xoa: ";
cin.ignore();
getline(cin, soPCX);
xoaPhieuMuon_soPhieu(dsPhieuMuon, soPCX);
27
}
break;
case 10:
{
string Masv;
cout << "\n Nhap Masv cua PHIEU NHAP muon xoa: ";
cin.ignore();
getline(cin, Masv);
xoaPhieuMuon_Masv(dsPhieuMuon, Masv);
}
break;
case 11:
SuaPhieuMuon_SoPhieu(dsPhieuMuon);
break;
case 12:
DocFile_PhieuMuon(dsPhieuMuon, f);
break;
case 13:
GhiFile_PhieuMuon(dsPhieuMuon, f);
break;
case 0:
return;
}
28
V. KIỂM THỬ - LẬP BỘ TEST
5.1. Bộ test của SACH:
//Chọn quản lý Sách trong thư viện
29
//In DS Sách có số lượng lớn hơn 10
30
//Tính tổng số sách có trong thư viện
31
//Sửa thông tin của 1 Sách
//Xoá 1 Sách
32
//Ghi dữ liệu vào file
33
5.2. Bộ test của DOCGIA:
//Nhập danh sách Độc Giả:
34
//In Độc Giả có Lớp là 2210A02:
//Sắp xếp danh sách Độc Giả tăng dần theo maSV
35
//Xóa 1 Độc Giả theo maSV:
//Ghi file:
//Đọc file:
36
5.3. Bộ test của PHIEUMUON:
//Nhập DS PHIEUMUON
37
//In DS PHIEUMUON
38
//Tìm kiếm theo maSinhVien
39
//SX giảm dần theo số Sách mượn
40
//Xoá 1 PHIEUMUON theo mã Sinh Viên
41