Lab 2
Lab 2
//element.h
#pragma once
#ifndef ELEMENT_H
#define ELEMENT_H
class element
{
private:
int data;
element* pointer;
public:
element();
element(int);
virtual ~element();
protected:
};
#endif // ELEMENT_H
//element.cpp
#include "element.h"
element::element() {
//ctor
this->data = 0;
this->pointer = nullptr;
}
element::element(int data) {
//ctor
this->data = data;
this->pointer = nullptr;
}
element::~element() {
//dtor
}
//linkedlist.h
#pragma once
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "element.h"
class linkedlist {
private:
element* head;
element* tail;
int nNum;
public:
linkedlist();
virtual ~linkedlist();
element* Gethead() { return head; }
void Sethead(element* val) { head = val; }
element* Gettail() { return tail; }
void Settail(element* val) { tail = val; }
void InsertFirst(element*);
void InsertTail(element*);
bool InsertAt(element*, int);
bool DeleteFirst();
bool DeleteTail();
bool DeleteAt(element*);
void Travel();
int SumList();
int MaxList();
int CountPrime();
int CountOccurrences(int);
void SplitList(int, linkedlist&, linkedlist&);
protected:
};
#endif // LINKEDLIST_H
//linkedlist.cpp
#include "linkedlist.h"
#include <iostream>
using namespace std;
linkedlist::linkedlist() {
//ctor
this->head = nullptr;
this->tail = nullptr;
this->nNum = 0;
}
linkedlist::~linkedlist() {
//dtor
}
void linkedlist::InsertFirst(element* e) {
if (this->head == nullptr)
this->head = this->tail = e;
else {
e->Setpointer(this->head); //step 1
this->head = e; // step 2
}
this->nNum++;
}
void linkedlist::InsertTail(element* e) {
if (this->head == nullptr)
this->head = this->tail = e;
else {
this->tail->Setpointer(e);// step 1
this->tail = e; // step 2
}
this->nNum++;
}
bool linkedlist::InsertAt(element* p, int value) {
if (p == nullptr) {
return false;
}
if (p == this->head) {
this->InsertFirst(newElement);
}
else {
newElement->Setpointer(p->Getpointer());
p->Setpointer(newElement);
if (p == this->tail) {
this->tail = newElement;
}
}
return true;
}
void linkedlist::Travel() {
element* p = this->head;
while (p != nullptr) {
cout << p->Getdata() << " ";
p = p->Getpointer();
}
cout << "\n";
}
bool linkedlist::DeleteFirst() {
if (this->head == nullptr) return false;
else {
element* p = this->head;
this->head = this->head->Getpointer();
delete p;
return true;
}
}
bool linkedlist::DeleteTail() {
if (this->head == nullptr) {
return false;
}
if (this->head == this->tail) {
delete this->head;
this->head = this->tail = nullptr;
}
else {
element* p = this->head;
while (p->Getpointer() != this->tail) {
p = p->Getpointer();
}
delete this->tail;
this->tail = p;
this->tail->Setpointer(nullptr);
}
this->nNum--;
return true;
}
bool linkedlist::DeleteAt(element* p) {
if (this->head == nullptr || p == nullptr) {
return false;
}
if (p == this->head) {
return this->DeleteFirst();
}
if (p == this->tail) {
return this->DeleteTail();
}
if (prev->Getpointer() == nullptr) {
return false;
}
this->nNum--;
return true;
}
int linkedlist::SumList() {
int sum = 0;
element* p = this->head;
while (p != nullptr) {
sum += p->Getdata();
p = p->Getpointer();
}
return sum;
}
int linkedlist::MaxList() {
if (this->head == nullptr) {
throw runtime_error("List is empty, no maximum value."); // Xử lý
danh sách rỗng
}
element* p = this->head;
int maxVal = p->Getdata();
while (p != nullptr) {
if (p->Getdata() > maxVal) {
maxVal = p->Getdata();
}
p = p->Getpointer();
}
return maxVal;
}
bool isPrime(int n) {
if (n < 2) return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
int linkedlist::CountPrime() {
int count = 0;
element* p = this->head;
while (p != nullptr) {
if (isPrime(p->Getdata())) count++;
p = p->Getpointer();
}
cout << endl;
return count;
}
int linkedlist::CountOccurrences(int x) {
int count = 0;
element* p = this->head;
while (p != nullptr) {
if (p->Getdata() == x) {
count++;
}
p = p->Getpointer();
}
return count;
}
//main.cpp
#include <iostream>
#include "linkedlist.h"
using namespace std;
int main() {
linkedlist* list_ = new linkedlist();
linkedlist smallerList;
linkedlist largerList;
element* e;
int x, y;
cout << "Nhap x (tim phan tu trung voi x): ";
cin >> x;
cout << "Nhap y (gia tri tach danh sach): ";
cin >> y;
cout << "\n";
// cau 4
e = new element(9);
list_->InsertTail(e);
e = new element(10);
list_->InsertTail(e);
e = new element(8);
list_->InsertTail(e);
// cau 5
list_->InsertFirst(e1);
list_->InsertFirst(e2);
// bo sung cau 10
list_->InsertAt(e1, 13);
list_->Travel();
// cau 1
cout << "Sum List: " << list_->SumList() << endl;
// cau 2
cout << "Max List: " << list_->MaxList() << endl;
// cau 3
cout << "Prime : " << list_->CountPrime() << endl;
// cau 9
cout << "So luong phan tu trung voi x: " << list_->CountOccurrences(x)
<< endl;
// cau 11
list_->SplitList(y, smallerList, largerList);
// cau 6
list_->DeleteFirst();
cout << "\n";
list_->Travel();
// cau 7
list_->DeleteTail();
cout << "\n";
list_->Travel();
// cau 8
list_->DeleteAt(e1);
cout << "\n";
list_->Travel();
return 0;
}
//Term.cpp
#include "Term.h"
Term::Term() {
this->heso = 0;
this->bac = 0;
this->next = nullptr;
}
Term::~Term(){
//dtor
}
//Polynomial.h
#pragma once
#include "Term.h"
class Polynomial
{
private:
Term* head;
public:
Polynomial();
virtual ~Polynomial();
void AddTerm(int heso, int bac);
void Input();
void Print() const; // In đa thức
double Evaluate(double x); // Tính giá trị đa thức
Polynomial Add(const Polynomial& other); // Cộng hai đa thức
Polynomial Multiply(const Polynomial& other); // Nhân hai đa thức
};
//Polynomial.cpp
#include "Polynomial.h"
#include <iostream>
using namespace std;
Polynomial::Polynomial() {
this->head = nullptr;
}
Polynomial::~Polynomial() {
//dtor
}
if (curr->getBac() == bac) {
curr->setHeso(curr->getHeso() + heso); // Gộp hệ số nếu bậc đã tồn tại
delete newTerm;
if (curr->getHeso() == 0) { // Xóa nút nếu hệ số bằng 0
Term* temp = curr->getNext();
delete curr;
curr = temp;
}
}
else {
newTerm->setNext(curr->getNext());
curr->setNext(newTerm);
}
}
}
void Polynomial::Input() {
int heso, bac;
cout << "Nhap da thuc (nhap he so = 0 de ket thuc):\n";
while (true) {
cout << "He so: ";
cin >> heso;
if (heso == 0) break;
AddTerm(heso, bac);
}
}
double Polynomial::Evaluate(double x) {
double result = 0.0;
Term* curr = head;
while (curr) {
result += curr->getHeso() * pow(x, curr->getBac());
curr = curr->getNext();
}
return result;
}
int main() {
Polynomial p1, p2;
Polynomial p3 = p1.Add(p2);
cout << "Tong 2 da thuc: ";
p3.Print();
Polynomial p4 = p1.Multiply(p2);
cout << "Tich 2 da thuc: ";
p4.Print();
return 0;
}
2.
//Book.h
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;
struct Book {
string title; // Tên sách
vector<string> authors; // Danh sách tác giả
string publisher; // Nhà xuất bản
int year; // Năm xuất bản
Book* next;
//Book.cpp
#include "Book.h"
//Libary.h
#pragma once
#include "Book.h"
class Library {
private:
Book* head; // Đầu danh sách liên kết
public:
Library() : head(nullptr) {}
~Library();
//Libary.cpp
#include "Libary.h"
Library::~Library() {
while (head) {
Book* temp = head;
head = head->next;
delete temp;
}
}
void Library::AddBook() {
string title, publisher, author;
int year, numAuthors;
cout << "Nhap ten sach: ";
getline(cin, title);
vector<string> authors;
for (int i = 0; i < numAuthors; ++i) {
cout << "Nhap ten tac gia: " << i + 1 << ": ";
getline(cin, author);
authors.push_back(author);
}
newBook->next = head;
head = newBook;
}
//main.cpp
#include "Book.h"
#include "Libary.h"
int main() {
Library library;
int choice;
do {
cout << "Menu:\n";
cout << "1. Them sach moi\n";
cout << "2. Liet ke danh sach cac sach\n";
cout << "3. Dem so sach cua mot tac gia\n";
cout << "4. Tim sach theo NXB và nam\n";
cout << "0. Thoat\n";
cout << "Nhap lua chon cua ban: ";
cin >> choice;
cin.ignore();
switch (choice) {
case 1:
library.AddBook();
break;
case 2:
library.ListBooks();
break;
case 3: {
string author;
cout << "Nhap ten tac gia: ";
getline(cin, author);
int count = library.CountBooksByAuthor(author);
cout << "So sach cua tac gia " << author << ": " << count << "\n";
break;
}
case 4: {
string publisher;
int year;
cout << "Nhap NXB: ";
getline(cin, publisher);
cout << "Nhap nam xuat ban: ";
cin >> year;
library.FindBooksByPublisherYear(publisher, year);
break;
}
case 0:
cout << "Thoat chuong trinh\n";
break;
default:
cout << "Khong hop le\n";
}
} while (choice != 0);
return 0;
}
#include "linkedlist.h"
#include <iostream>
class Stack {
private:
linkedlist* Linkedlist;
int nNum;
public:
Stack();
~Stack();
void push(int x);
int pop();
void printStack();
int isEmpty();
};
#endif
//Stack.cpp
#include "Stack.h"
using namespace std;
void Stack::push(int x) {
element* p = new element(x);
Linkedlist->InsertFirst(p);
nNum++;
}
int Stack::pop() {
if (Linkedlist->Gethead() == nullptr) {
cout << "STACK RONG, KHONG LAY DUOC PHAN TU" << endl;
return -1; // Nếu Stack rỗng, trả về -1
}
int p = Linkedlist->Gethead()->Getdata();
Linkedlist->DeleteFirst();
nNum--;
return p;
}
void Stack::printStack() {
if (Linkedlist->Gethead() == nullptr) {
cout << "STACK RONG" << endl;
return;
}
cout << "Cac phan tu trong Stack: ";
Linkedlist->Travel(); // Gọi phương thức travel() trong LinkedList để in các
phần tử
}
int Stack::isEmpty()
{
return this->Linkedlist->Gethead() == nullptr;
}
Stack::Stack() {
nNum = 0;
Linkedlist = new linkedlist();
}
Stack::~Stack() {
delete Linkedlist;
}
//Queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include "linkedlist.h"
#include <iostream>
class Queue {
private:
linkedlist* Linkedlist;
public:
Queue();
~Queue();
#endif
//Queue.cpp
#include "Queue.h"
using namespace std;
void Queue::enQueue(int x) {
element* p = new element(x);
Linkedlist->InsertTail(p);
}
int Queue::deQueue() {
if (Linkedlist->Gethead() == nullptr) {
cout << "QUEUE RONG, KHONG LAY DUOC PHAN TU" << endl;
return -1; // Nếu Queue rỗng, trả về -1
}
int p = Linkedlist->Gethead()->Getdata();
Linkedlist->DeleteFirst();
return p;
}
void Queue::printQueue() {
if (Linkedlist->Gethead() == nullptr) {
cout << "QUEUE RONG" << endl;
return;
}
cout << "Cac phan tu trong Queue: ";
Linkedlist->Travel(); // Gọi phương thức travel() trong LinkedList để in các
phần tử
}
Queue::Queue() {
Linkedlist = new linkedlist();
}
Queue::~Queue() {
delete Linkedlist;
}
//main.cpp
#include <iostream>
#include "Stack.h"
#include "Queue.h"
using namespace std;
int main() {
// Test Stack
Stack stack;
int value;
// Test Queue
Queue queue;
return 0;
}
Nâng cao
//Stack.cpp
#include "Stack.h"
using namespace std;
void Stack::push(int x) {
element* p = new element(x);
Linkedlist->InsertTail(p);//1
nNum++;
}
int Stack::pop() {
if (Linkedlist->Gethead() == nullptr) {
cout << "STACK RONG, KHONG LAY DUOC PHAN TU" << endl;
return -1; // Nếu Stack rỗng, trả về -1
}
int p = Linkedlist->Gethead()->Getdata();
Linkedlist->DeleteTail();
nNum--;
return p;
}
void Stack::printStack() {
if (Linkedlist->Gethead() == nullptr) {
cout << "STACK RONG" << endl;
return;
}
cout << "Cac phan tu trong Stack: ";
Linkedlist->Travel(); // Gọi phương thức travel() trong LinkedList để in các
phần tử
}
int Stack::isEmpty()
{
return this->Linkedlist->Gethead() == nullptr;
}
Stack::Stack() {
nNum = 0;
Linkedlist = new linkedlist();
}
Stack::~Stack() {
delete Linkedlist;
}
//Queue.cpp
#include "Queue.h"
using namespace std;
void Queue::enQueue(int x) {
element* p = new element(x);
Linkedlist->InsertTail(p);
}
int Queue::deQueue() {
if (Linkedlist->Gethead() == nullptr) {
cout << "QUEUE RONG, KHONG LAY DUOC PHAN TU" << endl;
return -1; // Nếu Queue rỗng, trả về -1
}
int p = Linkedlist->Gethead()->Getdata();
Linkedlist->DeleteFirst();
return p;
}
void Queue::printQueue() {
if (Linkedlist->Gethead() == nullptr) {
cout << "QUEUE RONG" << endl;
return;
}
cout << "Cac phan tu trong Queue: ";
Linkedlist->Travel(); // Gọi phương thức travel() trong LinkedList để in các
phần tử
}
Queue::Queue() {
Linkedlist = new linkedlist();
}
Queue::~Queue() {
delete Linkedlist;
}
//main.cpp
#include <iostream>
#include "Stack.h"
using namespace std;
void convertToBinary(int n) {
Stack stack;
while (n > 0) {
int remainder = n % 2;
stack.push(remainder); // Đay phan du vao Stack
n = n / 2; // Chia n cho 2
}
int main() {
int number;
cout << "Nhap mot so tu he co so 10: ";
cin >> number;
convertToBinary(number);
return 0;
}
2.
Stack:
- Thao tác push và pop lần lượt thực hiện chèn và xóa phần tử ở đầu danh sách
liên kết.
+ Ưu điểm:
Các thao tác thêm (push) và xóa (pop) diễn ra nhanh chóng với độ phức
tạp O(1).
Không cần di chuyển các phần tử khác trong danh sách.
+ Nhược điểm:
Mất thêm không gian để quản lý con trỏ của từng nút (điểm đặc trưng của
danh sách liên kết).
- Sử dụng danh sách liên kết nhưng thao tác push thêm phần tử vào cuối danh
sách liên kết và thao tác pop lấy phần tử từ cuối danh sách liên kết.
+ Ưu điểm:
Cách tiếp cận này mô phỏng đúng hơn cách hoạt động thực tế của stack
(phần tử thêm cuối là phần tử được xóa đầu tiên - LIFO).
+ Nhược điểm:
Thao tác pop từ cuối danh sách liên kết có thể tốn thêm thời gian nếu
phải duyệt từ đầu danh sách để tìm phần tử cuối (độ phức tạp O(n) nếu
không có con trỏ tail).
Đòi hỏi thêm thao tác để quản lý con trỏ cuối.
Queue:
- Thao tác enqueue thêm phần tử vào cuối danh sách và dequeue lấy phần tử
từ đầu danh sách.
+ Ưu điểm:
Cách cài đặt này đảm bảo các thao tác enqueue và dequeue thực hiện
nhanh chóng, với độ phức tạp O(1) khi sử dụng con trỏ tail để quản lý
phần tử cuối danh sách.
Phù hợp với cấu trúc dữ liệu queue (FIFO - phần tử thêm trước được xử
lý trước).
+ Nhược điểm:
Phụ thuộc vào việc duy trì cả con trỏ đầu và con trỏ cuối để đảm bảo hiệu
năng.
- Sử dụng danh sách liên kết nhưng thao tác enqueue thêm phần tử vào đầu
danh sách liên kết và dequeue lấy phần tử từ cuối danh sách liên kết.
+ Ưu điểm:
Dễ cài đặt vì chỉ cần thao tác trên danh sách liên kết một chiều mà không
cần quản lý thêm con trỏ tail.
+ Nhược điểm:
Thao tác dequeue từ cuối danh sách liên kết có thể tốn thời gian hơn (độ
phức tạp O(n) nếu phải duyệt danh sách để tìm phần tử cuối).
Không tuân thủ chặt chẽ với bản chất của queue vì việc lấy phần tử từ
cuối danh sách có thể tạo cảm giác ngược với FIFO (đặc biệt khi không
sử dụng thêm con trỏ tail).
bool canReach(const vector<vector<int>>& matrix, int x1, int y1, int x2, int y2)
{
int rows = matrix.size();
int cols = matrix[0].size();
// Kiểm tra tính hợp lệ của ô bắt đầu và ô đích
if (x1 < 0 || x1 >= rows || y1 < 0 || y1 >= cols || x2 < 0 || x2 >= rows || y2 < 0 ||
y2 >= cols)
return false;
if (matrix[x1][y1] == 0 || matrix[x2][y2] == 0)
return false;
while (!q.empty()) {
auto [x, y] = q.front();
q.pop();
// Duyệt các ô kề
for (auto [dx, dy] : directions) {
int nx = x + dx;
int ny = y + dy;
int main() {
vector<vector<int>> matrix = {
{1, 0, 1, 1},
{1, 1, 0, 1},
{0, 1, 1, 1},
{1, 0, 0, 1}
};
return 0;
}