1. 程式人生 > >實驗四(建圖,無向圖+鄰接矩陣(BFS,DFS(遞迴+非遞迴)),有向圖+鄰接表(BFS,DFS(遞迴+非遞迴)),拓撲排序)

實驗四(建圖,無向圖+鄰接矩陣(BFS,DFS(遞迴+非遞迴)),有向圖+鄰接表(BFS,DFS(遞迴+非遞迴)),拓撲排序)

//Sinhaeng Hhjian
#include<bits/stdc++.h>
using namespace std;
const int N=100;
const int MAX=1000;
int book[N], cnt;
struct node{
	char x[N];
	int mp[N][N];
	int v, e;
};
struct anode{
	int ad, wei;
	anode *next;
};
struct vnode{
	char x;
	anode *fir;
	int ind;
}; 
struct graph{
	vnode ver[N];
	int v, e;
};
//佇列 
struct Queue{
	int *base;
	int f, r;
};
void InitQueue(Queue &q){
	q.base = (int *)malloc(sizeof(int) * MAX);
	q.f = q.r = 0;
}
void InQueue(Queue &q, int bt){
	q.base[q.r++] = bt;
}
int IsEmpty(Queue q){
	return q.f == q.r? 1:0;
}
void OutQueue(Queue &q, int &bt){
	if(IsEmpty(q)) return ;
	bt = q.base[q.f++];
}
//棧
struct Stack{
	int *base;
	int top;
};
void Push(Stack &s, int bt){
	s.base[++s.top] = bt;
}
int GetTop(Stack s, int &bt){
	if(!s.top)
		return 0;
	bt = s.base[s.top];
	return 1;
}
int IsSEmpty(Stack s){
	return s.top==0? 1 : 0;
}
void InitStack(Stack &s){
	s.base = (int *)malloc(MAX*(sizeof(int)));
	s.top=0;
}
void Pop(Stack &s){
	if(IsSEmpty(s))
		return ;
	s.top--;
}
//建圖 
int lx(node &G, char x){
	for(int i=0;i<G.v;i++)
		if(G.x[i]==x)
			return i;
	return -1;
}
int ly(graph &GG, char x){
	for(int i=0;i<GG.v;i++)
		if(GG.ver[i].x==x)
			return i;
	return -1;
}
void wuxiang(node &G){
	char u, v;
	printf("建立無向圖的鄰接矩陣:\n請輸入頂點數和邊數:");
	scanf("%d %d", &G.v, &G.e);
	printf("請輸入頂點資訊(頂點間不要有空格):\n");
	getchar();
	for(int i=0;i<G.v;i++)
		scanf("%c", &G.x[i]);
	getchar();
	for(int i=0;i<G.v;i++)
		for(int j=0;j<G.v;j++)
			G.mp[i][j]=0;
	printf("請輸入無向圖的邊(兩頂點間加空格,並且每輸入一條邊用回車來間隔開另一條邊):\n"); 
	for(int k=0;k<G.e;k++){
		scanf("%c %c", &u, &v);
		getchar();
		int i=lx(G, u);
		if(i==-1){
			printf("ERROR\n");
			return ;
		}
		int j=lx(G, v);
		if(j==-1){
			printf("ERROR\n");
			return ;
		}
		G.mp[i][j]=G.mp[j][i]=1; 
	}
	printf("鄰接矩陣儲存無向圖結果:\n   ");
	for(int i=0;i<G.v;i++)
		printf("%3c", G.x[i]);
	printf("\n");
	for(int i=0;i<G.v;i++){
		printf("%3c", G.x[i]);
		for(int j=0;j<G.v;j++)	
			printf("%3d", G.mp[i][j]);
		printf("\n");
	} 	
}
void youxiang(graph &GG){
	char u, v;
	printf("建立有向圖的鄰接表:\n請輸入頂點數和邊數:"); 
	scanf("%d %d", &GG.v, &GG.e);
	printf("請輸入頂點資訊(頂點間不要有空格):\n");
	getchar();
	for(int i=0;i<GG.v;i++){
		scanf("%c", &GG.ver[i].x);
		GG.ver[i].fir=NULL;
	}
	getchar();
	printf("請輸入有向圖的邊(兩頂點間加空格,並且每輸入一條邊用回車來間隔開另一條邊):\n"); 
	for(int i=0;i<GG.v;i++)
		GG.ver[i].ind=0;
	for(int k=0;k<GG.e;k++){
		scanf("%c %c", &u, &v);
		getchar();
		int i=ly(GG, u);
		if(i==-1){
			printf("ERROR\n");
			return ;
		}
		int j=ly(GG, v);
		if(j==-1){
			printf("ERROR\n");
			return ;
		}
		anode *s=(anode *)malloc(sizeof(anode));
		s->ad=j;s->next=NULL;
		if(!GG.ver[i].fir)
			GG.ver[i].fir=s;
		else{
			anode *p=GG.ver[i].fir;
			while(p->next)
				p=p->next;
			p->next=s;
		}
	}
	printf("鄰接表儲存有向圖結果:\n");
	for(int i=0;i<GG.v;i++){
		printf("%3c", GG.ver[i].x);
		anode *p=GG.ver[i].fir;
		while(p){
			printf(" ->%3c", GG.ver[p->ad].x);
			p=p->next;
		}
		printf("\n");
	} 
}
//無向圖的遍歷 
void dfs1(node &G, int x){
	book[x]=1;
	printf("%3c", G.x[x]);
	for(int i=0;i<G.v;i++)
		if(G.mp[x][i] && !book[i])
			dfs1(G, i);
}
void wuxiangdfs(node &G){
	printf("對無向圖的深度優先遍歷(遞迴演算法):\n");
	for(int i=0;i<G.v;i++){
		if(!book[i]){
			dfs1(G, i);
		}
	}
	printf("\n");
}
void bfs1(node &G, int x){
	Queue q;
	InitQueue(q);
	InQueue(q, x);
	book[x]=1;
	while(!IsEmpty(q)){
		int bt;
		OutQueue(q, bt);
		printf("%3c", G.x[bt]);
		for(int i=0;i<G.v;i++)
			if(G.mp[bt][i] && !book[i]){
				InQueue(q, i);
				book[i]=1;
			}
	}
}
void wuxiangbfs(node &G){
	printf("對無向圖的廣度優先遍歷:\n");
	for(int i=0;i<N;i++)
		book[i]=0;
	for(int i=0;i<G.v;i++)
		if(!book[i])
			bfs1(G, i);
	printf("\n");
}
void dfs11(node &G, int x){
	int i, j, k;
	Stack S;
	InitStack(S);
	Push(S, x);
	printf("%3c", G.x[x]);
	book[x]=1;
	while(!IsSEmpty(S)){
		GetTop(S, i);
		for(j=0;j<G.v;j++){
			if(G.mp[i][j] && !book[j]){
				Push(S, j);
				printf("%3c", G.x[j]);
				book[j]=1;
				i=j;
				j=0;
			}
		}
		if(!IsSEmpty(S))
			Pop(S);
	}
}
void wuxiangfdfs(node &G){
	printf("對無向圖的深度優先遍歷(非遞迴演算法):\n"); 
	for(int i=0;i<G.v;i++)
		book[i]=0;
	for(int i=0;i<G.v;i++)
		if(!book[i])
			dfs11(G, i);
	printf("\n");
}
//有向圖的遍歷 
void dfs2(graph &GG, int x){
    anode *p;
    book[x]=1;
    p=GG.ver[x].fir;
	printf("%3c", GG.ver[x].x);
    while(p){
       if(!book[p->ad])
           dfs2(GG, p->ad);
       p=p->next;
    }
}
void youxiangdfs(graph &GG){
	printf("對有向圖的深度優先遍歷(遞迴演算法):\n");
	for(int i=0;i<N;i++)
		book[i]=0;
	for(int i=0;i<GG.v;i++)
		if(!book[i])
			dfs2(GG, i);
	printf("\n");
}
void bfs2(graph &GG, int x){
	Queue q;
	InitQueue(q);
	InQueue(q, x);
	book[x]=1;
	while(!IsEmpty(q)){
		OutQueue(q, x);
		printf("%3c", GG.ver[x].x);
		anode *p=GG.ver[x].fir;
		while(p){
			if(!book[p->ad]){
				book[p->ad]=1;
				InQueue(q, p->ad);
			}
			p=p->next;
		}
	}
}
void youxiangbfs(graph &GG){
	printf("對有向圖的廣度優先遍歷:\n");
	for(int i=0;i<N;i++)
		book[i]=0;
	for(int i=0;i<GG.v;i++)
		if(!book[i])
			bfs2(GG, i);
	printf("\n");
}
void dfs22(graph &GG, int x){
    Stack s;
	InitStack(s);  
    anode *p;
    book[x]=1; 
    Push(s, x);
    printf("%3c", GG.ver[x].x);
    while(!IsSEmpty(s)){
    	p = GG.ver[s.base[s.top]].fir;
        while(p){ 
            if(!book[p->ad]){                              
	            book[p->ad]=1;  
	        	printf("%3c", GG.ver[p->ad].x);  
	            Push(s, p->ad); 
	        	p=GG.ver[p->ad].fir; 
            } 
            else  
                 p=p->next;  
         }
         if(!p)
             Pop(s); 
     }   
}
void youxiangfdfs(graph &GG){
	printf("對有向圖的深度優先遍歷(非遞迴演算法):\n"); 
	for(int i=0;i<GG.v;i++)
		book[i]=0;
	for(int i=0;i<GG.v;i++)
		if(!book[i])
			dfs22(GG, i);
	printf("\n");
}

void tuopu(graph &GG){
	printf("對有向圖的拓撲排序為:\n");
	Stack s;cnt=0;
	InitStack(s);
	int a[N], c=0;
	for(int i=0;i<GG.v;i++)
		if(GG.ver[i].ind==0)
			Push(s, i);
	while(!IsSEmpty(s)){
		int xx=s.base[s.top];
		a[c++]=xx;
		Pop(s);
		cnt++;
		for(anode *p=GG.ver[xx].fir;p;p=p->next){
			int k=p->ad;
			GG.ver[k].ind--;
			if(!GG.ver[k].ind)
				Push(s, k);
		}
	}
	if(cnt<GG.v)
		printf("該圖有迴路\n");
	else{
		for(int i=0;i<c;i++)
			printf("%3c", GG.ver[i].x);
		printf("\n");
	}
}
int main()
{
	node G;
	wuxiang(G);
	wuxiangdfs(G);
	wuxiangbfs(G);
	wuxiangfdfs(G);

	graph GG;
	youxiang(GG);
	youxiangdfs(GG);
	youxiangbfs(GG);
	youxiangfdfs(GG);
	tuopu(GG);
	return 0;
}