數據結構實驗9:圖的相關操做

實驗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

 

//頂點數據列表,對應的編號爲1234,...

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:

 

 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
View Code

 

  源文件 vNode.h:

 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
View Code

  頭文件 pch.h:

 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
View Code

  源文件 pch.cpp:

1 #include "pch.h"
2 
3 #ifndef PCH_CPP 4 #define PCH_CPP
5 
6 
7 
8 #endi
View Code

  頭文件 eNode.h:

 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
View Code

  源文件 eNode.cpp:

 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
View Code

  頭文件 adjListNode.h:

 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
View Code

  源文件 adjListNode.cpp:

 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
View Code

  頭文件 graph.h:

 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
View Code

  源文件 graph.cpp:

 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
View Code

  測試數據與數據文件對照圖能夠在這裏下載:https://github.com/25thengineer/Data-structure-experiments-of-Hefei-University-of-Technology/tree/master/Exp9_Graph/grpData

相關文章
相關標籤/搜索