1 概述#
簡(jiǎn)單的說简逮,圖由表示數(shù)據(jù)元素的集合V和表示數(shù)據(jù)之間關(guān)系的集合E組成,記為G=<V,E>朗儒。圖又分為有向圖與無向圖肪跋。下面是圖的一些基本元素:
- 邊(edge):頂點(diǎn)的序偶。
- 頂點(diǎn)(vertex):數(shù)據(jù)元素宁炫。
- 權(quán)重(weight):用來表示一個(gè)頂點(diǎn)到另一個(gè)頂點(diǎn)的距離偿曙、代價(jià)、耗費(fèi)等羔巢。
- 度(degree):與該頂點(diǎn)相關(guān)聯(lián)的邊的數(shù)目望忆,入度、出度等等竿秆。
圖的基本類型常使用的有相鄰矩陣與鄰接表启摄。下面將從兩方面介紹圖的儲(chǔ)存結(jié)構(gòu)與基本操作。
2 圖的相鄰矩陣儲(chǔ)存類型#
圖的相鄰矩陣或鄰接矩陣表示定點(diǎn)之間的鄰接關(guān)系幽钢,即表示頂點(diǎn)之間有邊或沒有邊的情況歉备。如下圖則是無向圖G1和有向圖G2的鄰接矩陣。
- 相鄰矩陣類型定義
對(duì)于有向圖匪燕,相鄰矩陣不一定對(duì)稱蕾羊。因?yàn)槿绻噜従仃嚨趇行第j列的元素為1,則表示有一條從頂點(diǎn)vi到頂點(diǎn)vj的弧帽驯,而此時(shí)不一定存在由頂點(diǎn)vj到頂點(diǎn)vi的弧龟再。
/*圖的相鄰矩陣儲(chǔ)存類型定義*/
#define MaxVertexNum 100 /*最大頂點(diǎn)數(shù)設(shè)為100*/
typedef enum{FALSE,TRUE} Boolean;
Boolean mark[MaxVertexNum];
typedef char VertexType; /*頂點(diǎn)類型設(shè)為字符型*/
typedef int EdgeType; /*邊的權(quán)值設(shè)為整型*/
typedef struct {
VertexType vexs[MaxVertexNum]; /*頂點(diǎn)表*/
EdgeType edges[MaxVertexNum][MaxVertexNum]; /*鄰接矩陣,即邊表*/
int numVertex,numEdge; /*頂點(diǎn)數(shù)和邊數(shù)*/
}Mgragh,*MGragh; /*Maragh 是以鄰接矩陣存儲(chǔ)的圖類型*/
- 圖創(chuàng)建
首先定義相鄰矩陣的尺寸尼变,即定點(diǎn)數(shù)和邊數(shù)利凑。
輸入每條邊信息,vi為初始點(diǎn)嫌术,vj為終止點(diǎn)哀澈。將鄰接表中的edges[i][j]設(shè)置為1,代表起點(diǎn)為i蛉威,終點(diǎn)為j日丹,存在一條邊。
void CreateMGraph(MGragh G){/*建立有向圖G 的鄰接矩陣存儲(chǔ)*/
int i,j,k,w;
char ch;
cout<<"請(qǐng)輸入頂點(diǎn)數(shù)和邊數(shù)";
cin>>i>>j;
G->numVertex=i;
G->numEdge=j;
cout<<"請(qǐng)輸入頂點(diǎn)信息:"<<endl;
for (i=0;i<G->numVertex;i++) {cout<<"第"<<i<<"個(gè)點(diǎn):";cin>>G->vexs[i];} /*輸入頂點(diǎn)信息蚯嫌,建立頂點(diǎn)表*/
for (i=0;i<G->numVertex;i++)
for (j=0;j<G->numVertex;j++)
G->edges[i][j]=0; /*初始化鄰接矩陣*/
cout<<"請(qǐng)輸入每條邊對(duì)應(yīng)的兩個(gè)頂點(diǎn)的序號(hào):\n";
for (k=0;k<G->numEdge;k++){
cout<<"v<i,j>:";
cin>>i>>j; /*輸入e 條邊哲虾,建立鄰接矩陣*/
G->edges[i][j]=1;
}
}
- 判斷邊類
FirstEdge即返回以v為頂點(diǎn)的第一條邊。它的想法是:返回以頂點(diǎn)v的編號(hào)的相鄰矩陣行择示,從j=0開始遍歷束凑,直到搜索到矩陣元素為1時(shí),表示i到j(luò)有一條邊栅盲,于是返回此條邊汪诉。
NextEdge即返回以v為頂點(diǎn)的下一條邊。當(dāng)輸入邊edge時(shí),將返回以edge.from的編號(hào)相同的矩陣行扒寄,從j=edge.to+1開始遍歷鱼鼓,直到搜索到矩陣元素為1時(shí),表示i到j(luò)有一條邊该编,返回此邊迄本。
Edge FirstEdge(MGragh G,int oneVertex){
Edge myEdge;
myEdge.from=oneVertex;
for(int i=0;i<G->numVertex;i++){
if(G->edges[oneVertex][i]!=0){
myEdge.to=i;
myEdge.weight=G->edges[oneVertex][i];
break;
}
}
return myEdge;
}
Edge NextEdge(MGragh G,Edge preEdge){
Edge myEdge;
myEdge.from =preEdge.from ;
if(preEdge.to <G->numVertex){
for(int i=preEdge.to+1;i<G->numVertex;i++){
if(G->edges[preEdge.from][i]!=0){
myEdge.to =i;
myEdge.weight =G->edges[preEdge.from ][i];
break;
}
}
}
return myEdge;
}
bool isEdge(MGragh G, Edge myEdge){
int test=0;
for(int i=0;i<G->numVertex;i++){
if(myEdge.to>=0&&G->edges[myEdge.from][myEdge.to]==1)return true;
}
return false;
}
- 兩種周游算法
以有向圖G2為例:
深度優(yōu)先搜索的周游算法如下:假設(shè)從v0點(diǎn)出發(fā),首先將v0的標(biāo)志位設(shè)置為TRUE课竣,然后從v0的第一條邊出發(fā)嘉赎,尋找第一條邊的終點(diǎn)v2。因?yàn)関2為被訪問過于樟,因此將v2標(biāo)志位設(shè)置為TRUE公条。從v2出發(fā),尋找v2的第一條邊終點(diǎn)為v3迂曲。因?yàn)関3為被訪問過靶橱,因此設(shè)v3的標(biāo)志位為TRUE。從v3出發(fā)奢米,尋找v3的第一條邊終點(diǎn)為v0抓韩,標(biāo)志位為TRUE說明已被訪問過纠永。返回上一個(gè)頂點(diǎn)v2鬓长,尋找v2的nextEdge,無尝江。返回v0涉波,尋找v0的nextEdge,為v1炭序,標(biāo)識(shí)v1為TRUE啤覆。遍歷完畢。
廣度優(yōu)先算法的周游如下:假設(shè)從v0出發(fā)惭聂。首先將v0的標(biāo)志位設(shè)置為TRUE窗声,將v0入隊(duì)。因?yàn)殛?duì)列不為空辜纲,所以取出front笨觅,設(shè)置為u,同時(shí)pop掉front耕腾。尋找v0的第一條邊的終點(diǎn)v2见剩。輸出v2,并將其push入隊(duì)列扫俺;尋找v0的第二條邊的終點(diǎn)v1,苍苞,輸出v1,并將其push入隊(duì)列狼纬;尋找v0的第三條邊的終點(diǎn)羹呵,無骂际。返回取出front,將v2設(shè)置為u冈欢,pop掉它方援。尋找v2的第一條邊v3,輸出v3并將其push如隊(duì)列涛癌;尋找v2的第二條邊犯戏,無。返回取出front拳话,將v1設(shè)置為u先匪,pop掉它。尋找v1的第一條邊弃衍,無呀非。返回取出front,將v3設(shè)置為u镜盯,pop掉它岸裙,尋找v3的第一條邊v0,因?yàn)橐员辉L問速缆,因此跳過降允;尋找v3的第二條邊,無艺糜。算法結(jié)束剧董。
//深度優(yōu)先周游
void DFS(MGragh G, int v){
mark[v]=TRUE;
cout<<G->vexs[v];
for(Edge e=FirstEdge(G,v);isEdge(G,e);e=NextEdge(G,e)){
if(mark[e.to]==FALSE) DFS(G,e.to);
}
}
void DFSM(MGragh G,int v){
for(int i=0;i<G->numVertex;i++){
mark[i]=FALSE;
}
DFS(G,0);
}
//廣度優(yōu)先周游
void BFS(MGragh G, int v){
for(int i=0;i<G->numVertex;i++){
mark[i]=FALSE;
}
using std::queue;
queue<int>Q;
cout<<G->vexs[v];
mark[v]=TRUE;
Q.push(v);
while(!Q.empty()){
int u=Q.front();
Q.pop();
for(Edge e=FirstEdge(G,u);isEdge(G,e);e=NextEdge(G,e))
if(mark[e.to]==FALSE){
cout<<G->vexs[e.to];
mark[e.to]=TRUE;
Q.push(e.to);
}
}
}
3 圖的鄰接表儲(chǔ)存類型#
當(dāng)圖中的邊數(shù)較少時(shí),相鄰矩陣就會(huì)出現(xiàn)大量的0元素破停,儲(chǔ)存這些0元素將消耗大量的儲(chǔ)存空間翅楼。
鄰接表表示法是一種鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu),由一個(gè)順序儲(chǔ)存的頂點(diǎn)表和n個(gè)鏈表儲(chǔ)存的邊表組成真慢。頂點(diǎn)表目有兩個(gè)域:頂點(diǎn)數(shù)據(jù)域和指向此頂點(diǎn)邊表指針域毅臊。邊表把依附于同一個(gè)頂點(diǎn)vi的邊(即相鄰矩陣中同一行的非0元素)組織成一個(gè)單鏈表。邊表中的每一個(gè)表目都代表一條邊黑界,由兩個(gè)主要的域組成:與頂點(diǎn)vi鄰接的另一個(gè)頂點(diǎn)的序號(hào)管嬉、指向邊表中下一個(gè)邊表的目的指針。
頂點(diǎn)結(jié)點(diǎn)和邊結(jié)點(diǎn)的結(jié)構(gòu)如下:
與鄰接矩陣儲(chǔ)存類型相似园爷,鄰接表的基本函數(shù)依然包括FirstEdge宠蚂,NextEdge和isEdge。這里不再重復(fù)童社,下面只給出廣度周游和深度周游算法求厕。
- 鄰接表類型定義
using namespace std;
#define MAX_VERTEXT_NUM 20
typedef enum{FALSE,TRUE} Boolean;
Boolean mark[MAX_VERTEXT_NUM];
typedef struct edge{ /*邊定義*/
int from,to,weight;
}Edge,*Edged;
typedef struct ArcNode{ /*邊結(jié)點(diǎn)定義*/
int adjvex;
struct ArcNode *nextArc;
int weight;
}ArcNode;
typedef struct VNode{ /*頂點(diǎn)定義*/
char data;
ArcNode *firstArc;
}VNode, AdjList[MAX_VERTEXT_NUM];
typedef struct Indegree{ /*每個(gè)點(diǎn)的入度*/
int indegree;
}Indegree,indegree[MAX_VERTEXT_NUM];
typedef struct{ /*圖定義*/
AdjList verTices;
int vexNum;
int arcNum;
int kind;
indegree Indegree;
}ALGraph;
- 圖的鄰接表儲(chǔ)存類型建立
首先輸入頂點(diǎn)和邊的個(gè)數(shù),同時(shí)申請(qǐng)頂點(diǎn)個(gè)數(shù)的結(jié)點(diǎn)空間。
每次輸入邊的鄰接關(guān)系時(shí)i-j時(shí)呀癣,首先申請(qǐng)一個(gè)邊結(jié)點(diǎn)空間給美浦,結(jié)點(diǎn)的adjvex為j,nextarc為頭結(jié)點(diǎn)firstarc的nextarc项栏,頭結(jié)點(diǎn)的firstarc變?yōu)榇薺結(jié)點(diǎn)arcnode浦辨。
void CreateGraph(ALGraph *G)
{
int i,j,k,weight;
ArcNode *arcNode;
printf_s("請(qǐng)輸入頂點(diǎn)數(shù)和邊數(shù):");
cin>>G->vexNum;
cin>>G->arcNum;
//建立頂點(diǎn)表
printf_s("建立頂點(diǎn)表\n");
for (i = 0; i < G->vexNum; i++)
{
printf_s("請(qǐng)輸入第%d個(gè)頂點(diǎn):", i);
cin>>G->verTices[i].data;
arcNode = (ArcNode *)malloc(sizeof(ArcNode));
arcNode->adjvex=i;
arcNode->nextArc=NULL;
G->verTices[i].firstArc=arcNode;
G->Indegree[i].indegree=0;
}
//建立邊表
printf_s("建立邊表\n");
for (k = 0; k < G->arcNum; k++)
{
printf_s("請(qǐng)輸入(vi-vj)的頂點(diǎn)對(duì)序號(hào)");
cin>>i;
cin>>j;
arcNode = (ArcNode *)malloc(sizeof(ArcNode));
arcNode->adjvex = j;
arcNode->nextArc = G->verTices[i].firstArc->nextArc;//插入表頭
G->verTices[i].firstArc ->nextArc= arcNode;
G->Indegree[j].indegree++;
}
}
- 兩種周游算法
深度優(yōu)先周游:對(duì)于鄰接表存儲(chǔ)類型,它采用遞歸算法沼沈,從起始點(diǎn)v0沿著鄰接表一次訪問流酬,直到next指針為NULL,則返回上一層列另,進(jìn)入上一層頂點(diǎn)v1所在的鏈表繼續(xù)逐個(gè)訪問芽腾。
廣度周游與相鄰矩陣法類似,這里不做闡述页衙。算法如下:
//深度優(yōu)先周游
void DFSM(ALGraph *G,int i){
ArcNode *p;
cout<<G->verTices[i].data;
mark[i]=TRUE;
p=G->verTices[i].firstArc;
while(p){
if(mark[p->adjvex]==FALSE)
DFSM(G,p->adjvex);
p=p->nextArc;
}
}
void DFS(ALGraph *G){
for ( int i=0; i<G->vexNum;i++)
mark[i]=FALSE;
for( int i=0; i<G->vexNum;i++)
if(!mark[i])
DFSM(G,i);
}
//廣度優(yōu)先周游
void BFS(ALGraph *G,int x){
ArcNode *p;
int w;
using std::queue;
queue<int> Q;
for ( int i=0; i<G->vexNum;i++) {mark[i]=FALSE;}
cout<<G->verTices[x].data;
mark[x]=TRUE;
Q.push(x);
while(!Q.empty()){
int v=Q.front();
Q.pop();
p=G->verTices[v].firstArc;
while(p){
int w=p->adjvex;
if(mark[w]==FALSE){
mark[w]=TRUE;
cout<<G->verTices[w].data;
Q.push(w);}
p=p->nextArc;
}
}
}
- 拓?fù)渑判?/strong>
有向圖的邊可以看做定點(diǎn)之間制約關(guān)系的描述摊滔。在工程實(shí)踐中火窒,有些工程的進(jìn)行經(jīng)常受到一定條件的約束狮暑,例如一個(gè)工程項(xiàng)目通常由若干子工程組成,某些子工程完成之后另一些子工程才能開始顿天。
一個(gè)無環(huán)的有向圖稱為有向無環(huán)圖眨八,有向無環(huán)圖常用來描述一個(gè)過程或一個(gè)系統(tǒng)的進(jìn)行過程腺兴。對(duì)于有向無環(huán)圖G=<V,E>,如果頂點(diǎn)序列滿足:存在頂點(diǎn)vi到vj的一條路徑踪古,那么在序列中頂點(diǎn)vi必在頂點(diǎn)vj之前含长,頂點(diǎn)集合V的這種線型序列稱作一個(gè)拓?fù)湫蛄小?/p>
進(jìn)行有向圖的拓?fù)湫蛄蟹椒ㄈ缦拢?/p>
- 從有向圖中選出一個(gè)沒有前驅(qū)(入度為0)的頂點(diǎn)并輸出。
- 刪除圖中該頂點(diǎn)和所有以它為起點(diǎn)的弧伏穆。
不斷重復(fù)上述兩個(gè)步驟,會(huì)出現(xiàn)兩種情形:要么有向圖中頂點(diǎn)全部被輸出纷纫,要么當(dāng)前圖中不存在沒有前驅(qū)的頂點(diǎn)枕扫。當(dāng)圖中的頂點(diǎn)全部輸出時(shí),就完成了有向無環(huán)圖的拓?fù)渑判蛉杩划?dāng)圖中還有頂點(diǎn)沒有輸出時(shí)烟瞧,說明有向圖中含有環(huán)。
它的工作思想如下:
//拓?fù)渑判?void TopsortbyQueue(ALGraph*G){
for(int i=0; i< G->vexNum;i++)
mark[i]=FALSE;
using std::queue;
queue<int> Q;
cout<<"拓?fù)湫蛄袨?"<<endl;
for(int i=0; i< G->vexNum;i++){
if(G->Indegree[i].indegree==0)
Q.push(i);}
while(!Q.empty()){
int v=Q.front();
Q.pop();
cout<<v;
mark[v]=TRUE;
for(Edge e=FirstEdge(G,v);isEdge(G,e);e=NextEdge(G,e)){
G->Indegree[e.to].indegree--;
if(G->Indegree[e.to].indegree ==0)
Q.push(e.to);
}
}
for(int i=0;i< G->vexNum;i++)
if(mark[i]==FALSE){
cout<<endl;
cout<<"還有頂點(diǎn)未訪問染簇,此圖有環(huán)参滴。"<<endl;
break;
}
}
4 總結(jié)#
明顯感覺到寫得多了對(duì)于語言的運(yùn)用更熟練了,也更有了設(shè)計(jì)算法需要的邏輯思想锻弓。這個(gè)寫的還算比較順隨著思維和語言能力提升砾赔,希望能在acm校選賽比賽上有好的發(fā)揮過兩天來更新結(jié)果!
5 附錄#
鄰接矩陣:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<queue>
using namespace std;
#define MaxVertexNum 100 /*最大頂點(diǎn)數(shù)設(shè)為100*/
typedef enum{FALSE,TRUE} Boolean;
Boolean mark[MaxVertexNum];
typedef char VertexType; /*頂點(diǎn)類型設(shè)為字符型*/
typedef int EdgeType; /*邊的權(quán)值設(shè)為整型*/
typedef struct {
VertexType vexs[MaxVertexNum]; /*頂點(diǎn)表*/
EdgeType edges[MaxVertexNum][MaxVertexNum]; /*鄰接矩陣,即邊表*/
int numVertex,numEdge; /*頂點(diǎn)數(shù)和邊數(shù)*/
}Mgragh,*MGragh; /*Maragh 是以鄰接矩陣存儲(chǔ)的圖類型*/
typedef struct edge{
int from,to,weight;
}Edge,*Edged;
void CreateMGraph(MGragh G){/*建立有向圖G 的鄰接矩陣存儲(chǔ)*/
int i,j,k,w;
char ch;
cout<<"請(qǐng)輸入頂點(diǎn)數(shù)和邊數(shù)";
cin>>i>>j;
G->numVertex=i;
G->numEdge=j;
cout<<"請(qǐng)輸入頂點(diǎn)信息:"<<endl;
for (i=0;i<G->numVertex;i++) {cout<<"第"<<i<<"個(gè)點(diǎn):";cin>>G->vexs[i];} /*輸入頂點(diǎn)信息暴心,建立頂點(diǎn)表*/
for (i=0;i<G->numVertex;i++)
for (j=0;j<G->numVertex;j++)
G->edges[i][j]=0; /*初始化鄰接矩陣*/
cout<<"請(qǐng)輸入每條邊對(duì)應(yīng)的兩個(gè)頂點(diǎn)的序號(hào):\n";
for (k=0;k<G->numEdge;k++){
cout<<"v<i,j>:";
cin>>i>>j; /*輸入e 條邊妓盲,建立鄰接矩陣*/
G->edges[i][j]=1;
}
}
void displaygraph(MGragh G){
int i,j;
for(i=0;i<G->numVertex;i++){
for(j=0;j<G->numVertex;j++){
cout<<G->edges[i][j]<<" ";}
cout<<endl;
}
}
Edge FirstEdge(MGragh G,int oneVertex){
Edge myEdge;
myEdge.from=oneVertex;
for(int i=0;i<G->numVertex;i++){
if(G->edges[oneVertex][i]!=0){
myEdge.to=i;
myEdge.weight=G->edges[oneVertex][i];
break;
}
}
return myEdge;
}
Edge NextEdge(MGragh G,Edge preEdge){
Edge myEdge;
myEdge.from =preEdge.from ;
if(preEdge.to <G->numVertex){
for(int i=preEdge.to+1;i<G->numVertex;i++){
if(G->edges[preEdge.from][i]!=0){
myEdge.to =i;
myEdge.weight =G->edges[preEdge.from ][i];
break;
}
}
}
return myEdge;
}
bool isEdge(MGragh G, Edge myEdge){
int test=0;
for(int i=0;i<G->numVertex;i++){
if(myEdge.to>=0&&G->edges[myEdge.from][myEdge.to]==1)return true;
}
return false;
}
//深度優(yōu)先周游
void DFS(MGragh G, int v){
mark[v]=TRUE;
cout<<G->vexs[v];
for(Edge e=FirstEdge(G,v);isEdge(G,e);e=NextEdge(G,e)){
if(mark[e.to]==FALSE) DFS(G,e.to);
}
}
void DFSM(MGragh G,int v){
for(int i=0;i<G->numVertex;i++){
mark[i]=FALSE;
}
DFS(G,0);
}
//廣度優(yōu)先周游
void BFS(MGragh G, int v){
for(int i=0;i<G->numVertex;i++){
mark[i]=FALSE;
}
using std::queue;
queue<int>Q;
cout<<G->vexs[v];
mark[v]=TRUE;
Q.push(v);
while(!Q.empty()){
int u=Q.front();
Q.pop();
for(Edge e=FirstEdge(G,u);isEdge(G,e);e=NextEdge(G,e))
if(mark[e.to]==FALSE){
cout<<G->vexs[e.to];
mark[e.to]=TRUE;
Q.push(e.to);
}
}
}
int main(){
Mgragh *Graph = (Mgragh *)malloc(sizeof(Mgragh));
CreateMGraph(Graph);
displaygraph(Graph);
cout<<endl;
BFS(Graph,0);
cout<<endl;
DFSM(Graph,0);
system("pause");
return 0;
}
鄰接表
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<queue>
using namespace std;
#define MAX_VERTEXT_NUM 20
typedef enum{FALSE,TRUE} Boolean;
Boolean mark[MAX_VERTEXT_NUM];
typedef struct edge{
int from,to,weight;
}Edge,*Edged;
typedef struct ArcNode{
int adjvex;
struct ArcNode *nextArc;
int weight;
}ArcNode;
typedef struct VNode{
char data;
ArcNode *firstArc;
}VNode, AdjList[MAX_VERTEXT_NUM];
typedef struct Indegree{
int indegree;
}Indegree,indegree[MAX_VERTEXT_NUM];
typedef struct{
AdjList verTices;
int vexNum;
int arcNum;
int kind;
indegree Indegree;
}ALGraph;
typedef struct Dist{
int index;
int length;
int pre;
}Dist,*Dijk;
edge FirstEdge(ALGraph *G,int oneVertex){
Edge myEdge;
myEdge.from=oneVertex;
ArcNode *temp=G->verTices[oneVertex].firstArc;
if(temp->nextArc!=NULL){
myEdge.to=temp->nextArc->adjvex;
myEdge.weight=temp->nextArc->weight;
}
return myEdge;
}
edge NextEdge(ALGraph *G,Edge preEdge){
Edge myEdge;
myEdge.from =preEdge.from;
ArcNode *temp=G->verTices[preEdge.from].firstArc;
while(temp->nextArc!=NULL&&temp->adjvex<=preEdge.to)
temp=temp->nextArc;
if(temp->nextArc!=NULL){
myEdge.to=temp->nextArc->adjvex;
myEdge.weight=temp->nextArc->weight;
}
return myEdge;
}
bool isEdge(ALGraph *G, Edge myEdge){
int n=0;
ArcNode *p;
p=G->verTices[myEdge.from].firstArc;
while(p){
if(p->adjvex==myEdge.to){
n=0;
}else{
n=1;
}
p=p->nextArc;
}
if(n==0){return true;}
else{
return false;
}
}
void CreateGraph(ALGraph *G)
{
int i,j,k,weight;
ArcNode *arcNode;
printf_s("請(qǐng)輸入頂點(diǎn)數(shù)和邊數(shù):");
cin>>G->vexNum;
cin>>G->arcNum;
//建立頂點(diǎn)表
printf_s("建立頂點(diǎn)表\n");
for (i = 0; i < G->vexNum; i++)
{
printf_s("請(qǐng)輸入第%d個(gè)頂點(diǎn):", i);
cin>>G->verTices[i].data;
arcNode = (ArcNode *)malloc(sizeof(ArcNode));
arcNode->adjvex=i;
arcNode->nextArc=NULL;
G->verTices[i].firstArc=arcNode;
G->Indegree[i].indegree=0;
}
//建立邊表
printf_s("建立邊表\n");
for (k = 0; k < G->arcNum; k++)
{
printf_s("請(qǐng)輸入(vi-vj)的頂點(diǎn)對(duì)序號(hào)");
cin>>i;
cin>>j;
arcNode = (ArcNode *)malloc(sizeof(ArcNode));
arcNode->adjvex = j;
arcNode->nextArc = G->verTices[i].firstArc->nextArc;//插入表頭
G->verTices[i].firstArc ->nextArc= arcNode;
G->Indegree[j].indegree++;
}
}
//顯示圖的鄰接表
void DisplayGraph(ALGraph *G)
{
int i;
for (i = 0; i < G->vexNum; i++)
{
cout<<G->Indegree[i].indegree;
ArcNode *P= G->verTices[i].firstArc;
printf_s("%d->", i);
while (P != NULL)
{
printf_s("%d->", P->adjvex);
P = P->nextArc;
}
printf_s("\n");
}
}
//深度優(yōu)先周游
void DFSM(ALGraph *G,int i){
ArcNode *p;
cout<<G->verTices[i].data;
mark[i]=TRUE;
p=G->verTices[i].firstArc;
while(p){
if(mark[p->adjvex]==FALSE)
DFSM(G,p->adjvex);
p=p->nextArc;
}
}
void DFS(ALGraph *G){
for ( int i=0; i<G->vexNum;i++)
mark[i]=FALSE;
for( int i=0; i<G->vexNum;i++)
if(!mark[i])
DFSM(G,i);
}
//廣度優(yōu)先周游
void BFS(ALGraph *G,int x){
ArcNode *p;
int w;
using std::queue;
queue<int> Q;
for ( int i=0; i<G->vexNum;i++) {mark[i]=FALSE;}
cout<<G->verTices[x].data;
mark[x]=TRUE;
Q.push(x);
while(!Q.empty()){
int v=Q.front();
Q.pop();
p=G->verTices[v].firstArc;
while(p){
int w=p->adjvex;
if(mark[w]==FALSE){
mark[w]=TRUE;
cout<<G->verTices[w].data;
Q.push(w);}
p=p->nextArc;
}
}
}
//拓?fù)渑判?void TopsortbyQueue(ALGraph*G){
for(int i=0; i< G->vexNum;i++)
mark[i]=FALSE;
using std::queue;
queue<int> Q;
cout<<"拓?fù)湫蛄袨?"<<endl;
for(int i=0; i< G->vexNum;i++){
if(G->Indegree[i].indegree==0)
Q.push(i);}
while(!Q.empty()){
int v=Q.front();
Q.pop();
cout<<v;
mark[v]=TRUE;
for(Edge e=FirstEdge(G,v);isEdge(G,e);e=NextEdge(G,e)){
G->Indegree[e.to].indegree--;
if(G->Indegree[e.to].indegree ==0)
Q.push(e.to);
}
}
for(int i=0;i< G->vexNum;i++)
if(mark[i]==FALSE){
cout<<endl;
cout<<"還有頂點(diǎn)未訪問,此圖有環(huán)专普。"<<endl;
break;
}
}
int main(){
int x;
int num;
string edge;
ALGraph *Graph = (ALGraph *)malloc(sizeof(ALGraph));
CreateGraph(Graph);
DisplayGraph(Graph);
DFS(Graph);
BFS(Graph,0);
TopsortbyQueue(Graph);
system("pause");
}
- 文/潘曉璐 我一進(jìn)店門暇唾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人辰斋,你說我怎么就攤上這事策州。” “怎么了宫仗?”我有些...
- 文/不壞的土叔 我叫張陵够挂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我藕夫,道長(zhǎng)孽糖,這世上最難降的妖魔是什么? 我笑而不...
- 正文 為了忘掉前任毅贮,我火速辦了婚禮办悟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘滩褥。我一直安慰自己病蛉,他們只是感情好,可當(dāng)我...
- 文/花漫 我一把揭開白布瑰煎。 她就那樣靜靜地躺著铺然,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酒甸。 梳的紋絲不亂的頭發(fā)上魄健,一...
- 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绿满!你這毒婦竟也來了臂外?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬榮一對(duì)情侶失蹤喇颁,失蹤者是張志新(化名)和其女友劉穎漏健,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體橘霎,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔫浆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了姐叁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓦盛。...
- 正文 年R本政府宣布嘱吗,位于F島的核電站,受9級(jí)特大地震影響滔驾,放射性物質(zhì)發(fā)生泄漏谒麦。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一哆致、第九天 我趴在偏房一處隱蔽的房頂上張望绕德。 院中可真熱鬧,春花似錦沽瞭、人聲如沸迁匠。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至延曙,卻和暖如春豌鹤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背枝缔。 一陣腳步聲響...
- 正文 我出身青樓灵临,卻偏偏與公主長(zhǎng)得像截型,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子儒溉,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 弗洛伊德算法適用于為圖中每一個(gè)頂點(diǎn)求最短路徑宦焦,思路如下 檢查圖中任何一個(gè) 到 任何另一個(gè)點(diǎn)能否通過第一個(gè)點(diǎn)降低最短...
- 數(shù)據(jù)結(jié)構(gòu)與算法--圖的實(shí)現(xiàn)(鄰接表涛碑、鄰接矩陣精堕、邊的數(shù)組) 應(yīng)該用哪種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)圖呢?主要有如下三種: 鄰接矩陣 ...
- 內(nèi)容整理于魚c工作室教程 1. 圖的基本概念 1.1 圖的概念 圖(Graph)是由頂點(diǎn)的有窮非空集合和頂點(diǎn)之間邊...
- 圖是一種比線性表和樹更復(fù)雜的數(shù)據(jù)結(jié)構(gòu),在圖中揉阎,結(jié)點(diǎn)之間的關(guān)系是任意的庄撮,任意兩個(gè)數(shù)據(jù)元素之間都可能相關(guān)。圖是一種多對(duì)...
- 圖是由頂點(diǎn)的有窮非空集合和頂點(diǎn)之間邊的集合組成余黎,通常表示為:G(V,E)重窟,其中,G表示一個(gè)圖惧财,V是圖G中頂點(diǎn)的集合...