Tải bản đầy đủ (.docx) (16 trang)

Bài Tập Và Lời Giải ( Code ) Môn Cấu Trúc Dữ Liệu Và Giải Thuật Nâng Cao

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (76.43 KB, 16 trang )

Bài tâp 1: Viet chuong trinh dinh nghia cau truc stack voi cac thao tac
tuong ung
Su dung cau truc stack va cac thao tac da cai dat de luu tru n so nguyen
duoc nhap tu ban phim . Lay cac gia tri ra khoi stack va hien thi ra man
hinh.
Bài tập 2 : Tìm kiếm theo chiều rộng
Bài tập 3 : Thuật toán tìm kiếm A*
Bài tập 4: Thuật toán Best First Search
Bài tập 5: Thuật toán nhánh cận ( Bài tập : Người du lịch )
Lời Giải Bài 1 : Viet chuong trinh dinh nghia cau truc stack voi cac thao tac tuong ung
Su dung cau truc stack va cac thao tac da cai dat de luu tru n so nguyen duoc nhap tu
ban phim
Lay cac gia tri ra khoi stack va hien thi ra man hinh.
CODE:
#include <iostream>
#include <conio.h>
using namespace std;
#define MAX 100
// Tao Node
struct Node{
int data;
Node* next;
};
// Tao cau truc ngan xep
struct Stack{
Node* top;
};
// Khoi tao ngan xep
void Init(Stack &s){
s.top = NULL;
}


// Kiem tra rong
int IsEmpty(Stack s){
if (s.top==NULL)
return 1;
return 0;
}
// Tao nut
Node* createnode(int x){
Node* p=new Node;
if(p==NULL) return NULL;
p->data=x;


p->next=NULL;
return p;
}
// Dau vao
void Push(Stack &s, int x){
Node* p=createnode(x);
if (IsEmpty(s)==1)
s.top=p;
else {
p->next=s.top;
s.top=p;
}
}
// dau ra
int Pop(Stack &s){
int x;
Node* p=s.top;

if (IsEmpty(s)==1)
return 0;
x=p->data;
s.top=s.top->next;
delete p;
return x;
}
int Search(Stack s, int x){
for (Node* p=s.top; p!=NULL; p=p->next)
if (p->data==x)
return 1;
return 0;
}

#define SIZE 7
const int X = 32767;
char Label[7] = {'A','B','C','D','E','F','G'};
int main(){
int T[7][7] = {{0, 1, 1, X, X, X, X},
{1, 0, X, 1, 1, X, X},
{1, X, 0, X, X, 1, 1},
{X, 1, X, 0, X, X, X},
{X, 1, X, X, 0, X, X},
{X, X, 1, X, X, 0, X},
{X, X, 1, X, X, X, 0}};
int u, v, start = 0, goal = 5, ok=0;
int Close[SIZE]={0}; // Chua dinh nao duoc phat trien


int Father[SIZE]; //Father[i] = chi so dinh cha cua i

Stack OP;
Init(OP);
Push(OP, start);
while (!IsEmpty(OP)){
//lay u la trang thai o dau hang doi
u = Pop(OP);
//Kiem tra u co phai trang thai dich
if (u==goal){
ok = 1;
break;
}
//Luu u vao danh Close - de xac dinh u da duoc phat trien
Close[u] = 1;
//xet lan luot con v cua u
for (v=SIZE; v>=0; v--)
if (T[u][v]==1)
if (Search(OP, v)==0 && Close[v]==0){
Push(OP, v);
Father[v] = u;
}
}
if (ok==1){
cout << "Duong di la: " << endl;
while (u!=start){
cout << Label[u] << "<--";
u = Father[u];
}
cout << Label[start] << endl;
}
}

