BÀI TẬP LỚN CẤU TRÚC DỮ LIỆU VÀ
GIẢI THUẬT
Đề tài: Đồ thị và bài toán cây khung cực tiểu.
Sinh Viên
1.Trần Văn Toàn
Lớp
Tin5-K53
MSSV
20082715
2.Nguyễn Khánh Hưng
Tin5-K53
20081279
3.Trần Đức Việt
Tin5-K53
20083159
4.Nguyễn Đình Mẫn
20071933
5.Nguyễn Trọng Nghĩa
20052338
A.Giới thiệu chương trình
1.Nội dung
+Tạo lập đồ thị vô hướng liên thông và luu dữ liệu đồ thị.
+Hiển thị thông tin đồ thị.
+Hiển thị trọng số một cạnh của đồ thị.
+Bổ sung một cạnh vào đồ thị.
+Bổ sung một đỉnh vào đồ thị.
+Tìm cây khung cực tiểu.
1
2.Cài đặt
Bao gồm: các hàm
+int ghi_file();
+int doc_file();
+int MakeHeap(float *A, int i, int n);
+int InsertEdge();
+int InsertVertex();
+int GetWeight();
+int Kruskal();
3. So sánh giải thuật Kruskal và Prim.
Thuật toán
Bộ nhớ
Thời gian
Kruskal
Prim
n+m
n^2
0(m(log m+log n))
Áp dụng
Đồ thị thưa
(số cạnh
( n : số đỉnh ; m : số cạnh )
Input: 5
Output:
6
5
1
7.5
(1,3); (5,1); (2,4); (1,4);
1
4
9.2
Sum=4.5+7.5+8.3+9.2=29.5.
1
3
4.5
2
4
8.3
5
3
11.5
4
5
13
2
0(n^2)
Đồ thị đầy đủ
CODE:
/*--------BAI TOAN TIM CAY KHUNG CUC TIEU--------------*/
#include <conio.h>
#include <stdio.h>
/*---------------------------------------------------------------------*/
int ghi_file();
int doc_file();
int MakeHeap(float *A,int i,int n);
int InsertEdge();
int InsertVertex();
int GetWeight();
int Kruskal();
/*--------------------------------------------------------------------*/
typedef struct ds{
int dau,cuoi;
float ts;
};ds dt[100];
int n,m,temp,Dau[100],Cuoi[100],Index[100],K_Dau[100],K_Cuoi[100];
3
float D[100],tg;
//========NHAP THONG TIN DO THI VA LUU VAO FILE ========//
int ghi_file()
{
FILE *f;char c[10];
int i;
printf ("\n NHAP THONG SO DO THI: ");
printf("\n Nhap so dinh: n= ");scanf("%d",&n);
printf("\n Nhap so canh: m= ");scanf("%d",&m);
printf("\n Nhap danh sach canh: ");
for(i=1;i<=m;i++)
{
printf("\n +Canh %d : \n",i);
printf(" Dinh dau: ");scanf("%d",&dt[i].dau);
printf(" Dinh cuoi: ");scanf("%d",&dt[i].cuoi);
printf(" Trong so canh %d - %d : ",dt[i].dau,dt[i].cuoi);
scanf("%f",&dt[i].ts);
}
printf("\n Danh sach canh:");
for(i=1;i<=m;i++)
{
4
printf("\n %d - %d : %6.2f",dt[i].dau,dt[i].cuoi,dt[i].ts);
}
printf("\n Nhap ten file muon luu(ten_file.TXT): ");
scanf("%s",&c);
f=fopen(c,"w");
fprintf(f,"%3d%3d\n",n,m);
for(i=1;i<=m;i++)
{
fwrite(dt+i,sizeof(ds),1,f);
}
fclose(f);
return 1;
}
//========== DOC THONG TIN DO THI TU FILE ===========//
int doc_file()
{
FILE *f;char c[10];
int i;
printf("\n Nhap ten file(ten_file.TXT): " );
scanf("%s",&c);
f=fopen(c,"r");
fscanf(f,"%3d%3d\n",&n,&m);
5
for(i=1;i<=n;i++)
Index[i]=0;
for(i=1;i<=m;i++)
{
fread(dt+i,sizeof(ds),1,f);
}
for(i=1;i<=m;i++)
{
Dau[i]=dt[i].dau;
Cuoi[i]=dt[i].cuoi;
D[i]=dt[i].ts;
}
fclose(f);
return 1;
}
//========BO SUNG MOT CANH VAO DO THI=====//
int InsertEdge()
{
FILE *f;char c[10];
int i;
int s, d,dem=0;
float w;
6
printf("\n Nhap dinh dau canh bo sung: ");
scanf("%d",&s);
printf("\n Nhap dinh cuoi canh bo sung: ");
scanf("%d",&d);
printf("\n Nhap trong so canh bo sung: ");
scanf("%f",&w);
for(i=1;i<=m;i++)
{
if(((dt[i].dau==s)&&(dt[i].cuoi==d))||
((dt[i].dau==d)&&(dt[i].cuoi==s)))
{
dem++;
printf("\n Canh da ton tai");
}
else {
dt[m+1].dau=s;dt[m+1].cuoi=d;dt[m+1].ts=w;
}
}
if(!dem){
printf("\n Nhap lai ten do thi(ten_file.TXT): ");
scanf("%s",&c);
f=fopen(c,"w");
7
fprintf(f,"%3d%3d\n",n,m+1);
for(i=1;i<=m+1;i++)
{
fwrite(dt+i,sizeof(ds),1,f);
}
}
fclose(f);
return 1;
}
//========BO SUNG MOT DINH VAO DO THI=====//
int InsertVertex()
{
FILE *f;char c[10];
int dinh,i;
printf("\n Nhap dinh muon bo sung: ");
scanf("%d",&dinh);
if(dinh>0&&dinh<=n)
printf("\n Dinh da ton tai");
else{
printf("\n Nhap lai ten do thi(ten_file.TXT): ");
scanf("%s",&c);
f=fopen(c,"w");
fprintf(f,"%3d%3d\n",n+1,m);
8
for(i=1;i<=m;i++)
{
fwrite(dt+i,sizeof(ds),1,f);
}
}
fclose(f);
return 1;
}
//==== HIEN THI TRONG SO MOT CANH========//
int GetWeight()
{
int i,s,d,dem=0;
printf("\n Nhap dinh dau: ");scanf("%d",&s);
printf("\n Nhap dinh cuoi: ");scanf("%d",&d);
for(i=1;i<=m;i++)
{
if(((Dau[i]==s)&&(Cuoi[i]==d))||((Dau[i]==d)&&(Cuoi[i]==s))){
dem++;
printf("\n Trong so cua canh %d - %d : %f",s,d,D[i]);}
}
if(dem==0) printf("\n Canh khong ton tai");
return 1;
9
}
//=====HIEN THI THONG TIN DO THI ========//
int print()
{
printf("\n THONG TIN DO THI");
printf("\n So dinh cua do thi n= %d",n);
printf("\n So canh cua do thi m= %d",m);
printf("\n\n Danh sach canh:\n");
for(int i=1;i<=m;i++)
printf(" %d - %d : %6.2f\n",Dau[i],Cuoi[i],D[i]);
return 1;
}
//=========== VUN DONG ================//
int MakeHeap(float *D,int i,int m)
{
int temp,j=2*i;
float key=D[i];
while(j<=m)
{
if((j<m)&&(D[j]>D[j+1]))
j=j+1;
if(key<=D[j])
10
return 1;
else
{
D[j/2]=D[j];
D[j]=key;
temp=Dau[j];
Dau[j]=Dau[j/2];
Dau[j/2]=temp;
temp=Cuoi[j];
Cuoi[j]=Cuoi[j/2];
Cuoi[j/2]=temp;
j=j*2;
}
}
return 1;
}
//========= GIAI THUAT KRUSKAL ========//
int Kruskal()
{
11
int t, i, j, count, temp1, temp2;
float sum=0;
t=1;
i=m-1;
count=1;
for(j=m/2;j>=1;j--)
MakeHeap(D,j,m);
while(t<=n-1)
{
if((Index[Dau[1]]!=Index[Cuoi[1]]))
// Kiem tra xem canh bo sung co tao thanh chu trinh khong qua chi so Index cua
dinh
{
K_Dau[t]=Dau[1];
K_Cuoi[t]=Cuoi[1];
t++;
if(Index[Dau[1]]>Index[Cuoi[1]])
{
temp1=Index[Dau[1]];
temp2=Index[Cuoi[1]];
12
// danh dau cac dinh trong cung mot cay cung mot chi so.
for(j=1;j
{
if(Index[K_Dau[j]]==temp2)
Index[K_Dau[j]]=temp1;
if(Index[K_Cuoi[j]]==temp2)
Index[K_Cuoi[j]]=temp1;
}
}
if(Index[Dau[1]]<=Index[Cuoi[1]])
{
temp1=Index[Cuoi[1]];
temp2=Index[Dau[1]];
// danh dau cac dinh trong cung mot cay cung mot chi so.
for(j=1;j
{
if(Index[K_Dau[j]]==temp2)
Index[K_Dau[j]]=temp1;
if(Index[K_Cuoi[j]]==temp2)
Index[K_Cuoi[j]]=temp1;
}
13
}
}
if((Index[Dau[1]]==0)&&(Index[Cuoi[1]]==0)) // Truong hop hai dinh tu do chua
tham gia vao cay nao
{
K_Dau[t]=Dau[1];
K_Cuoi[t]=Cuoi[1];
t++;
// Danh chi so cay khung .
Index[Dau[1]]=count;
Index[Cuoi[1]]=count;
count++;
}
// Tao lai dong .
tg=D[1];
D[1]=D[i+1];
D[i+1]=tg;
temp1=Dau[1];
Dau[1]=Dau[i+1];
Dau[i+1]=temp1;
14
temp1=Cuoi[1];
Cuoi[1]=Cuoi[i+1];
Cuoi[i+1]=temp1;
MakeHeap(D,1,i);
i--;
}
// Hien thi cay khung nho nhat.
printf("\n Cac canh cua cay khung nho nhat");
for(j=1;j
printf("\n %d-%d",K_Dau[j],K_Cuoi[j]);
for(int k=1;k<=m;k++)
for(j=1;j
{
if((Dau[k]==K_Dau[j])&&(Cuoi[k]==K_Cuoi[j]))
sum+=D[k];
}
printf("\n Tong trong so: %6.2f",sum);
return 1;
}
//======= CHUONG TRINH CHINH==============//
int main()
15
{
int chon;
printf("
º
printf("
--- Lap Trinh C ---
º\n");
TIM KHUNG CAY CUC TIEU TREN DO THI
printf("
º
º\n");
printf("
\n");
while(1){
printf("\n -----------MENU----------------------------");
printf("\n 1.TAO LAP DO THI VO HUONG") ;
printf("\n 2.HIEN THI THONG TIN DO THI");
printf("\n 3.HIEN THI TRONG SO MOT CANH");
printf("\n 4.BO SUNG MOT CANH VAO DO THI");
printf("\n 5.BO SUNG MOT DINH VAO DO THI");
printf("\n 6.TIM CAY KHUNG CUC TIEU");
printf("\n 7.XOA MAN HINH");
printf("\n 8.STOP");
printf("\n Chon: ");scanf("%d",&chon);
switch(chon){
case 1: ghi_file();break;
case 2: doc_file();
print();break;
case 3: doc_file();
GetWeight();break;
16
\n");
case 4: doc_file();
InsertEdge();break;
case 5: doc_file();
InsertVertex();break;
case 6: doc_file();
Kruskal();break;
case 7: clrscr();break;
case 8: printf("\n Chuong trinh da dung");return 0;break;
default : printf("\n Khong co chuc nang nay");break;
}
}
getch();
}
17