圖的深度優先遍歷[非堆疊、堆疊實現]
/*
標題:<<系統設計師>>應試程式設計例項-[圖程式設計]
作者:成曉旭
時間:2002年09月06日(16:30:00-17:16:00)
完成圖的建立函式、順序遍歷函式
時間:2002年09月08日(21:30:00-22:35:00)
完成圖的深度優先遍歷函式[非堆疊、堆疊實現]
*/
#include "stdio.h"
#include "stdlib.h"
//如:FROMHEAD = 1,則用頭插法;否則:則用尾插法
#define FROMHEAD 1
/*
如:HASHEAD 被定義,則各頂點的鄰接點鏈中<帶起始頂點>;
否則:各頂點的鄰接點鏈中<不帶起始頂點>;
*/
#define NODE_NUM 5
#ifdef HASHEAD
//<帶起始頂點>
int GraphNode[NODE_NUM][3] = {{1,'A',4},{2,'B',4},{3,'C',5},{4,'D',5},{5,'E',3}};
int ConnectTable[] = {0,1,2,3,1,0,2,3,2,0,1,3,4,3,0,1,2,4,4,2,3};
#else
//<不帶起始頂點>
int GraphNode[NODE_NUM][3] = {{1,'A',3},{2,'B',3},{3,'C',4},{4,'D',4},{5,'E',2}};
int ConnectTable[] = {1,2,3,0,2,3,0,1,3,4,0,1,2,4,2,3};
#endif
//鄰接表中圖各頂點結構型別定義
#define gVertexNode struct gVertexNode
gVertexNode
{
int order; //頂點在圖中的序號
int data; //頂點的資料域
gVertexNode *link; //指向頂點的下一個鄰接頂點節點的指標
};
//鄰接表中圖各頂點的遍歷頭節點結構型別定義
#define gHeadNode struct gHeadNode
gHeadNode
{
int vcount; //鄰接連結串列的節點數目[即當前頂點的鄰接頂點個數]
//int order; //頂點在圖中的序號
int data; //頂點的資料域
gVertexNode *firstnode; //指向鄰接表的首頂點節點的指標
};
/*
建立以鄰接表方式儲存的圖
引數描述:
gHeadNode HeadNode 圖的鄰接儲存的頭節點陣列
int max:圖的頂點個數
int fromhead:插入鄰接佔點的方式
fromhead=1 頭插入方式
fromhead=0 尾插入方式
*/
void CreateGraph(gHeadNode HeadNode[],int max,int fromhead)
{
gVertexNode *p,*tail; //當前頂點節點及鄰接表當前節點的鄰接連結串列的尾節點
int i,j,k; //i,j為迴圈計數器,k為當前頂點的鄰接頂點數目
for(i=0;i<max;i++)
{
HeadNode[i].vcount = GraphNode[i][2];
HeadNode[i].data = GraphNode[i][1];
HeadNode[i].firstnode = NULL;
//printf(" 頂點[%c]有[%d]個鄰接點! ",HeadNode[i].data,HeadNode[i].vcount);
}
for(i=0,k=0;i<max;i++)
{
for(j=0;j<HeadNode[i].vcount;j++)
{
//建立圖的頂點節點
p = (gVertexNode *)malloc(sizeof(gVertexNode));
if(p==NULL)
{
exit(1);
}
else
{
//圖的新頂點賦值
p->order = GraphNode[ConnectTable[k+j]][0];
p->data = GraphNode[ConnectTable[k+j]][1];
p->link = NULL;
if(fromhead)
{//新節點放在最前面<緊接頭節點的後面>頭插法
p->link = HeadNode[i].firstnode;
HeadNode[i].firstnode = p;
}
else
{//新節點放在最後面<緊接最後一個表節點的後面>尾插法
if(HeadNode[i].firstnode == NULL)
{//插入第一個節點
HeadNode[i].firstnode = p;
tail = p;
}
else
{//插入非第一個節點[直接接到最後一個節點之後]
tail->link = p;
tail = p;
}
}
}
}
//移動關聯表計數位置“指標”
k = k + HeadNode[i].vcount;
}
}
/*
順序訪問圖中的各個節點[以建立的鄰接表的頭節點陣列前後順序]
引數描述:
gHeadNode HeadNode 圖的鄰接儲存的頭節點陣列
int max:圖的頂點個數
*/
void Sequence_Journey(gHeadNode HeadNode[],int max)
{
gVertexNode *p;
int i;
printf("以建立的鄰接表的頭節點陣列前後順序訪問的圖: ");
for(i=0;i<max;i++)
{
p = HeadNode[i].firstnode;
//printf(" 頂點[%c]的[%d]個鄰接點: ",HeadNode[i].data,HeadNode[i].vcount);
while(p != NULL)
{
printf("頂點[%d][%c] ",p->order,p->data);
p = p->link;
}
printf(" ");
}
}
//圖的[深度優先遍歷]演算法<非堆疊實現演算法>
void nsDeepthFirst_Journey(gHeadNode HeadNode[],int max)
{
gVertexNode *p; //頂點
int visited[NODE_NUM]; //0:未訪問 1:已訪問
int i;
printf("圖的[深度優先遍歷]結果<非堆疊實現>: ");
for(i=0;i<max;i++) //設定所有的頂點未訪問標誌
visited[i] = 0;
for(i=0;i<max;i++)
{
p = HeadNode[i].firstnode; //指向當前訪問頂點
//printf("頂點[%d][%c] ",p->order,p->data);
while(p != NULL) //如果頂點有鄰接頂點
{
if(visited[p->order] == 0)
{//當前頂點的鄰接頂點還未訪問
printf("頂點[%d][%c] ",p->order,p->data);
visited[p->order] = 1;
}
p = p->link; //移向下一個頂點
}
}
}
//圖的[深度優先遍歷]演算法<堆疊實現演算法>
void DeepthFirst_Journey(gHeadNode HeadNode[],int max)
{
gVertexNode *p; //頂點
gVertexNode *vstack[NODE_NUM+1]; //頂點堆疊
int visited[NODE_NUM+1]; //0:未訪問 1:已訪問
int i,top; //迴圈計數器和堆疊指標
printf("圖的[深度優先遍歷]結果<堆疊實現>: ");
for(i=0;i<=max;i++) //設定所有的頂點未訪問標誌
visited[i] = 0;
for(i=0;i<max;i++)
{
top = 1;
vstack[top] = HeadNode[i].firstnode;//將本次訪問的起始節點進棧,以便將來正確返回
while(top != 0) //堆疊不為空
{
p = vstack[top]; //取堆疊中的棧頂元素
while((p != NULL) && (visited[p->order] == 1)) //還有鄰接頂點,且已被訪問
p = p->link;
if(p == NULL) //當前頂點沒有鄰接頂點,或有,但都已經被訪問過
top--; //完成退棧
else
{//否則,則訪問之
printf("頂點[%d][%c] ",p->order,p->data);
visited[p->order] = 1;
vstack[++top] = p; //訪問頂點進棧
}
}
}
}
int main(int argc, char* argv[])
{
gHeadNode HeadNodeArray[NODE_NUM];
int InsertMode = -1;
while(InsertMode != 0 && InsertMode != 1)
{
printf("請輸入頂點的插入方式[0尾插入法:/1:頭插入法]");
scanf("%d",&InsertMode);
}
CreateGraph(HeadNodeArray,NODE_NUM,InsertMode);
Sequence_Journey(HeadNodeArray,NODE_NUM);
//nsDeepthFirst_Journey(HeadNodeArray,NODE_NUM);
DeepthFirst_Journey(HeadNodeArray,NODE_NUM);
printf(" 應用程式執行結束! ");
return 0;
}
標題:<<系統設計師>>應試程式設計例項-[圖程式設計]
作者:成曉旭
時間:2002年09月06日(16:30:00-17:16:00)
完成圖的建立函式、順序遍歷函式
時間:2002年09月08日(21:30:00-22:35:00)
完成圖的深度優先遍歷函式[非堆疊、堆疊實現]
*/
#include "stdio.h"
#include "stdlib.h"
//如:FROMHEAD = 1,則用頭插法;否則:則用尾插法
#define FROMHEAD 1
/*
如:HASHEAD 被定義,則各頂點的鄰接點鏈中<帶起始頂點>;
否則:各頂點的鄰接點鏈中<不帶起始頂點>;
*/
#define NODE_NUM 5
#ifdef HASHEAD
//<帶起始頂點>
int GraphNode[NODE_NUM][3] = {{1,'A',4},{2,'B',4},{3,'C',5},{4,'D',5},{5,'E',3}};
int ConnectTable[] = {0,1,2,3,1,0,2,3,2,0,1,3,4,3,0,1,2,4,4,2,3};
#else
//<不帶起始頂點>
int GraphNode[NODE_NUM][3] = {{1,'A',3},{2,'B',3},{3,'C',4},{4,'D',4},{5,'E',2}};
int ConnectTable[] = {1,2,3,0,2,3,0,1,3,4,0,1,2,4,2,3};
#endif
//鄰接表中圖各頂點結構型別定義
#define gVertexNode struct gVertexNode
gVertexNode
{
int order; //頂點在圖中的序號
int data; //頂點的資料域
gVertexNode *link; //指向頂點的下一個鄰接頂點節點的指標
};
//鄰接表中圖各頂點的遍歷頭節點結構型別定義
#define gHeadNode struct gHeadNode
gHeadNode
{
int vcount; //鄰接連結串列的節點數目[即當前頂點的鄰接頂點個數]
//int order; //頂點在圖中的序號
int data; //頂點的資料域
gVertexNode *firstnode; //指向鄰接表的首頂點節點的指標
};
/*
建立以鄰接表方式儲存的圖
引數描述:
gHeadNode HeadNode 圖的鄰接儲存的頭節點陣列
int max:圖的頂點個數
int fromhead:插入鄰接佔點的方式
fromhead=1 頭插入方式
fromhead=0 尾插入方式
*/
void CreateGraph(gHeadNode HeadNode[],int max,int fromhead)
{
gVertexNode *p,*tail; //當前頂點節點及鄰接表當前節點的鄰接連結串列的尾節點
int i,j,k; //i,j為迴圈計數器,k為當前頂點的鄰接頂點數目
for(i=0;i<max;i++)
{
HeadNode[i].vcount = GraphNode[i][2];
HeadNode[i].data = GraphNode[i][1];
HeadNode[i].firstnode = NULL;
//printf(" 頂點[%c]有[%d]個鄰接點! ",HeadNode[i].data,HeadNode[i].vcount);
}
for(i=0,k=0;i<max;i++)
{
for(j=0;j<HeadNode[i].vcount;j++)
{
//建立圖的頂點節點
p = (gVertexNode *)malloc(sizeof(gVertexNode));
if(p==NULL)
{
exit(1);
}
else
{
//圖的新頂點賦值
p->order = GraphNode[ConnectTable[k+j]][0];
p->data = GraphNode[ConnectTable[k+j]][1];
p->link = NULL;
if(fromhead)
{//新節點放在最前面<緊接頭節點的後面>頭插法
p->link = HeadNode[i].firstnode;
HeadNode[i].firstnode = p;
}
else
{//新節點放在最後面<緊接最後一個表節點的後面>尾插法
if(HeadNode[i].firstnode == NULL)
{//插入第一個節點
HeadNode[i].firstnode = p;
tail = p;
}
else
{//插入非第一個節點[直接接到最後一個節點之後]
tail->link = p;
tail = p;
}
}
}
}
//移動關聯表計數位置“指標”
k = k + HeadNode[i].vcount;
}
}
/*
順序訪問圖中的各個節點[以建立的鄰接表的頭節點陣列前後順序]
引數描述:
gHeadNode HeadNode 圖的鄰接儲存的頭節點陣列
int max:圖的頂點個數
*/
void Sequence_Journey(gHeadNode HeadNode[],int max)
{
gVertexNode *p;
int i;
printf("以建立的鄰接表的頭節點陣列前後順序訪問的圖: ");
for(i=0;i<max;i++)
{
p = HeadNode[i].firstnode;
//printf(" 頂點[%c]的[%d]個鄰接點: ",HeadNode[i].data,HeadNode[i].vcount);
while(p != NULL)
{
printf("頂點[%d][%c] ",p->order,p->data);
p = p->link;
}
printf(" ");
}
}
//圖的[深度優先遍歷]演算法<非堆疊實現演算法>
void nsDeepthFirst_Journey(gHeadNode HeadNode[],int max)
{
gVertexNode *p; //頂點
int visited[NODE_NUM]; //0:未訪問 1:已訪問
int i;
printf("圖的[深度優先遍歷]結果<非堆疊實現>: ");
for(i=0;i<max;i++) //設定所有的頂點未訪問標誌
visited[i] = 0;
for(i=0;i<max;i++)
{
p = HeadNode[i].firstnode; //指向當前訪問頂點
//printf("頂點[%d][%c] ",p->order,p->data);
while(p != NULL) //如果頂點有鄰接頂點
{
if(visited[p->order] == 0)
{//當前頂點的鄰接頂點還未訪問
printf("頂點[%d][%c] ",p->order,p->data);
visited[p->order] = 1;
}
p = p->link; //移向下一個頂點
}
}
}
//圖的[深度優先遍歷]演算法<堆疊實現演算法>
void DeepthFirst_Journey(gHeadNode HeadNode[],int max)
{
gVertexNode *p; //頂點
gVertexNode *vstack[NODE_NUM+1]; //頂點堆疊
int visited[NODE_NUM+1]; //0:未訪問 1:已訪問
int i,top; //迴圈計數器和堆疊指標
printf("圖的[深度優先遍歷]結果<堆疊實現>: ");
for(i=0;i<=max;i++) //設定所有的頂點未訪問標誌
visited[i] = 0;
for(i=0;i<max;i++)
{
top = 1;
vstack[top] = HeadNode[i].firstnode;//將本次訪問的起始節點進棧,以便將來正確返回
while(top != 0) //堆疊不為空
{
p = vstack[top]; //取堆疊中的棧頂元素
while((p != NULL) && (visited[p->order] == 1)) //還有鄰接頂點,且已被訪問
p = p->link;
if(p == NULL) //當前頂點沒有鄰接頂點,或有,但都已經被訪問過
top--; //完成退棧
else
{//否則,則訪問之
printf("頂點[%d][%c] ",p->order,p->data);
visited[p->order] = 1;
vstack[++top] = p; //訪問頂點進棧
}
}
}
}
int main(int argc, char* argv[])
{
gHeadNode HeadNodeArray[NODE_NUM];
int InsertMode = -1;
while(InsertMode != 0 && InsertMode != 1)
{
printf("請輸入頂點的插入方式[0尾插入法:/1:頭插入法]");
scanf("%d",&InsertMode);
}
CreateGraph(HeadNodeArray,NODE_NUM,InsertMode);
Sequence_Journey(HeadNodeArray,NODE_NUM);
//nsDeepthFirst_Journey(HeadNodeArray,NODE_NUM);
DeepthFirst_Journey(HeadNodeArray,NODE_NUM);
printf(" 應用程式執行結束! ");
return 0;
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=935905
相關文章
- 圖的深度優先遍歷(堆疊實現和非堆疊實現)
- 堆疊圖
- JS 堆疊JS
- java堆疊Java
- 平衡堆疊
- js實現深度優先遍歷和廣度優先遍歷JS
- 【matplotlib 實戰】--堆疊面積圖
- 堆疊的工作原理
- 堆疊的實現(1)--靜態陣列陣列
- Python實現堆疊與佇列Python佇列
- 深度優先遍歷,廣度優先遍歷實現物件的深拷貝物件
- echarts 堆疊面積階梯圖Echarts
- Thrift的網路堆疊
- C#中堆和堆疊的區別C#
- 記憶體堆疊記憶體
- C#堆疊(Stack)C#
- Python實現堆疊和佇列詳解Python佇列
- [golang]如何看懂呼叫堆疊Golang
- 華為裝置堆疊原理
- C++堆疊詳解C++
- 泛型鏈式堆疊泛型
- 第六講 堆疊操作
- 益智補劑:Stamets堆疊
- Java堆疊的深度分析及記憶體管理技巧Java記憶體
- Photopile JS – 幫助你實現精緻的照片堆疊效果JS
- Java堆疊的區別有哪些Java
- 「前端」History API與瀏覽器歷史堆疊管理前端API瀏覽器
- pretty-printers:更優雅的看GDB堆疊資訊
- junkman 遠端堆疊監控
- 什麼是網路堆疊?
- Java 堆疊記憶體分配Java記憶體
- iOS crash 日誌堆疊解析iOS
- (js佇列,堆疊) (FIFO,LIFO)JS佇列
- z-index堆疊規則Index
- StackOverflowError堆疊溢位錯誤Error
- 如何優雅地檢視 JS 錯誤堆疊?JS
- 利用Decorator和SourceMap優化JavaScript錯誤堆疊優化JavaScript
- 二叉樹的深度優先遍歷和廣度優先遍歷二叉樹