Bài tập 2 : Tìm kiếm theo chiều rộng
#include <iostream>
using namespace std;
//Dinh nghia cau truc hang doi va cac thao tac tren do
#define MAX 100
struct Node{
int data;
Node *next;
};
struct Queue{
Node *pHead;
Node *pTail;
};
// Khoi tao
void Init(Queue &q){


q.pHead=q.pTail=NULL;
}
// Tao nut
Node *taonut(int x){
Node *p=new Node;
if (p==NULL) return NULL;
p->data=x;
p->next=NULL;
return p;
}
// Them vao cuoi
void Add(Queue &q, Node *p){
if(q.pHead==NULL) q.pHead=q.pTail=p;

else{
q.pTail->next=p;
q.pTail=p;
}
}
// Xoa hang doi
int Remove(Queue &q){
if (q.pHead==NULL){
cout << "Hang doi rong!";
return 0;
}
Node *p=q.pHead;
int x= p->data;
q.pHead=q.pHead->next;
delete p;
return x;
}
// Tim kiem hang doi
int Search(Queue q, int x){
Node *p;
for (p=q.pHead; p!=NULL; p=p->next)
if (p->data==x)
return 1;
return 0;
}
// Huy hang doi
void huy(Queue &q){
while(q.pHead!=NULL){
Node *p=q.pHead;
q.pHead=q.pHead->next;

delete p;
}
q.pTail==NULL;


}
const int X = 32767;
char Label[7] = {'A','B','C','D','E','F','G'};
int main(){
int T[7][7] = {{0, 1, 1, X, X, X, X},
{1, 0, X, 1, 1, X, X},
{1, X, 0, X, X, 1, 1},
{X, 1, X, 0, X, X, X},
{X, 1, X, X, 0, X, X},
{X, X, 1, X, X, 0, X},
{X, X, 1, X, X, X, 0}};
int u, v, start = 0, goal = 3, ok=0;
int Close[7]={0}; // Chua dinh nao duoc phat trien
int Father[7]; //Father[i] = chi so dinh cha cua i
Queue OP;
Init(OP);
Node *p =taonut(start);
Add(OP, p);
while (OP.pHead!=NULL){
//lay u la trang thai o dau hang doi
u = Remove(OP);
//Kiem tra u co phai trang thai dich
if (u==goal){
ok = 1;
break;

}
//Luu u vao danh Close - de xac dinh u da duoc phat trien
Close[u] = 1;
//xet lan luot con v cua u
for (v=0; v<7; v++)
if (T[u][v]==1)
if (Search(OP,v)==0 )
if (Close[v]==0){
Node *q=taonut(v);
Add(OP, q);
Father[v] = u;
}
}
if (ok==1){
cout << "Duong di la: " << endl;
while (u!=start){
cout << Label[u] << "<--";
u=Father[u];
}
cout << Label[start] << endl;


}
huy(OP);
}

Bài tập 3: Thuật toán tìm kiếm A*
1.
2.
3.

4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.

34.
35.
36.
37.
38.
39.
40.
41.
42.

#include <fstream>
#include <iostream>
using namespace std;
struct Node
{
int stt;// so thu tu
int g; // khoang cach tu dinh ban dau den dinh hien taị
int f; // f = h + g;
int h;// duong di ngan nhat
int color; // danh dau dinh di qua
int dad; // dinh cha
};
int a[100][100];
Node p[100];
Node Open[100];
Node Close[100];
void ReadfileInput1(int *b, int &n)
{
fstream myfile("Input1.txt");
if (!myfile.is_open())

{
cout << "Khong the mo duoc file" << endl;
}
else
{
myfile >> n;
for (int i = 0; i < n; i++)
{
myfile >> b[i];
}
}
}
void ReadfileInput2(int a[100][100], int &n, int &start, int &finsh)
{
fstream shichiki("Input2.txt");
if (!shichiki.is_open())


43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.

55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.

85.
86.
87.
88.
89.
90.

{
cout << "Khong the mo duoc file !";
}
else
{
shichiki >> n >> start >> finsh;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
shichiki >> a[i][j];
}
}
shichiki.close();
}
void printfmaxtric(int a[100][100], int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << a[i][j] << "\t";
}
cout << "\n";

}
}
int Count(int n, Node *Open)
{
int count = 0;
for (int i = 0; i < n; i++)
{
if (Open[i].color == 1)
count++;
}
return count;
}
int Find(int n, Node *Open)
{
for (int i = 0; i < n; i++)
if (Open[i].color == 1)
return i;
}
int Findmin(int n, Node *Open)


91. {
92.
93.
94.
95.
96.
97.
98.
99.

100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.

130.
131.
132.
133.
134.

int min1 = Find(n, Open);
int min = Open[min1].f;
for (int i = 0; i < n; i++)
{
if (Open[i].f < min && Open[i].color == 1)
{
min1 = i;
min = Open[i].f;
}
}
return min1;
}
void Init(int n, int *b)
{
for (int i = 0; i < n; i++)
{
p[i].stt = i;
p[i].color = 0;
p[i].g = b[i];
p[i].dad = 0;
p[i].f = p[i].g;
p[i].h = 0;
}
}

