實驗9
姓名: 學號:班級: node
8.1 實驗目的
(1) 掌握圖的基本概念。ios
(2) 掌握圖的存儲結構的設計與實現,基本運算的實現。git
(3) 熟練掌握圖的兩種遍歷算法、遍歷生成樹及遍歷算法的應用。github
8.2 實驗任務
分別設計圖(網)的鄰接矩陣、鄰接表存儲結構,編寫算法實現下列問題的求解。、算法
數據要求:可利用8.3中的數據,也可自行編寫數據。數組
1.打印出圖(網)的兩種遍歷序列。ide
2.求給定圖中的邊(或弧)的數目。函數
3.對給定的圖G及出發點v0,設計算法從V0出發深度優先遍歷圖G,並構造出相應的生成樹或生成森林。學習
4.對給定的圖G及出發點v0,設計算法從V0出發廣度優先遍歷圖G,並構造出相應的生成樹或生成森林。測試
8.3 實驗說明
這裏介紹一種從文本文件讀入圖的數據建立圖的方法,這樣咱們能夠按照指定的格式,先從容地準備好數據,而後由程序自動讀入數據來建立圖。
createGrpAdjMatrix.h,文件建立鄰接矩陣表示的圖。
createGrpAdjLinkedList.h,文件建立鄰接表表示的圖。
(如下給出的圖的建立方法僅供參考,實驗者可自行設計其它建立方法)
1. 數據文件格式設計
這裏數據用文本文件保存,文件擴展名可自行指定,好比g8.grp,只要數據按文本文件格式讀寫便可。下面給出一種數據文件格式,其實讀者能夠自行設計圖的數據文件格式。
①標識行1:Graph
標識這是一個圖的數據文件,這一行也能夠不要。
②標識行2:UDG、或UDN、或DG、或DN
這一行用來標識此圖是無向圖(UDG)、無向網(UDN)、有向圖(DG)、仍是有向網(DN)。
③頂點行
這一行將圖中全部頂點列出,頂點之間用空格進行分割。這些頂點數據讀出後存放到圖的頂點數組中。
例如,圖6-21(a)所示的圖的頂點行數據爲:a b c d。
圖的各類算法都是用頂點的編號來引用頂點的,因此這一行頂點的排列順序是很重要的,頂點的排列順序決定了頂點的編號。好比上例中,頂點a、b、c、d對應的編號就爲一、二、三、4。
④邊數據行
一條邊一行,邊的2個頂點之間用空格分割。若是是網,每一行再加邊的權值,也以空格分割。若是是無向圖和無向網,每條邊會重複一次。
例如圖6-18(a)無向圖的邊的數據爲:
a b
a c
a d
b a
b c
c a
c b
c d
d a
d c
圖6-21(a)無向網邊的數據爲:
a b 4
a c 5
a d 3
b a 4
b c 2
c a 5
c b 2
c d 6
d a 3
d c 6
⑤其它行
若是程序強大一點,還能夠在文件中加註釋行,容許出現空行等,固然這是非必須的。
舉一個完整的圖的數據文件的例子,對圖6-18(a)的無向圖,完整的數據文件以下:
//文件能夠加註釋行,註釋以「//」開始
//Graph爲圖標誌,不然斷定格式不對
//標誌行後,第一行爲圖的類型。UDG--無向圖;UDN--無向網;DG--有向圖;DN--有向網
//標誌行後,第二行爲頂點元素
//頂點行如下圖的邊或弧。用頂點表示,第一列爲起始頂點;第二列爲鄰接點;在網中再增長一列表示權值。
//本圖具備4個頂點5條邊
//下一行爲圖的標識行
Graph
//圖的類型標識,此爲無向圖
UDG
//頂點元素數據
a b c d
//如下爲邊的數據,共10行數據,表示5條邊
a b
a c
a d
b a
b c
c a
c b
c d
d a
d c
文件名不妨叫作Gudg4.grp。
再舉一個有向網的例子,對圖6-22所示的有向網,完整的數據文件以下:
圖1 一個有向網實例
//標識爲圖數據
Graph
//標識有向網
DN
//頂點數據
a b c d e f g h i j
//如下爲邊數據,共15條邊
a b 2
a d 20
b e 1
c a 3
d c 8
d f 6
d g 4
e c 7
e h 3
f c 1
g h 1
h f 2
h j 2
i g 2
j i 1
不妨設文件名爲Gdn10.grp
2. 從數據文件建立鄰接矩陣表示的圖
指定圖的數據文件名,而後逐行讀出數據並處理,自動建立鄰接矩陣表示的圖。本程序能夠自動處理註釋行和空行,程序實現以下:
1 //****************************文件建立圖*****************************// 2 //* 函數功能:從文本文件建立鄰接矩陣表示的圖 *// 3 //* 入口參數 char fileName[],文件名 *// 4 //* 出口參數:Graph &G,即建立的圖 *// 5 //* 返回值:bool,true建立成功;false建立失敗 *// 6 //* 函數名:CreateGraphFromFile(char fileName[], Graph &G) *// 7 //*******************************************************************// 8 int CreateGraphFromFile(char fileName[], Graph &G) 9 { 10 FILE* pFile; //定義文件指針 11 char str[1000]; //存放讀出一行文本的字符串 12 char strTemp[10]; //判斷是否註釋行 13 cellType eWeight; //邊的信息,常爲邊的權值 14 GraphKind graphType; //圖類型枚舉變量 15 pFile=fopen(fileName,"r"); 16 if(!pFile) 17 { 18 printf("錯誤:文件%s打開失敗。\n",fileName); 19 return false; 20 } 21 while(fgets(str,1000,pFile)!=NULL) 22 { 23 strLTrim(str); //刪除字符串左邊空格,這是一個自定義的函數 24 if (str[0]=='\n') //空行,繼續讀取下一行 25 continue; 26 strncpy(strTemp,str,2); 27 if(strstr(strTemp,"//")!=NULL) //跳過註釋行 28 continue; 29 else //非註釋行、非空行,跳出循環 30 break; 31 } 32 //循環結束,str中應該已是圖的標識Graph,判斷標識是否正確 33 if(strstr(str,"Graph")==NULL) 34 { 35 printf("錯誤:打開的文件格式錯誤!\n"); 36 fclose(pFile); //關閉文件 37 return false; 38 } 39 //讀取圖的類型,跳過空行 40 while(fgets(str,1000,pFile)!=NULL) 41 { 42 strLTrim(str); //刪除字符串左邊空格,這是一個自定義函數 43 if (str[0]=='\n') //空行,繼續讀取下一行 44 continue; 45 strncpy(strTemp,str,2); 46 if(strstr(strTemp,"//")!=NULL) //註釋行,跳過,繼續讀取下一行 47 continue; 48 else //非空行,也非註釋行,即圖的類型標識 49 break; 50 } 51 //設置圖的類型 52 if(strstr(str,"UDG")) 53 graphType=UDG; //無向圖 54 else if(strstr(str,"UDN")) 55 graphType=UDN; //無向網 56 else if(strstr(str,"DG")) 57 graphType=DG; //有向圖 58 else if(strstr(str,"DN")) 59 graphType=DN; //有向網 60 else 61 { 62 printf("錯誤:讀取圖的類型標記失敗!\n"); 63 fclose(pFile); //關閉文件 64 return false; 65 } 66 //讀取頂點行數據到str。跳過空行 67 while(fgets(str,1000,pFile)!=NULL) 68 { 69 strLTrim(str); //刪除字符串左邊空格,這是一個自定義函數 70 if (str[0]=='\n') //空行,繼續讀取下一行 71 continue; 72 strncpy(strTemp,str,2); 73 if(strstr(strTemp,"//")!=NULL) //註釋行,跳過,繼續讀取下一行 74 continue; 75 else //非空行,也非註釋行,即圖的頂點元素行 76 break; 77 } 78 79 //頂點數據放入圖的頂點數組 80 char* token=strtok(str," "); 81 int nNum=0; 82 while(token!=NULL) 83 { 84 G.Data[nNum]=*token; 85 token = strtok( NULL, " "); 86 nNum++; 87 } 88 //圖的鄰接矩陣初始化 89 int nRow=0; //矩陣行下標 90 int nCol=0; //矩陣列下標 91 if(graphType==UDG || graphType==DG) 92 { 93 for(nRow=0;nRow<nNum;nRow++) 94 for(nCol=0;nCol<nNum;nCol++) 95 G.AdjMatrix[nRow][nCol]=0; 96 } 97 else 98 { 99 for(nRow=0;nRow<nNum;nRow++) 100 for(nCol=0;nCol<nNum;nCol++) 101 G.AdjMatrix[nRow][nCol]=INF; //INF表示無窮大 102 } 103 //循環讀取邊的數據到鄰接矩陣 104 int edgeNum=0; //邊的數量 105 elementType Nf, Ns; //邊或弧的2個相鄰頂點 106 while(fgets(str,1000,pFile)!=NULL) 107 { 108 strLTrim(str); //刪除字符串左邊空格,這是一個自定義函數 109 if (str[0]=='\n') //空行,繼續讀取下一行 110 continue; 111 strncpy(strTemp,str,2); 112 if(strstr(strTemp,"//")!=NULL) //註釋行,跳過,繼續讀取下一行 113 continue; 114 char* token=strtok(str," "); //以空格爲分隔符,分割一行數據,寫入鄰接矩陣 115 if(token==NULL) //分割爲空串,失敗退出 116 { 117 printf("錯誤:讀取圖的邊數據失敗!\n"); 118 fclose(pFile); //關閉文件 119 return false; 120 } 121 Nf=*token; //獲取邊的第一個頂點 122 token = strtok( NULL, " "); //讀取下一個子串,即第二個頂點 123 if(token==NULL) //分割爲空串,失敗退出 124 { 125 printf("錯誤:讀取圖的邊數據失敗!\n"); 126 fclose(pFile); //關閉文件 127 return false; 128 } 129 Ns=*token; //獲取邊的第二個頂點 130 //從第一個頂點獲取行號 131 for(nRow=0;nRow<nNum;nRow++) 132 { 133 if(G.Data[nRow]==Nf) //從頂點列表找到第一個頂點的編號 134 break; 135 } 136 //從第二個頂點獲取列號 137 for(nCol=0;nCol<nNum;nCol++) 138 { 139 if(G.Data[nCol]==Ns) //從頂點列表找到第二個頂點的編號 140 break; 141 } 142 //若是爲網,讀取權值 143 if(graphType==UDN || graphType==DN) 144 { //讀取下一個子串,即邊的附加信息,常爲邊的權重 145 token = strtok( NULL, " "); 146 if(token==NULL) //分割爲空串,失敗退出 147 { 148 printf("錯誤:讀取圖的邊數據失敗!\n"); 149 fclose(pFile); //關閉文件 150 return false; 151 } 152 eWeight=atoi(token); //取得邊的附加信息 153 } 154 if(graphType==UDN || graphType==DN) 155 G.AdjMatrix[nRow][nCol]=eWeight; 156 //若是爲網,鄰接矩陣中對應的邊設置權值,不然置爲1 157 else 158 G.AdjMatrix[nRow][nCol]=1; 159 edgeNum++; //邊數加1 160 } 161 G.VerNum=nNum; //圖的頂點數 162 if(graphType==UDG || graphType==UDN) 163 G.ArcNum=edgeNum / 2; //無向圖或網的邊數等於統計的數字除2 164 else 165 G.ArcNum=edgeNum; 166 G.gKind=graphType; //圖的類型 167 fclose(pFile); //關閉文件 168 return true; 169 }
3. 從數據文件建立鄰接表表示的圖
程序實現以下:
1 //****************************文件建立圖*****************************// 2 //* 函數功能:從文本文件建立鄰接表表示的圖 *// 3 //* 入口參數 char fileName[],文件名 *// 4 //* 出口參數:Graph &G,即建立的圖 *// 5 //* 返回值:bool,true建立成功;false建立失敗 *// 6 //* 函數名:CreateGraphFromFile(char fileName[], Graph &G) *// 7 //* 備註:本函數使用的數據文件格式以邊(頂點對)爲基本數據 *// 8 //*******************************************************************// 9 int CreateGraphFromFile(char fileName[], Graph &G) 10 { 11 FILE* pFile; //定義文件指針 12 char str[1000]; //存放讀出一行文本的字符串 13 char strTemp[10]; //判斷是否註釋行 14 char* ss; 15 int i=0, j=0; 16 int edgeNum=0; //邊的數量 17 eInfoType eWeight; //邊的信息,常爲邊的權值 18 GraphKind graphType; //圖類型枚舉變量 19 pFile=fopen(fileName,"r"); 20 if(!pFile) 21 { 22 printf("錯誤:文件%s打開失敗。\n",fileName); 23 return false; 24 } 25 while(fgets(str,1000,pFile)!=NULL) //跳過空行和註釋行 26 { 27 strLTrim(str); //刪除字符串左邊空格,這是一個自定義函數 28 if (str[0]=='\n') //空行,繼續讀取下一行 29 continue; 30 strncpy(strTemp,str,2); 31 if(strstr(strTemp,"//")!=NULL) //跳過註釋行 32 continue; 33 else //非註釋行、非空行,跳出循環 34 break; 35 } 36 //循環結束,str中應該已是圖的標識Graph,判斷標識是否正確 37 if(strstr(str,"Graph")==NULL) 38 { 39 printf("錯誤:打開的文件格式錯誤!\n"); 40 fclose(pFile); //關閉文件 41 return false; 42 } 43 //讀取圖的類型,跳過空行及註釋行 44 while(fgets(str,1000,pFile)!=NULL) 45 { 46 strLTrim(str); //刪除字符串左邊空格,這是一個自定義函數 47 if (str[0]=='\n') //空行,繼續讀取下一行 48 continue; 49 strncpy(strTemp,str,2); 50 if(strstr(strTemp,"//")!=NULL) //註釋行,跳過,繼續讀取下一行 51 continue; 52 else //非空行,也非註釋行,即圖的類型標識 53 break; 54 } 55 //設置圖的類型 56 if(strstr(str,"UDG")) 57 graphType=UDG; //無向圖 58 else if(strstr(str,"UDN")) 59 graphType=UDN; //無向網 60 else if(strstr(str,"DG")) 61 graphType=DG; //有向圖 62 else if(strstr(str,"DN")) 63 graphType=DN; //有向網 64 else 65 { 66 printf("錯誤:讀取圖的類型標記失敗!\n"); 67 fclose(pFile); //關閉文件 68 return false; 69 } 70 //讀取頂點數據到str。跳過空行 71 while(fgets(str,1000,pFile)!=NULL) 72 { 73 strLTrim(str); //刪除字符串左邊空格,這是一個自定義函數 74 if (str[0]=='\n') //空行,繼續讀取下一行 75 continue; 76 strncpy(strTemp,str,2); 77 if(strstr(strTemp,"//")!=NULL) //註釋行,跳過,繼續讀取下一行 78 continue; 79 else //非空行,也非註釋行,即圖的頂點元素行 80 break; 81 } 82 //頂點數據放入圖的頂點數組 83 char* token=strtok(str," "); 84 int nNum=0; 85 while(token!=NULL) 86 { 87 G.VerList[nNum].data=*token; 88 G.VerList[nNum].firstEdge=NULL; 89 token = strtok( NULL, " "); 90 nNum++; 91 } 92 //循環讀取邊(頂點對)數據 93 int nRow=0; //矩陣行下標 94 int nCol=0; //矩陣列下標 95 EdgeNode* eR; //邊鏈表尾指針 96 EdgeNode* p; 97 elementType Nf, Ns; //邊或弧的2個相鄰頂點 98 while(fgets(str,1000,pFile)!=NULL) 99 { 100 strLTrim(str); //刪除字符串左邊空格,這是一個自定義函數 101 if (str[0]=='\n') //空行,繼續讀取下一行 102 continue; 103 strncpy(strTemp,str,2); 104 if(strstr(strTemp,"//")!=NULL) //註釋行,跳過,繼續讀取下一行 105 continue; 106 char* token=strtok(str," "); //以空格爲分隔符,分割一行數據 107 if(token==NULL) //分割爲空串,失敗退出 108 { 109 printf("錯誤:讀取圖的邊數據失敗!\n"); 110 fclose(pFile); //關閉文件 111 return false; 112 } 113 Nf=*token; //獲取邊的第一個頂點 114 token = strtok( NULL, " "); //讀取下一個子串,即第二個頂點 115 if(token==NULL) //分割爲空串,失敗退出 116 { 117 printf("錯誤:讀取圖的邊數據失敗!\n"); 118 fclose(pFile); //關閉文件 119 return false; 120 } 121 Ns=*token; //獲取邊的第二個頂點 122 //從第一個頂點獲取行號 123 for(nRow=0;nRow<nNum;nRow++) 124 { 125 if(G.VerList[nRow].data==Nf) //從頂點列表找到第一個頂點的編號 126 break; 127 } 128 //從第二個頂點獲取列號 129 for(nCol=0;nCol<nNum;nCol++) 130 { 131 if(G.VerList[nCol].data==Ns) //從頂點列表找到第二個頂點的編號 132 break; 133 } 134 //若是爲網,讀取權值 135 if(graphType==UDN || graphType==DN) 136 { //讀取下一個子串,即邊的附加信息,常爲邊的權重 137 token = strtok( NULL, " "); 138 if(token==NULL) //分割爲空串,失敗退出 139 { 140 printf("錯誤:讀取圖的邊數據失敗!\n"); 141 fclose(pFile); //關閉文件 142 return false; 143 } 144 eWeight=atoi(token); //取得邊的附加信息,即權值 145 } 146 eR=G.VerList[nRow].firstEdge; 147 while(eR!=NULL && eR->next!=NULL) 148 { 149 eR=eR->next; //後移邊鏈表指針,直至尾節點 150 } 151 p=new EdgeNode; //申請一個邊鏈表結點 152 p->adjVer=nCol+1; //頂點的編號,從1開始 153 //邊的附加信息(權值),對有權圖保存權值,無權圖爲1 154 if(graphType==UDN || graphType==DN) 155 p->eInfo=eWeight; 156 else 157 p->eInfo=1; 158 p->next=NULL; 159 if(G.VerList[nRow].firstEdge==NULL) 160 { 161 G.VerList[nRow].firstEdge=p; 162 eR=p; 163 } 164 else 165 { 166 eR->next=p; 167 eR=p; //新的尾指針 168 } 169 edgeNum++; //邊數加1 170 } 171 G.VerNum=nNum; //圖的頂點數 172 if(graphType==UDG || graphType==UDN) 173 G.ArcNum=edgeNum / 2; //無向圖或網的邊數等於統計的數字除2 174 else 175 G.ArcNum=edgeNum; 176 G.gKind=graphType; //圖的類型 177 fclose(pFile); //關閉文件 178 return true; 179 }
4. 圖的銷燬
以鄰接矩陣爲存儲結構的圖,由於使用矩陣存儲圖的數據,不存在銷燬(釋放內存)問題。可是以鄰接表爲存儲結構的圖,因爲在建立圖的過程當中使用malloc()函數或new操做符動態申請了內存,當這個圖再也不須要時,必須手工釋放動態申請的內存,不然形成內存泄漏。下面給出一個銷燬鄰接表表示的圖的程序。
8.4 運行截圖
圖2 運行結果
圖3 運行結果
圖4 遍歷圖dn10.grp
圖5 求圖dn10.grp的邊數
圖6 深度優先遍歷圖dn10.grp
圖7 廣度優先遍歷圖dn10.grp
圖8 遍歷森林ung114.grp
圖9 求森林ung114.grp的邊數
圖10 深度優先遍歷森林ung114.grp
圖11 廣度優先遍歷森林ung114.grp
圖12 遍歷圖ung8.grp
圖13 求圖ung8.grp的邊數
圖14 深度優先遍歷圖ung8.grp
圖15 廣度優先遍歷圖ung8.grp
部分測試數據與數據文件對照圖:
數據文件dn10.grp:
//文件能夠加註釋行,註釋以//開始,且必須頂頭開始,不能有空格
//文件不能有空行
//Graph爲圖標誌,不然斷定格式不對
//標誌行後,第一行爲圖的類型。UDG--無向圖;UDN--無向網;DG--有向圖;DN--有向網
//標誌行後,第二行爲頂點元素
//頂點行如下圖的邊或弧。用頂點表示,第一列以頂點編號排列;第二列爲鄰接點;在網中增長一列表示權值。
//此圖爲一個10個頂點、15條邊的有向網。
//標識爲圖數據
Graph
//標識有向網
DN
//頂點數據列表,對應的編號爲1,2,3,4,...
a b c d e f g h i j
//如下爲邊數據,共15條邊
a b 2
a d 20
b e 1
c a 3
d c 8
d f 6
d g 4
e c 7
e h 3
f c 1
g h 1
h f 2
h j 2
i g 2
j i 1
圖16 數據dn10.grp對照圖
數據文件ung114.grp:
//文件能夠加註釋行,註釋以//開始,且必須頂頭開始,不能有空格
//文件不能有空行
//Graph爲圖標誌,不然斷定格式不對
//標誌行後,第一行爲圖的類型。UDG--無向圖;UDN--無向網;DG--有向圖;DN--有向網
//標誌行後,第二行爲頂點元素
//頂點行如下圖的邊或弧。用頂點表示,第一列以頂點編號排列;第二列爲鄰接點;在網中增長一列表示權值。
//此圖爲一個有11個頂點、9條邊的非連通的無向圖。
Graph
UDG
//下面爲頂點列表,對應的編號爲1,2,3,4,...
a b c d e f g h i j k
//如下爲鄰接點(邊)信息
//第一連通份量
a b
a d
b a
b c
c b
c d
d a
d c
//第二連通份量
e f
f e
f g
g f
//第三連通份量
h i
h k
i h
i j
j i
k h
圖17 數據ung114.grp對照圖
數據文件udg8.grp:
//文件能夠加註釋行,註釋以//開始,且必須頂頭開始,不能有空格
//文件不能有空行
//Graph爲圖標誌,不然斷定格式不對
//標誌行後,第一行爲圖的類型。UDG--無向圖;UDN--無向網;DG--有向圖;DN--有向網
//標誌行後,第二行爲頂點元素
//頂點行如下圖的邊或弧。用頂點表示,第一列以頂點編號排列;第二列爲鄰接點;在網中增長一列表示權值。
//此圖爲一個有8個頂點、9條邊的無向圖。
Graph
UDG
//下面爲頂點列表,對應的編號爲1,2,3,4,...
a b c d e f g h
//如下爲鄰接點(邊)信息
a b
a c
b a
b d
b e
c a
c g
c h
d b
d f
e b
e f
f d
f e
g c
g h
h c
h g
圖18 數據udg8.grp對照圖
8.5 附源代碼
嚴正聲明:此部分代碼徹底非本人所寫,而是某個不具名大佬的手筆。本人秉着方便學習、互相交流的精神將代碼貼在此處,原做者若有異議,請聯繫本人,即刻刪除。
頭文件 vNode.h:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #ifndef VNODE_H 2 #define VNODE_H 3 4 class vNode 5 { 6 public: 7 vNode(int r_id, char r_data); 8 int id(); 9 char data(); 10 bool flag1(); 11 void T_flag1(); 12 void F_flag1(); 13 bool flag2(); 14 void T_flag2(); 15 void F_flag2(); 16 bool flag3(); 17 void T_flag3(); 18 void F_flag3(); 19 void clear_flag(); 20 ~vNode(); 21 private: 22 int V_id; 23 char V_data; 24 bool V_flag1; 25 bool V_flag2; 26 bool V_flag3; 27 }; 28 29 #endif
源文件 vNode.h:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #include "pch.h" 2 3 #ifndef VNODE_CPP 4 #define VNODE_CPP 5 6 #include "vNode.h" 7 8 vNode::vNode(int r_id, char r_data) 9 { 10 this->V_id = r_id; 11 this->V_data = r_data; 12 this->V_flag1 = false; 13 this->V_flag2 = false; 14 this->V_flag3 = false; 15 } 16 17 int vNode::id() 18 { 19 return this->V_id; 20 } 21 22 char vNode::data() 23 { 24 return this->V_data; 25 } 26 27 bool vNode::flag1() 28 { 29 return this->V_flag1; 30 } 31 32 void vNode::T_flag1() 33 { 34 this->V_flag1 = true; 35 } 36 37 void vNode::F_flag1() 38 { 39 this->V_flag1 = false; 40 } 41 42 bool vNode::flag2() 43 { 44 return this->V_flag2; 45 } 46 47 void vNode::T_flag2() 48 { 49 this->V_flag2 = true; 50 } 51 52 void vNode::F_flag2() 53 { 54 this->V_flag2 = false; 55 } 56 57 bool vNode::flag3() 58 { 59 return this->V_flag3; 60 } 61 62 void vNode::T_flag3() 63 { 64 this->V_flag3 = true; 65 } 66 67 void vNode::F_flag3() 68 { 69 this->V_flag3 = false; 70 } 71 72 void vNode::clear_flag() 73 { 74 this->V_flag1 = false; 75 this->V_flag2 = false; 76 this->V_flag3 = false; 77 } 78 79 80 vNode::~vNode() 81 { 82 } 83 84 #endif
頭文件 pch.h:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #ifndef PCH_H 2 #define PCH_H 3 4 // TODO: 添加要在此處預編譯的標頭 5 #include <iostream> 6 #include <fstream> 7 #include <cstdlib> 8 #include <cstring> 9 #include <cctype> 10 #include <list> 11 #include <vector> 12 #include <stack> 13 #include <queue> 14 15 #endif //PCH_H
源文件 pch.cpp:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #include "pch.h" 2 3 #ifndef PCH_CPP 4 #define PCH_CPP 5 6 7 8 #endi
頭文件 eNode.h:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #ifndef ENODE_H 2 #define ENODE_H 3 4 #include "vNode.cpp" 5 6 //#define INF 65535 7 8 class eNode 9 { 10 public: 11 eNode(int r_id, vNode *v_begin, vNode *v_end, int r_len); 12 int id(); 13 vNode *begin(); 14 vNode *end(); 15 int len(); 16 bool flag1(); 17 void T_flag1(); 18 void F_flag1(); 19 bool flag2(); 20 void T_flag2(); 21 void F_flag2(); 22 bool flag3(); 23 void T_flag3(); 24 void F_flag3(); 25 void clear_flag(); 26 ~eNode(); 27 private: 28 int E_id; 29 vNode *E_begin; 30 vNode *E_end; 31 int E_len; 32 bool E_flag1; 33 bool E_flag2; 34 bool E_flag3; 35 }; 36 37 #endif
源文件 eNode.cpp:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #include "pch.h" 2 3 #ifndef ENODE_CPP 4 #define ENODE_CPP 5 6 #include "eNode.h" 7 8 eNode::eNode(int r_id, vNode *v_begin, vNode *v_end, int r_len) 9 { 10 this->E_id = r_id; 11 this->E_begin = v_begin; 12 this->E_end = v_end; 13 this->E_len = r_len; 14 this->E_flag1 = false; 15 this->E_flag2 = false; 16 this->E_flag3 = false; 17 } 18 19 int eNode::id() 20 { 21 return this->E_id; 22 } 23 24 vNode * eNode::begin() 25 { 26 return this->E_begin; 27 } 28 29 vNode * eNode::end() 30 { 31 return this->E_end; 32 } 33 34 int eNode::len() 35 { 36 return this->E_len; 37 } 38 39 bool eNode::flag1() 40 { 41 return this->E_flag1; 42 } 43 44 void eNode::T_flag1() 45 { 46 this->E_flag1 = true; 47 } 48 49 void eNode::F_flag1() 50 { 51 this->E_flag1 = false; 52 } 53 54 bool eNode::flag2() 55 { 56 return this->E_flag2; 57 } 58 59 void eNode::T_flag2() 60 { 61 this->E_flag2 = true; 62 } 63 64 void eNode::F_flag2() 65 { 66 this->E_flag2 = false; 67 } 68 69 bool eNode::flag3() 70 { 71 return this->E_flag3; 72 } 73 74 void eNode::T_flag3() 75 { 76 this->E_flag3 = true; 77 } 78 79 void eNode::F_flag3() 80 { 81 this->E_flag3 = false; 82 } 83 84 void eNode::clear_flag() 85 { 86 this->E_flag1 = false; 87 this->E_flag2 = false; 88 this->E_flag3 = false; 89 } 90 91 92 eNode::~eNode() 93 { 94 } 95 96 #endif
頭文件 adjListNode.h:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #ifndef ADJLISTNODE_H 2 #define ADJLISTNODE_H 3 4 #include "vNode.cpp" 5 #include "eNode.cpp" 6 7 class adjListNode 8 { 9 public: 10 adjListNode(vNode *r_v); 11 vNode *v(); 12 std::list<eNode *> &eList(); 13 void add_adj_e(eNode *r_e); 14 eNode *get_first_adj_e(); 15 eNode *get_next_adj_e(eNode *e); 16 void clear(); 17 ~adjListNode(); 18 private: 19 vNode *N_v; 20 std::list<eNode *> N_eList; 21 }; 22 23 #endif
源文件 adjListNode.cpp:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #include "pch.h" 2 3 #ifndef ADJLISTNODE_CPP 4 #define ADJLISTNODE_CPP 5 6 #include "adjListNode.h" 7 8 adjListNode::adjListNode(vNode *r_v) 9 { 10 this->N_v = r_v; 11 } 12 13 vNode * adjListNode::v() 14 { 15 return this->N_v; 16 } 17 18 std::list<eNode*>& adjListNode::eList() 19 { 20 // TODO: 在此處插入 return 語句 21 return this->N_eList; 22 } 23 24 void adjListNode::add_adj_e(eNode * r_e) 25 { 26 this->N_eList.push_back(r_e); 27 } 28 29 eNode * adjListNode::get_first_adj_e() 30 { 31 if (!this->N_eList.empty()) 32 { 33 return this->N_eList.front(); 34 } 35 return NULL; 36 } 37 38 eNode * adjListNode::get_next_adj_e(eNode * e) 39 { 40 std::list <eNode *>::iterator i = this->N_eList.begin(); 41 while (i != this->N_eList.end()) 42 { 43 if (*i == e) 44 { 45 ++i; 46 break; 47 } 48 i++; 49 } 50 if (i != this->N_eList.end()) 51 { 52 return *i; 53 } 54 return NULL; 55 } 56 57 void adjListNode::clear() 58 { 59 this->N_eList.clear(); 60 } 61 62 63 adjListNode::~adjListNode() 64 { 65 } 66 67 #endif
頭文件 graph.h:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #include "pch.h" 2 3 #ifndef GRAPH_H 4 #define GRAPH_H 5 6 #include "vNode.cpp" 7 #include "eNode.cpp" 8 #include "adjListNode.cpp" 9 10 #ifndef MAX_V_NUM 11 #define MAX_V_NUM 40 12 13 #endif 14 15 class graph 16 { 17 public: 18 graph(); 19 graph(const char *fileName); 20 int init_list(void); 21 int dfsTraversal_l(); 22 int dfsTraversal_l(vNode *V); 23 int dfs_l(vNode *V); 24 int bfsTraversal_l(); 25 int bfsTraversal_l(vNode *V); 26 int bfs_l(vNode *V); 27 int dfsTraversal_t_l(); 28 int dfsTraversal_t_l(vNode *V); 29 int dfs_t_l(vNode *V, std::list<vNode *>&Lv, std::list<eNode *>&Le); 30 int bfsTraversal_t_l(); 31 int bfsTraversal_t_l(vNode *V); 32 int bfs_t_l(vNode *V, std::list<vNode *>&Lv, std::list<eNode *>&Le); 33 int get_Enum_l(); 34 int Prim_l(vNode *V); 35 int Kruskal_l(void); 36 int Dijkstra_l(vNode *V); 37 int Floyd_l(void); 38 int AOV_l(void); 39 int AOE_l(void); 40 int dfsTraversal_m(); 41 int dfs_m(vNode *V); 42 bool empty(void); 43 bool error(void); 44 vNode *getNode_for_data(const char n_data); 45 vNode *getNode_for_ID(const int id); 46 int clear_vFlag(); 47 int clear_eFlag(); 48 int clear_eFlag_l(); 49 int coverGraph(const char *fileName); 50 int delete_G(void); 51 ~graph(); 52 private: 53 bool G_empty; 54 bool G_error; 55 bool G_U; 56 bool G_N; 57 int G_type; 58 int G_Vnum; 59 int G_Enum; 60 vNode *G_vList[MAX_V_NUM]; 61 std::list<eNode *> G_eList; 62 eNode *G_adjMat[MAX_V_NUM][MAX_V_NUM]; 63 std::list<adjListNode *> G_adjList; 64 std::list<adjListNode *> G_i_adjList; 65 }; 66 67 #endif
源文件 graph.cpp:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #include "pch.h" 2 3 #ifndef GRAPH_CPP 4 #define GRAPH_CPP 5 6 #include "graph.h" 7 8 graph::graph() 9 { 10 this->G_empty = true; 11 } 12 13 graph::graph(const char *fileName) 14 { 15 int i; 16 int j; 17 i = 0; 18 while (i < MAX_V_NUM) 19 { 20 this->G_vList[i] = NULL; 21 j = 0; 22 while (j < MAX_V_NUM) 23 { 24 this->G_adjMat[i][j] = NULL; 25 j++; 26 } 27 i++; 28 } 29 30 this->coverGraph(fileName); 31 } 32 33 int graph::init_list(void) 34 { 35 int i; 36 adjListNode *pa = NULL; 37 std::list<eNode *>::iterator i_e; 38 std::list<adjListNode *>::iterator i_a; 39 std::list<adjListNode *>::iterator i_i_a; 40 i = 0; 41 while (i < this->G_Vnum) 42 { 43 pa = new adjListNode(this->G_vList[i]); 44 if (pa != NULL) 45 { 46 this->G_adjList.push_back(pa); 47 } 48 pa = new adjListNode(this->G_vList[i]); 49 if (pa != NULL) 50 { 51 this->G_i_adjList.push_back(pa); 52 } 53 else 54 { 55 return -1; 56 } 57 i++; 58 } 59 i_e = this->G_eList.begin(); 60 while (i_e != this->G_eList.end()) 61 { 62 i_a = this->G_adjList.begin(); 63 while (i_a != this->G_adjList.end()) 64 { 65 if ((*i_a)->v()->data() == (*i_e)->begin()->data()) 66 { 67 (*i_a)->add_adj_e(*i_e); 68 break; 69 } 70 i_a++; 71 } 72 i_i_a = this->G_i_adjList.begin(); 73 while (i_i_a != this->G_i_adjList.end()) 74 { 75 if ((*i_i_a)->v()->data() == (*i_e)->end()->data()) 76 { 77 (*i_i_a)->add_adj_e(*i_e); 78 break; 79 } 80 i_i_a++; 81 } 82 if (i_a == this->G_adjList.end() || i_i_a == this->G_i_adjList.end()) 83 { 84 return -1; 85 } 86 i_e++; 87 } 88 return 0; 89 } 90 91 int graph::dfsTraversal_l() 92 { 93 int i; 94 std::cout << "深度優先遍歷序列爲:" << std::endl; 95 this->clear_vFlag(); 96 i = 0; 97 while (i < this->G_Vnum) 98 { 99 if (!this->G_vList[i]->flag1()) 100 { 101 dfs_l(this->G_vList[i]); 102 } 103 i++; 104 } 105 std::cout << std::endl; 106 return 0; 107 } 108 109 int graph::dfsTraversal_l(vNode * V) 110 { 111 int i; 112 if (V == NULL) 113 { 114 std::cout << "結點不存在!" << std::endl; 115 return -1; 116 } 117 std::cout << "深度優先遍歷序列爲:" << std::endl; 118 this->clear_vFlag(); 119 dfs_l(V); 120 i = 0; 121 while (i < this->G_Vnum) 122 { 123 if (!this->G_vList[i]->flag1()) 124 { 125 dfs_l(this->G_vList[i]); 126 } 127 i++; 128 } 129 std::cout << std::endl; 130 return 0; 131 } 132 133 int graph::dfs_l(vNode *V) 134 { 135 std::list<adjListNode *>::iterator i_a; 136 eNode *p_e; 137 if (V == NULL) 138 { 139 return -1; 140 } 141 if (V->flag1()) 142 { 143 return 0; 144 } 145 std::cout << V->data() << ' '; 146 V->T_flag1(); 147 i_a = this->G_adjList.begin(); 148 while (i_a != this->G_adjList.end()) 149 { 150 if ((*i_a)->v() == V) 151 { 152 break; 153 } 154 i_a++; 155 } 156 if (i_a == this->G_adjList.end()) 157 { 158 return -1; 159 } 160 p_e = (*i_a)->get_first_adj_e(); 161 while (p_e != NULL) 162 { 163 //std::cout << p_e->begin()->data() << ' ' << p_e->end()->data() << std::endl; 164 dfs_l(p_e->end()); 165 p_e = (*i_a)->get_next_adj_e(p_e); 166 } 167 return 0; 168 } 169 170 int graph::bfsTraversal_l() 171 { 172 int i; 173 std::cout << "廣度優先遍歷序列爲:" << std::endl; 174 this->clear_vFlag(); 175 i = 0; 176 while (i < this->G_Vnum) 177 { 178 if (!this->G_vList[i]->flag1()) 179 { 180 bfs_l(this->G_vList[i]); 181 } 182 i++; 183 } 184 std::cout << std::endl; 185 return 0; 186 } 187 188 int graph::bfsTraversal_l(vNode * V) 189 { 190 int i; 191 if (V == NULL) 192 { 193 std::cout << "結點不存在!" << std::endl; 194 return -1; 195 } 196 std::cout << "廣度優先遍歷序列爲:" << std::endl; 197 this->clear_vFlag(); 198 bfs_l(V); 199 i = 0; 200 while (i < this->G_Vnum) 201 { 202 if (!this->G_vList[i]->flag1()) 203 { 204 bfs_l(this->G_vList[i]); 205 } 206 i++; 207 } 208 std::cout << std::endl; 209 return 0; 210 } 211 212 int graph::bfs_l(vNode * V) 213 { 214 vNode *p; 215 std::queue<vNode *> Q; 216 std::list<adjListNode *>::iterator i_a; 217 std::list<eNode *>::iterator i_e; 218 if (V == NULL) 219 { 220 return -1; 221 } 222 Q.push(V); 223 while (!Q.empty()) 224 { 225 p = Q.front(); 226 Q.pop(); 227 if (p->flag1()) 228 { 229 continue; 230 } 231 std::cout << p->data() << ' '; 232 p->T_flag1(); 233 i_a = this->G_adjList.begin(); 234 while (i_a != this->G_adjList.end()) 235 { 236 if ((*i_a)->v()->data() == p->data()) 237 { 238 break; 239 } 240 i_a++; 241 } 242 if (i_a == this->G_adjList.end()) 243 { 244 return -1; 245 } 246 i_e = (*i_a)->eList().begin(); 247 while (i_e != (*i_a)->eList().end()) 248 { 249 if (!(*i_e)->end()->flag1()) 250 { 251 Q.push((*i_e)->end()); 252 } 253 i_e++; 254 } 255 } 256 return 0; 257 } 258 259 int graph::dfsTraversal_t_l() 260 { 261 int i; 262 std::list<vNode*> Lv; 263 std::list<eNode*> Le; 264 std::list<vNode*>::iterator iv; 265 std::list<eNode*>::iterator ie; 266 std::cout << "深度優先遍歷序列爲:" << std::endl; 267 this->clear_vFlag(); 268 i = 0; 269 while (i < this->G_Vnum) 270 { 271 if (!this->G_vList[i]->flag1()) 272 { 273 dfs_t_l(this->G_vList[i], Lv, Le); 274 } 275 i++; 276 } 277 std::cout << std::endl; 278 std::cout << "深度優先遍歷生成樹(森林)以下:" << std::endl; 279 std::cout << "點集:" << std::endl; 280 iv = Lv.begin(); 281 while (iv != Lv.end()) 282 { 283 std::cout << (*iv)->data() << ' '; 284 iv++; 285 } 286 std::cout << std::endl; 287 std::cout << "邊集:" << std::endl; 288 ie = Le.begin(); 289 while (ie != Le.end()) 290 { 291 std::cout << (*ie)->begin()->data(); 292 if (G_U) 293 { 294 std::cout << '-'; 295 } 296 else 297 { 298 std::cout << "->"; 299 } 300 std::cout << (*ie)->end()->data() << std::endl; 301 ie++; 302 } 303 std::cout << std::endl; 304 return 0; 305 } 306 307 int graph::dfsTraversal_t_l(vNode * V) 308 { 309 int i; 310 std::list<vNode*> Lv; 311 std::list<eNode*> Le; 312 std::list<vNode*>::iterator iv; 313 std::list<eNode*>::iterator ie; 314 if (V == NULL) 315 { 316 std::cout << "結點不存在!" << std::endl; 317 return -1; 318 } 319 std::cout << "深度優先遍歷序列爲:" << std::endl; 320 this->clear_vFlag(); 321 dfs_t_l(V, Lv, Le); 322 i = 0; 323 while (i < this->G_Vnum) 324 { 325 if (!this->G_vList[i]->flag1()) 326 { 327 dfs_t_l(this->G_vList[i], Lv, Le); 328 } 329 i++; 330 } 331 std::cout << std::endl; 332 std::cout << "深度優先遍歷生成樹(森林)以下:" << std::endl; 333 std::cout << "點集:" << std::endl; 334 iv = Lv.begin(); 335 while (iv != Lv.end()) 336 { 337 std::cout << (*iv)->data() << ' '; 338 iv++; 339 } 340 std::cout << std::endl; 341 std::cout << "邊集:" << std::endl; 342 ie = Le.begin(); 343 while (ie != Le.end()) 344 { 345 std::cout << (*ie)->begin()->data(); 346 if (G_U) 347 { 348 std::cout << '-'; 349 } 350 else 351 { 352 std::cout << "->"; 353 } 354 std::cout << (*ie)->end()->data() << std::endl; 355 ie++; 356 } 357 std::cout << std::endl; 358 return 0; 359 } 360 361 int graph::dfs_t_l(vNode * V, std::list<vNode*>& Lv, std::list<eNode*>& Le) 362 { 363 std::list<adjListNode *>::iterator i_a; 364 eNode *p_e; 365 if (V == NULL) 366 { 367 return -1; 368 } 369 if (V->flag1()) 370 { 371 Le.pop_back(); 372 return 0; 373 } 374 std::cout << V->data() << ' '; 375 V->T_flag1(); 376 Lv.push_back(V); 377 i_a = this->G_adjList.begin(); 378 while (i_a != this->G_adjList.end()) 379 { 380 if ((*i_a)->v() == V) 381 { 382 break; 383 } 384 i_a++; 385 } 386 if (i_a == this->G_adjList.end()) 387 { 388 return -1; 389 } 390 p_e = (*i_a)->get_first_adj_e(); 391 while (p_e != NULL) 392 { 393 //std::cout << p_e->begin()->data() << ' ' << p_e->end()->data() << std::endl; 394 Le.push_back(p_e); 395 dfs_t_l(p_e->end(), Lv, Le); 396 p_e = (*i_a)->get_next_adj_e(p_e); 397 } 398 return 0; 399 } 400 401 int graph::bfsTraversal_t_l() 402 { 403 int i; 404 std::list<vNode*> Lv; 405 std::list<eNode*> Le; 406 std::list<vNode*>::iterator iv; 407 std::list<eNode*>::iterator ie; 408 std::cout << "廣度優先遍歷序列爲:" << std::endl; 409 this->clear_vFlag(); 410 i = 0; 411 while (i < this->G_Vnum) 412 { 413 if (!this->G_vList[i]->flag1()) 414 { 415 bfs_t_l(this->G_vList[i], Lv, Le); 416 } 417 i++; 418 } 419 std::cout << std::endl; 420 std::cout << "廣度優先遍歷生成樹(森林)以下:" << std::endl; 421 std::cout << "點集:" << std::endl; 422 iv = Lv.begin(); 423 while (iv != Lv.end()) 424 { 425 std::cout << (*iv)->data() << ' '; 426 iv++; 427 } 428 std::cout << std::endl; 429 std::cout << "邊集:" << std::endl; 430 ie = Le.begin(); 431 while (ie != Le.end()) 432 { 433 std::cout << (*ie)->begin()->data(); 434 if (G_U) 435 { 436 std::cout << '-'; 437 } 438 else 439 { 440 std::cout << "->"; 441 } 442 std::cout << (*ie)->end()->data() << std::endl; 443 ie++; 444 } 445 std::cout << std::endl; 446 return 0; 447 } 448 449 int graph::bfsTraversal_t_l(vNode * V) 450 { 451 int i; 452 std::list<vNode*> Lv; 453 std::list<eNode*> Le; 454 std::list<vNode*>::iterator iv; 455 std::list<eNode*>::iterator ie; 456 if (V == NULL) 457 { 458 std::cout << "結點不存在!" << std::endl; 459 return -1; 460 } 461 std::cout << "廣度優先遍歷序列爲:" << std::endl; 462 this->clear_vFlag(); 463 bfs_t_l(V, Lv, Le); 464 i = 0; 465 while (i < this->G_Vnum) 466 { 467 if (!this->G_vList[i]->flag1()) 468 { 469 bfs_t_l(this->G_vList[i], Lv, Le); 470 } 471 i++; 472 } 473 std::cout << std::endl; 474 std::cout << "廣度優先遍歷生成樹(森林)以下:" << std::endl; 475 std::cout << "點集:" << std::endl; 476 iv = Lv.begin(); 477 while (iv != Lv.end()) 478 { 479 std::cout << (*iv)->data() << ' '; 480 iv++; 481 } 482 std::cout << std::endl; 483 std::cout << "邊集:" << std::endl; 484 ie = Le.begin(); 485 while (ie != Le.end()) 486 { 487 std::cout << (*ie)->begin()->data(); 488 if (G_U) 489 { 490 std::cout << '-'; 491 } 492 else 493 { 494 std::cout << "->"; 495 } 496 std::cout << (*ie)->end()->data() << std::endl; 497 ie++; 498 } 499 std::cout << std::endl; 500 return 0; 501 } 502 503 int graph::bfs_t_l(vNode * V, std::list<vNode*>& Lv, std::list<eNode*>& Le) 504 { 505 vNode *p; 506 std::queue<vNode *> Q; 507 std::list<adjListNode *>::iterator i_a; 508 std::list<eNode *>::iterator i_e; 509 if (V == NULL || V->flag1()) 510 { 511 return -1; 512 } 513 Q.push(V); 514 V->T_flag1(); 515 while (!Q.empty()) 516 { 517 p = Q.front(); 518 Q.pop(); 519 std::cout << p->data() << ' '; 520 Lv.push_back(p); 521 i_a = this->G_adjList.begin(); 522 while (i_a != this->G_adjList.end()) 523 { 524 if ((*i_a)->v()->data() == p->data()) 525 { 526 break; 527 } 528 i_a++; 529 } 530 if (i_a == this->G_adjList.end()) 531 { 532 return -1; 533 } 534 i_e = (*i_a)->eList().begin(); 535 while (i_e != (*i_a)->eList().end()) 536 { 537 if (!(*i_e)->end()->flag1()) 538 { 539 Q.push((*i_e)->end()); 540 (*i_e)->end()->T_flag1(); 541 Le.push_back(*i_e); 542 } 543 i_e++; 544 } 545 } 546 return 0; 547 } 548 549 int graph::get_Enum_l() 550 { 551 int e_num = 0; 552 std::list<adjListNode *>::iterator i_a = this->G_adjList.begin(); 553 while (i_a != this->G_adjList.end()) 554 { 555 e_num += (*i_a)->eList().size(); 556 i_a++; 557 } 558 if (G_U) 559 { 560 e_num /= 2; 561 } 562 return e_num; 563 } 564 565 int graph::Prim_l(vNode * V) 566 { 567 int i = 0; 568 int num = 1; 569 vNode *pv = NULL; 570 eNode *pe = NULL; 571 std::list<vNode *> V_l; 572 std::list<vNode *>::iterator iv; 573 std::list<eNode *> E_l; 574 std::list<eNode *> E_l2; 575 std::list<eNode *>::iterator ie; 576 std::list<adjListNode *>::iterator ia; 577 if (V == NULL) 578 { 579 return -1; 580 } 581 this->clear_vFlag(); 582 V_l.push_back(V); 583 while (E_l.size() < this->G_Vnum - 1) 584 { 585 pv = V_l.back(); 586 pv->T_flag1(); 587 ie = E_l2.begin(); 588 while (ie != E_l2.end()) 589 { 590 if ((*ie)->end()->flag1()) 591 { 592 ie = E_l2.erase(ie); 593 } 594 else 595 { 596 ie++; 597 } 598 } 599 ia = this->G_adjList.begin(); 600 while (ia != this->G_adjList.end()) 601 { 602 if ((*ia)->v()->data() == pv->data()) 603 { 604 break; 605 } 606 ia++; 607 } 608 if (ia == this->G_adjList.end()) 609 { 610 return -1; 611 } 612 ie = (*ia)->eList().begin(); 613 while (ie != (*ia)->eList().end()) 614 { 615 if (!(*ie)->end()->flag1()) 616 { 617 E_l2.push_back(*ie); 618 } 619 ie++; 620 } 621 if (!E_l2.empty()) 622 { 623 ie = E_l2.begin(); 624 pe = (*ie); 625 while (ie != E_l2.end()) 626 { 627 if ((*ie)->len() < pe->len()) 628 { 629 pe = (*ie); 630 } 631 ie++; 632 } 633 } 634 else 635 { 636 break; 637 } 638 E_l.push_back(pe); 639 V_l.push_back(pe->end()); 640 } 641 std::cout << "Prim算法:" << std::endl; 642 std::cout << "起點:" << V->data() << std::endl; 643 std::cout << "最小生成樹以下:" << std::endl; 644 std::cout << "點集:" << std::endl; 645 iv = V_l.begin(); 646 while (iv != V_l.end()) 647 { 648 std::cout << (*iv)->data() << ' '; 649 iv++; 650 } 651 std::cout << std::endl; 652 std::cout << "邊集:" << std::endl; 653 if (E_l.empty()) 654 { 655 std::cout << "null!" << std::endl; 656 } 657 else 658 { 659 ie = E_l.begin(); 660 while (ie != E_l.end()) 661 { 662 if (!this->G_U) 663 { 664 std::cout << (*ie)->begin()->data() << "->" << (*ie)->end()->data() << ' '; 665 } 666 else 667 { 668 std::cout << (*ie)->begin()->data() << '-' << (*ie)->end()->data() << ' '; 669 } 670 if (this->G_N) 671 { 672 std::cout << "len:" << (*ie)->len(); 673 } 674 std::cout << std::endl; 675 ie++; 676 } 677 } 678 return 0; 679 } 680 681 int graph::Kruskal_l(void) 682 { 683 int i; 684 int low_f; 685 int high_f; 686 int V_f[MAX_V_NUM]; 687 std::list<eNode *> E_l; 688 std::list<eNode *> E_l2; 689 std::list<eNode *>::iterator ie; 690 std::list<eNode *>::iterator ie2; 691 std::list<adjListNode *>::iterator ia = this->G_adjList.begin(); 692 i = 0; 693 while (i < this->G_Vnum) 694 { 695 V_f[this->G_vList[i]->id()] = this->G_vList[i]->id(); 696 i++; 697 } 698 while (ia != this->G_adjList.end()) 699 { 700 ie = (*ia)->eList().begin(); 701 while (ie != (*ia)->eList().end()) 702 { 703 ie2 = E_l2.begin(); 704 while (ie2 != E_l2.end() && (*ie)->len() > (*ie2)->len()) 705 { 706 ie2++; 707 } 708 E_l2.insert(ie2, *ie); 709 ie++; 710 } 711 ia++; 712 } 713 ie2 = E_l2.begin(); 714 while (ie2 != E_l2.end() && E_l.size() < this->G_Vnum - 1) 715 { 716 if (V_f[(*ie2)->begin()->id()] != V_f[(*ie2)->end()->id()]) 717 { 718 E_l.push_back(*ie2); 719 if ((*ie2)->begin()->id() < (*ie2)->end()->id()) 720 { 721 low_f = V_f[(*ie2)->begin()->id()]; 722 high_f = V_f[(*ie2)->end()->id()]; 723 } 724 else 725 { 726 low_f = V_f[(*ie2)->end()->id()]; 727 high_f = V_f[(*ie2)->begin()->id()]; 728 } 729 i = 0; 730 while (i < this->G_Vnum) 731 { 732 if (V_f[i] == high_f) 733 { 734 V_f[i] = low_f; 735 } 736 //std::cout << V_f[i] << ' '; 737 i++; 738 } 739 //std::cout << std::endl; 740 //std::cout << "low:" << low_f << std::endl; 741 //std::cout << "high:" << high_f << std::endl; 742 } 743 ie2++; 744 } 745 std::cout << "Kruskal算法:" << std::endl; 746 std::cout << "最小生成樹以下:" << std::endl; 747 std::cout << "點集:" << std::endl; 748 i = 0; 749 while (i < this->G_Vnum) 750 { 751 std::cout << this->G_vList[i]->data() << ' '; 752 //std::cout << "flag:" << V_f[i] << ' '; 753 i++; 754 } 755 std::cout << std::endl; 756 std::cout << "邊集:" << std::endl; 757 if (E_l.empty()) 758 { 759 std::cout << "null!" << std::endl; 760 } 761 else 762 { 763 ie = E_l.begin(); 764 while (ie != E_l.end()) 765 { 766 if (!this->G_U) 767 { 768 std::cout << (*ie)->begin()->data() << "->" << (*ie)->end()->data() << ' '; 769 } 770 else 771 { 772 std::cout << (*ie)->begin()->data() << '-' << (*ie)->end()->data() << ' '; 773 } 774 if (this->G_N) 775 { 776 std::cout << "len:" << (*ie)->len(); 777 } 778 std::cout << std::endl; 779 ie++; 780 } 781 } 782 return 0; 783 } 784 785 int graph::Dijkstra_l(vNode * V) 786 { 787 int i; 788 int j; 789 int V_pathLen[MAX_V_NUM]; 790 vNode *pv; 791 eNode *pe; 792 vNode *V_prior[MAX_V_NUM]; 793 std::list<eNode *>::iterator ie; 794 std::list<adjListNode *>::iterator ia; 795 std::stack<char> S_ch; 796 797 if (V == NULL) 798 { 799 return -1; 800 } 801 802 this->clear_vFlag(); 803 804 i = 0; 805 while (i < MAX_V_NUM) 806 { 807 V_pathLen[i] = -1; 808 V_prior[i] = NULL; 809 i++; 810 } 811 812 V_pathLen[V->id()] = 0; 813 V->T_flag1(); 814 pv = V; 815 do 816 { 817 pe = NULL; 818 ia = this->G_adjList.begin(); 819 while (ia != this->G_adjList.end()) 820 { 821 if ((*ia)->v()->flag1()) 822 { 823 ie = (*ia)->eList().begin(); 824 while (ie != (*ia)->eList().end()) 825 { 826 if (!(*ie)->end()->flag1()) 827 { 828 if (pe == NULL || 829 pe->len() + V_pathLen[pe->begin()->id()] > 830 (*ie)->len() + V_pathLen[(*ie)->begin()->id()]) 831 { 832 pe = *ie; 833 } 834 } 835 ie++; 836 } 837 } 838 ia++; 839 } 840 if (pe != NULL) 841 { 842 pe->end()->T_flag1(); 843 V_pathLen[pe->end()->id()] = V_pathLen[pe->begin()->id()] + pe->len(); 844 V_prior[pe->end()->id()] = pe->begin(); 845 } 846 } while (pe != NULL); 847 std::cout << "Dijkstra算法:" << std::endl; 848 std::cout << "起點:" << V->data() << std::endl; 849 std::cout << "從起點至其餘各結點的最短路徑以下:" << std::endl; 850 i = 0; 851 while (i < this->G_Vnum) 852 { 853 std::cout << V->data() << "->" << this->G_vList[i]->data() << ':'; 854 if (V_prior[i] != NULL) 855 { 856 j = i; 857 while (V_prior[j] != NULL) 858 { 859 S_ch.push(this->getNode_for_ID(j)->data()); 860 j = V_prior[j]->id(); 861 } 862 std::cout << V->data(); 863 while (!S_ch.empty()) 864 { 865 std::cout << "->" << S_ch.top(); 866 S_ch.pop(); 867 } 868 std::cout << " 路徑長度:" << V_pathLen[i]; 869 } 870 else if (V_pathLen[i] == 0) 871 { 872 std::cout << this->G_vList[i]->data(); 873 std::cout << " 路徑長度:" << V_pathLen[i]; 874 } 875 else 876 { 877 std::cout << "路徑不存在!"; 878 } 879 std::cout << std::endl; 880 i++; 881 } 882 return 0; 883 } 884 885 int graph::Floyd_l(void) 886 { 887 int i; 888 int j; 889 int k; 890 int path_len[MAX_V_NUM][MAX_V_NUM]; 891 vNode *path[MAX_V_NUM][MAX_V_NUM]; 892 std::list<eNode *>::iterator ie; 893 std::list<adjListNode *>::iterator ia; 894 std::stack<char> S_ch; 895 896 i = 0; 897 while (i < this->G_Vnum) 898 { 899 j = 0; 900 while (j < this->G_Vnum) 901 { 902 path[i][j] = NULL; 903 if (i == j) 904 { 905 path_len[i][j] = 0; 906 } 907 else 908 { 909 path_len[i][j] = -1; 910 } 911 j++; 912 } 913 i++; 914 } 915 916 ia = this->G_adjList.begin(); 917 while (ia != this->G_adjList.end()) 918 { 919 ie = (*ia)->eList().begin(); 920 while (ie != (*ia)->eList().end()) 921 { 922 path[(*ie)->begin()->id()][(*ie)->end()->id()] = (*ie)->begin(); 923 path_len[(*ie)->begin()->id()][(*ie)->end()->id()] = (*ie)->len(); 924 ie++; 925 } 926 ia++; 927 } 928 929 k = 0; 930 while (k < this->G_Vnum) 931 { 932 i = 0; 933 while (i < this->G_Vnum) 934 { 935 j = 0; 936 while (j < this->G_Vnum) 937 { 938 if (path[i][k] != NULL && path[k][j] != NULL && i != j) 939 { 940 if (path[i][j] == NULL || 941 path_len[i][k] + path_len[k][j] < path_len[i][j]) 942 { 943 path[i][j] = this->G_vList[k]; 944 path_len[i][j] = path_len[i][k] + path_len[k][j]; 945 } 946 } 947 j++; 948 } 949 i++; 950 } 951 k++; 952 } 953 954 std::cout << "Floyd算法:" << std::endl; 955 std::cout << "各對結點之間的最短路徑以下:" << std::endl; 956 i = 0; 957 while (i < this->G_Vnum) 958 { 959 j = 0; 960 while (j < this->G_Vnum) 961 { 962 std::cout << this->G_vList[i]->data() << "->" << this->G_vList[j]->data() << ':'; 963 if (path[i][j] != NULL) 964 { 965 k = j; 966 while (path[i][k] != NULL && k != i) 967 { 968 S_ch.push(this->G_vList[k]->data()); 969 k = path[i][k]->id(); 970 } 971 if (k != i) 972 { 973 std::cout << "路徑不存在!"; 974 } 975 else 976 { 977 std::cout << this->G_vList[i]->data(); 978 while (!S_ch.empty()) 979 { 980 std::cout << "->" << S_ch.top(); 981 S_ch.pop(); 982 } 983 std::cout << " 路徑長度:" << path_len[i][j]; 984 } 985 } 986 else 987 { 988 if (i != j) 989 { 990 std::cout << "路徑不存在!"; 991 } 992 else 993 { 994 std::cout << this->G_vList[i]->data(); 995 std::cout << " 路徑長度:" << path_len[i][j]; 996 } 997 } 998 std::cout << std::endl; 999 j++; 1000 } 1001 i++; 1002 } 1003 1004 1005 return 0; 1006 } 1007 1008 int graph::AOV_l(void) 1009 { 1010 int i; 1011 int deg_i[MAX_V_NUM]; 1012 std::list<char> L_ch; 1013 vNode *pv; 1014 std::queue<vNode *> Q; 1015 std::list<adjListNode *>::iterator ia; 1016 std::list<eNode *>::iterator ie; 1017 1018 this->clear_vFlag(); 1019 1020 i = 0; 1021 while (i < this->G_Vnum) 1022 { 1023 deg_i[i] = 0; 1024 i++; 1025 } 1026 1027 ia = this->G_adjList.begin(); 1028 while (ia != this->G_adjList.end()) 1029 { 1030 ie = (*ia)->eList().begin(); 1031 while (ie != (*ia)->eList().end()) 1032 { 1033 deg_i[(*ie)->end()->id()] += 1; 1034 ie++; 1035 } 1036 ia++; 1037 } 1038 1039 i = 0; 1040 while (i < this->G_Vnum) 1041 { 1042 if (deg_i[i] == 0) 1043 { 1044 Q.push(getNode_for_ID(i)); 1045 } 1046 i++; 1047 } 1048 1049 while (!Q.empty()) 1050 { 1051 pv = Q.front(); 1052 Q.pop(); 1053 1054 pv->T_flag1(); 1055 L_ch.push_back(pv->data()); 1056 1057 ia = this->G_adjList.begin(); 1058 while (ia != this->G_adjList.end()) 1059 { 1060 if ((*ia)->v() == pv) 1061 { 1062 ie = (*ia)->eList().begin(); 1063 while (ie != (*ia)->eList().end()) 1064 { 1065 deg_i[(*ie)->end()->id()] -= 1; 1066 if (deg_i[(*ie)->end()->id()] == 0 && !(*ie)->end()->flag1()) 1067 { 1068 Q.push((*ie)->end()); 1069 } 1070 ie++; 1071 } 1072 } 1073 ia++; 1074 } 1075 } 1076 1077 if (L_ch.size() < this->G_Vnum) 1078 { 1079 std::cout << "該圖無拓撲序列!" << std::endl; 1080 } 1081 else 1082 { 1083 std::cout << "該圖的拓撲序列爲:"; 1084 while (!L_ch.empty()) 1085 { 1086 std::cout << L_ch.front() << ' '; 1087 L_ch.pop_front(); 1088 } 1089 std::cout << std::endl; 1090 } 1091 1092 return 0; 1093 } 1094 1095 int graph::AOE_l(void) 1096 { 1097 int i; 1098 int j; 1099 int len = 0; 1100 int deg_i[MAX_V_NUM]; 1101 int deg_o[MAX_V_NUM]; 1102 int minLs[MAX_V_NUM]; 1103 int minLe[MAX_V_NUM]; 1104 int maxLs[MAX_V_NUM]; 1105 int maxLe[MAX_V_NUM]; 1106 vNode *prior[MAX_V_NUM]; 1107 vNode *pv; 1108 eNode *pe; 1109 std::list<vNode *> L; 1110 std::list<vNode *> path; 1111 std::list<vNode *>::iterator iv; 1112 std::list<adjListNode *>::iterator ia; 1113 std::list<eNode *>::iterator ie; 1114 1115 this->clear_vFlag(); 1116 this->clear_eFlag_l(); 1117 1118 i = 0; 1119 while (i < this->G_Vnum) 1120 { 1121 prior[i] = NULL; 1122 deg_i[i] = 0; 1123 deg_o[i] = 0; 1124 minLs[i] = 0; 1125 minLe[i] = 0; 1126 maxLs[i] = 0; 1127 maxLe[i] = 0; 1128 i++; 1129 } 1130 1131 ia = this->G_adjList.begin(); 1132 while (ia != this->G_adjList.end()) 1133 { 1134 ie = (*ia)->eList().begin(); 1135 while (ie != (*ia)->eList().end()) 1136 { 1137 deg_i[(*ie)->end()->id()] += 1; 1138 deg_o[(*ie)->begin()->id()] += 1; 1139 ie++; 1140 } 1141 ia++; 1142 } 1143 1144 i = 0; 1145 while (i < this->G_Vnum) 1146 { 1147 if (deg_i[i] == 0) 1148 { 1149 minLs[i] = 0; 1150 L.push_back(getNode_for_ID(i)); 1151 getNode_for_ID(i)->T_flag1(); 1152 } 1153 i++; 1154 } 1155 1156 while (!L.empty()) 1157 { 1158 iv = L.begin(); 1159 while (iv != L.end()) 1160 { 1161 maxLe[(*iv)->id()] = len; 1162 iv++; 1163 } 1164 1165 pe = NULL; 1166 iv = L.begin(); 1167 while (iv != L.end()) 1168 { 1169 ia = this->G_adjList.begin(); 1170 while (ia != this->G_adjList.end()) 1171 { 1172 if ((*ia)->v() == (*iv)) 1173 { 1174 ie = (*ia)->eList().begin(); 1175 while (ie != (*ia)->eList().end()) 1176 { 1177 if (!(*ie)->flag1()) 1178 { 1179 if (pe == NULL || 1180 pe->len() - (maxLe[pe->begin()->id()] - minLs[pe->begin()->id()]) > 1181 (*ie)->len() - (maxLe[(*ie)->begin()->id()] - minLs[(*ie)->begin()->id()])) 1182 { 1183 pe = *ie; 1184 } 1185 } 1186 ie++; 1187 } 1188 break; 1189 } 1190 ia++; 1191 } 1192 iv++; 1193 } 1194 1195 if (pe != NULL) 1196 { 1197 //std::cout << pe->begin()->data() << "->" << pe->end()->data() << std::endl; 1198 1199 len += pe->len() - (maxLe[pe->begin()->id()] - minLs[pe->begin()->id()]); 1200 deg_i[pe->end()->id()] -= 1; 1201 deg_o[pe->begin()->id()] -= 1; 1202 pe->T_flag1(); 1203 1204 1205 if (deg_o[pe->begin()->id()] == 0) 1206 { 1207 iv = L.begin(); 1208 while (iv != L.end()) 1209 { 1210 if ((*iv) == pe->begin()) 1211 { 1212 break; 1213 } 1214 iv++; 1215 } 1216 (*iv)->T_flag2(); 1217 maxLe[(*iv)->id()] = len; 1218 //std::cout << (*iv)->data() << ' '; 1219 L.erase(iv); 1220 } 1221 1222 if (deg_i[pe->end()->id()] == 0) 1223 { 1224 if (!pe->end()->flag1()) 1225 { 1226 minLs[pe->end()->id()] = len; 1227 prior[pe->end()->id()] = pe->begin(); 1228 if (deg_o[pe->end()->id()] != 0) 1229 { 1230 L.push_back(pe->end()); 1231 } 1232 else 1233 { 1234 if (!pe->end()->flag2()) 1235 { 1236 maxLe[pe->end()->id()] = len + pe->len(); 1237 pe->end()->T_flag2(); 1238 } 1239 } 1240 pe->end()->T_flag1(); 1241 } 1242 } 1243 } 1244 else 1245 { 1246 break; 1247 } 1248 } 1249 1250 i = 0; 1251 j = 0; 1252 while (i < this->G_Vnum) 1253 { 1254 //std::cout << maxLe[i] << std::endl; 1255 if (maxLe[i] > maxLe[j]) 1256 { 1257 j = i; 1258 } 1259 i++; 1260 } 1261 1262 i = 0; 1263 while (i < this->G_Vnum) 1264 { 1265 if (!this->G_vList[i]->flag2()) 1266 { 1267 std::cout << "該圖不存在關鍵路徑!" << std::endl; 1268 return 0; 1269 } 1270 i++; 1271 } 1272 1273 pv = getNode_for_ID(j); 1274 while (pv != NULL) 1275 { 1276 path.push_front(pv); 1277 pv = prior[pv->id()]; 1278 } 1279 std::cout << "該圖的關鍵路徑爲:" << std::endl; 1280 iv = path.begin(); 1281 while (iv != path.end()) 1282 { 1283 std::cout << (*iv)->data(); 1284 ++iv; 1285 if (iv != path.end()) 1286 { 1287 std::cout << "->"; 1288 } 1289 } 1290 std::cout << std::endl; 1291 std::cout << "關鍵路徑的長度爲:" << maxLe[j] << std::endl; 1292 1293 return 0; 1294 } 1295 1296 bool graph::empty(void) 1297 { 1298 return this->G_empty; 1299 } 1300 1301 bool graph::error(void) 1302 { 1303 return this->G_error; 1304 } 1305 1306 vNode * graph::getNode_for_data(const char n_data) 1307 { 1308 int i = 0; 1309 while (i < this->G_Vnum) 1310 { 1311 if (this->G_vList[i] != NULL && this->G_vList[i]->data() == n_data) 1312 { 1313 break; 1314 } 1315 i++; 1316 } 1317 if (i >= this->G_Vnum) 1318 { 1319 return NULL; 1320 } 1321 return this->G_vList[i]; 1322 } 1323 1324 vNode * graph::getNode_for_ID(const int id) 1325 { 1326 if (id >= 0 && id < this->G_Vnum) 1327 { 1328 return this->G_vList[id]; 1329 } 1330 return NULL; 1331 } 1332 1333 int graph::clear_vFlag() 1334 { 1335 int i = 0; 1336 while (i < this->G_Vnum) 1337 { 1338 this->G_vList[i]->clear_flag(); 1339 i++; 1340 } 1341 return 0; 1342 } 1343 1344 int graph::clear_eFlag() 1345 { 1346 std::list<eNode *>::iterator ie = this->G_eList.begin(); 1347 while (ie != this->G_eList.end()) 1348 { 1349 (*ie)->clear_flag(); 1350 ie++; 1351 } 1352 return 0; 1353 } 1354 1355 int graph::clear_eFlag_l() 1356 { 1357 std::list<adjListNode *>::iterator ia = this->G_adjList.begin(); 1358 std::list<eNode *>::iterator ie; 1359 while (ia != this->G_adjList.end()) 1360 { 1361 ie = (*ia)->eList().begin(); 1362 while (ie != (*ia)->eList().end()) 1363 { 1364 (*ie)->clear_flag(); 1365 ie++; 1366 } 1367 ia++; 1368 } 1369 return 0; 1370 } 1371 1372 int graph::coverGraph(const char * fileName) 1373 { 1374 bool error = false; 1375 bool typeLine = false; 1376 bool nodeLine = false; 1377 bool eLine = false; 1378 int elen; 1379 int vID = 0; 1380 int eID = 0; 1381 char ch_a; 1382 char ch_b; 1383 char str[256]; 1384 vNode *pv = NULL; 1385 eNode *pe = NULL; 1386 std::ifstream fra; 1387 int ia; 1388 int ib; 1389 this->delete_G(); 1390 fra.open(fileName); 1391 if (!fra.good()) 1392 { 1393 this->G_error = true; 1394 return -3; 1395 } 1396 while (fra.good()) 1397 { 1398 fra >> str; 1399 //std::cout << eID << '-'; 1400 //std::cout << str << std::endl; 1401 if (strlen(str) == 0) 1402 { 1403 continue; 1404 } 1405 if (strncmp(str, "//", 2) == 0) 1406 { 1407 fra.getline(str, 255); 1408 continue; 1409 } 1410 if (!typeLine && !nodeLine && !eLine) 1411 { 1412 if (strcmp(str, "Graph") == 0) 1413 { 1414 typeLine = true; 1415 continue; 1416 } 1417 } 1418 if (typeLine) 1419 { 1420 if (strcmp(str, "UDG") == 0) 1421 { 1422 this->G_U = true; 1423 this->G_N = false; 1424 } 1425 else 1426 { 1427 if (strcmp(str, "DG") == 0) 1428 { 1429 this->G_U = false; 1430 this->G_N = false; 1431 } 1432 else 1433 { 1434 if (strcmp(str, "UDN") == 0) 1435 { 1436 this->G_U = true; 1437 this->G_N = true; 1438 } 1439 else 1440 { 1441 if (strcmp(str, "DN") == 0) 1442 { 1443 this->G_U = false; 1444 this->G_N = true; 1445 } 1446 else 1447 { 1448 error = true; 1449 break; 1450 } 1451 } 1452 } 1453 } 1454 typeLine = false; 1455 nodeLine = true; 1456 continue; 1457 } 1458 if (nodeLine) 1459 { 1460 ch_a = str[0]; 1461 this->G_vList[vID] = new vNode(vID, ch_a); 1462 if (G_vList[vID] == NULL) 1463 { 1464 error = true; 1465 break; 1466 } 1467 vID += 1; 1468 if (!fra.good()) 1469 { 1470 error = true; 1471 break; 1472 } 1473 ch_a = fra.get(); 1474 while (ch_a != '\n') 1475 { 1476 //std::cout << ch_a << ' '; 1477 if (!isspace(ch_a)) 1478 { 1479 this->G_vList[vID] = new vNode(vID, ch_a); 1480 if (G_vList[vID] == NULL) 1481 { 1482 error = true; 1483 break; 1484 } 1485 vID += 1; 1486 } 1487 if (!fra.good()) 1488 { 1489 error = true; 1490 break; 1491 } 1492 ch_a = fra.get(); 1493 } 1494 //std::cout << std::endl; 1495 if (error) 1496 { 1497 break; 1498 } 1499 this->G_Vnum = vID; 1500 nodeLine = false; 1501 eLine = true; 1502 continue; 1503 } 1504 if (eLine) 1505 { 1506 ch_a = str[0]; 1507 if (!fra.good()) 1508 { 1509 error = true; 1510 break; 1511 } 1512 fra >> ch_b; 1513 if (this->G_N) 1514 { 1515 if (!fra.good()) 1516 { 1517 error = true; 1518 break; 1519 } 1520 fra >> elen; 1521 } 1522 else 1523 { 1524 elen = 1; 1525 } 1526 //std::cout << ch_a << ' ' << ch_b << ' ' << elen << std::endl; 1527 ia = 0; 1528 while (ia < this->G_Vnum) 1529 { 1530 if (this->G_vList[ia]->data() == ch_a) 1531 { 1532 break; 1533 } 1534 ia++; 1535 } 1536 ib = 0; 1537 while (ib < this->G_Vnum) 1538 { 1539 if (this->G_vList[ib]->data() == ch_b) 1540 { 1541 break; 1542 } 1543 ib++; 1544 } 1545 if (ia >= G_Vnum || ib >= G_Vnum) 1546 { 1547 error = true; 1548 break; 1549 } 1550 //std::cout << eID << std::endl; 1551 pe = new eNode(eID, this->G_vList[ia], this->G_vList[ib], elen); 1552 eID += 1; 1553 if (pe != NULL) 1554 { 1555 this->G_adjMat[ia][ib] = pe; 1556 this->G_eList.push_back(pe); 1557 } 1558 else 1559 { 1560 error = true; 1561 break; 1562 } 1563 } 1564 str[0] = '\0'; 1565 } 1566 fra.close(); 1567 1568 if (error) 1569 { 1570 this->G_error = true; 1571 return -4; 1572 } 1573 1574 this->G_Enum = eID; 1575 if (this->G_U) 1576 { 1577 this->G_Enum /= 2; 1578 } 1579 1580 if (this->init_list() != 0) 1581 { 1582 this->G_error = true; 1583 return -5; 1584 } 1585 1586 this->G_empty = false; 1587 1588 return 0; 1589 } 1590 1591 int graph::delete_G(void) 1592 { 1593 int i; 1594 int j; 1595 1596 i = 0; 1597 while (i < MAX_V_NUM) 1598 { 1599 if (this->G_vList[i] != NULL) 1600 { 1601 delete this->G_vList[i]; 1602 this->G_vList[i] = NULL; 1603 } 1604 i++; 1605 } 1606 1607 while (!this->G_eList.empty()) 1608 { 1609 delete this->G_eList.front(); 1610 this->G_eList.pop_front(); 1611 } 1612 1613 while (!this->G_adjList.empty()) 1614 { 1615 delete this->G_adjList.front(); 1616 this->G_adjList.pop_front(); 1617 } 1618 1619 while (!this->G_i_adjList.empty()) 1620 { 1621 delete this->G_i_adjList.front(); 1622 this->G_i_adjList.pop_front(); 1623 } 1624 1625 i = 0; 1626 while (i < MAX_V_NUM) 1627 { 1628 j = 0; 1629 while (j < MAX_V_NUM) 1630 { 1631 this->G_adjMat[i][j] = NULL; 1632 j++; 1633 } 1634 i++; 1635 } 1636 1637 this->G_empty = true; 1638 1639 return 0; 1640 } 1641 1642 graph::~graph() 1643 { 1644 this->delete_G(); 1645 } 1646 1647 #undef MAX_V_NUM 1648 1649 #endif
測試數據與數據文件對照圖能夠在這裏下載:https://github.com/25thengineer/Data-structure-experiments-of-Hefei-University-of-Technology/tree/master/Exp9_Graph/grpData。