int Findpoint(int n, Node *q, int o)
{
for (int i = 0; i < n; i++)
if (q[i].stt == o)
return i;
}
void AStar(int a[100][100], int n, int start, int finsh, int b[])
{
int l = 0;
Open[l] = p[start];
Open[l].color = 1;
Open[l].f = Open[l].h + Open[l].g;
l++;
int w = 0;
while (Count(l, Open) != 0) // kiem tra xem tap Open co con phan tu

nao khong
135.
136.
137.

{
int k = Findmin(n, Open); // tim vi tri nho nhat trong Open
Open[k].color = 2; // cho diem tim duoc vao Close


Close[w] = Open[k];
Close[w].color = 2;
w++;
p[Findpoint(n, p, Open[k].stt)].color = 2;

if (Findpoint(n, p, Open[k].stt) == finsh)
{
cout << "Duong di qua la" << endl;
cout << finsh << "\t";
int y = Findpoint(w, Close, finsh);
int u = Close[y].dad;
while (u != start)
{
y = Findpoint(w, Close, u);
u = Close[y].dad;
cout << u << "\t";
}
break;
}
else
{
for (int i = 0; i < n; i++)
{
if (a[Findpoint(n, p, Open[k].stt)][i] != 0 &&
p[i].color == 0) // neu chua co trong Open va Close
161.
{
162.
Open[l] = p[i];
163.
Open[l].color = 1;
164.
Open[l].h = a[Findpoint(n, p,
Open[k].stt)][i] + Open[k].h; // tinh h khoang cach ngan nhat tu dinh bat dau den dinh
hien tai

165.
Open[l].f = Open[l].g + Open[l].h;
166.
Open[l].dad = Findpoint(n, p,
Open[k].stt);
167.
p[i].color = 1;
168.
l++;
169.
}
170.
if (a[Findpoint(n, p, Open[k].stt)][i] != 0 &&
p[i].color == 1) // neu dinh da co trong open
171.
{
172.
int h = Findpoint(l, Open, p[i].stt);
173.
Node tam = p[i];
174.
tam.color = 1;
175.
tam.h = a[Findpoint(n, p, Open[k].stt)][i]
+ Open[k].h;
176.
tam.dad = k;
177.
tam.f = tam.h + tam.g;
178.

if (tam.f < Open[h].f) //neu f trang thai
hien tai be hon trang thai cap nhat truoc do
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.


Open[h] = tam;

179.

180.
181.

}
if (a[Findpoint(n, p, Open[k].stt)][i] != 0 &&
p[i].color == 2) // neu dinh da co trong Close
182.
{
183.
int h = Findpoint(l, Close, p[i].stt);
184.
Node tam = p[i];
185.
tam.color = 1;
186.
tam.h = a[Findpoint(n, p, Open[k].stt)][i]
+ Open[k].h;
187.
tam.dad = k;
188.
tam.f = tam.h + tam.g;
189.
if (tam.f < Close[h].f) //neu f trang thai
hien tai be hon trang thai truoc do
190.
{
191.
Open[l] = tam; // them vao Open
192.
Close[h].color = 1; //danh dau

dinh do thuoc Open
193.
l++;
194.
}
195.
}
196.
}
197.
}
198.
}
199.
}
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.

215.
216.
217.
218.
219.

int main()
{
int n;
int start;
int finish;
int b[100];
ReadfileInput2(a, n, start, finish);
ReadfileInput1(b, n);
Init(n, b);
cout << "Dinh bat dau" << endl;
cout << start << endl;
cout << "Dinh ket thuc" << endl;
cout << finsh << endl;
AStar(a, n, start, finish, b);
return 0;
}

Bài tập 4 : Thuật toán Best First Search


1.
2.
3.
4.

5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.

35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.

#include <stdio.h>
#include <queue>
#include <conio.h>
using namespace std;
// dinh nghia lop do thi
class Graph
{
private:
int n;
int **edge;
public:
Graph(int size = 2);
~Graph();
bool isConnected(int, int);
void addEdge(int, int);

void breadthFirstSearch(int, int);
};
Graph::Graph(int size)
{
int i, j;
// xac dinh so dinh cua do thi
if (size < 2)
n = 2;
else
n = size;
// tao ra cac dinh trong do thi
edge = new int*[n];
for (i = 0; i < n; i++)
edge[i] = new int[n];
// mac dinh giua cac dinh khong co ket noi voi nhau (= 0)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
edge[i][j] = 0;
}
Graph::~Graph()
{
for (int i = 0; i < n; ++i)
delete[] edge[i];
delete[] edge;
}
// kiem tra giua hai dinh co ke nhau hay khong


49.
50.

51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.

81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.

bool Graph::isConnected(int x, int y)
{
if (edge[x - 1][y - 1] == 1)
return true;
return false;
}
// tao canh noi giua hai dinh, lam cho hai dinh ke nhau
void Graph::addEdge(int x, int y)
{
if (x < 1 || x > n || y < 1 || y > n)
return;
edge[x - 1][y - 1] = edge[y - 1][x - 1] = 1;
}

void Graph::breadthFirstSearch(int s, int g)
{
if (s > n || s < 0 || g > n || g < 0)
{
printf("Could not traverse this graph with your request\n");
return;
}
queue <int> open;
bool *close = new bool[n];
int i;
int p;
// mac dinh cac dinh chua duoc duyet
for (i = 0; i < n; i++)
close[i] = false;
// dua dinh goc s vao queue open, chuan bi duyet
open.push(s);
printf("With Breadth first Search , we have vertex(s):\n");
while (!open.empty())
{
// lay mot dinh ra khoi open tro thanh dinh dang xet p
do
{
if (open.empty())
break;
p = open.front();
open.pop();


} while (close[p - 1] == true);


97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.

// in ra dinh dang xet
printf("%d ", p);
// p da duyet qua
close[p - 1] = true;
// ket thuc duyet khi tim ra ket qua can tim
if (p == g)
break;
// tim dinh ke voi dinh dang xet, dinh nao chua duoc duyet dua

vao open
110.
111.
112.
113.
114.
115.

116.
117.
118.
119.
120.
121.

for (i = 1; i <= n; i++)
{
if (isConnected(p, i) && !close[i - 1])
{
open.push(i);
}
}
}
printf("\n");
delete[] close;
}

void main()
1. {
2.
// khoi tao do thi
3.
Graph g(9);
4.
5.
// tao canh noi giua cac dinh ke
6.
g.addEdge(1, 2);

7.
g.addEdge(1, 3);
8.
g.addEdge(1, 4);
9.
g.addEdge(2, 5);
10.
g.addEdge(2, 6);
11.
g.addEdge(3, 4);
12.
g.addEdge(3, 5);
13.
g.addEdge(3, 7);
14.
g.addEdge(3, 8);
15.
g.addEdge(3, 9);
16.
17. // duyet bang Breadth First Search
18.
g.breadthFirstSearch(1, 8);
19. }


Bài tập 5 : Thuật toán nhánh cận ( Bài tập : Người du lịch )
#include<iostream>
using namespace std;
const int size = 20;
int maxE = 100;

int maxC = size * maxE;
int C[size][size]; //Ma trận chi phí


int X[size+1]; //X đểthửcác khảnăng, BestWay đểghi nhận nghiệm
int T[size]; //T[i] đểlưu chi phí đi từX[1] đến X[i]
int BestWay[size+1]; //, BestWay để ghi nhận nghiệm
bool FREE[size]; //Free để đánh dấu, Free[i]= True nếu chưa đi qua tp i
int minSpending; //Chi phí hành trình tối ưu
int M,N;
void input()
{
int i,j,k;
cin >> N; //Nhap so thanh pho
cin >> M; //Nhap so duong
for ( i = 1; i <= N; i++ ) //Khởi tạo bảng chi phí ban đầu
{
for ( j = 1; j <= N; j++ )
{
if ( i == j ) C[i][j] = 0;
else C[i][j] = maxC;
}
}
for ( int k = 1; k <= M; k++ )
{
cin >> i; //Nhap thanh pho bat dau
cin >> j; //Nhap thanh pho den
cin >> C[i][j]; //Nhap gia di tu thanh pho i den j
C[j][i] = C[i][j]; //Chi phí như nhau trên 2 chiều
}

}
void init()
{
for ( int i = 0; i <= N; i++ )
FREE[i] = true;
FREE[1] = false; //Các thành phố là chưa đi qua ngoại trừ thành phố 1
X[1] = 1; //xuat phat tu thanh pho 1
T[1] = 0; //Chi phí tại thành phố xuất phát là 0
minSpending = maxC;
}
void output()
{
if ( minSpending == maxC )
cout << "NO SOLUTION ";
else
{
for ( int i = 1; i <= N; i++ )


cout << BestWay[i] << "->";
cout << "1" << endl;
cout << "Cost : " << minSpending;
}
}
void tim(int i) //Thử các cách chọn xi
{
for ( int j = 2; j <= N; j++ ) //Thử các thành phố từ 2 đến n
{
if (FREE[j]) //Nếu gặp thành phố chưa đi qua
{

X[i] = j;
T[i] = T[i-1] + C[X[i-1]][j]; //Chi phí = Chi phí bước trước + chi phí đường đi trực tiếp
if ( T[i] < minSpending ) //Hiển nhiên nếu có điều này thì C[x[i - 1], j] < +∞ rồi
{
FREE[j] = false; //Đánh dấu thành phố vừa thử
if(i == N)
{
if ( ( T[N] + C[X[N]][1] ) < minSpending ) // Từx[n] quay lại 1 vẫn tốn chi phí ít
hơn trước
{
for ( int i = 0; i <= N; i++ ) // Cập nhật BestConfig
BestWay[i] = X[i];
minSpending = T[N] + C[X[N]][1];
}
}
else tim( i + 1 ); // Tìm các khả năng chọn x[i+1]
FREE[j] = true; // Bỏ đánh dấu
}
}
}
}
int main()
{
input();
init();
tim(2);
output();
}




×