數(shù)據(jù)結(jié)構(gòu)課程設計-拓撲排序_第1頁
已閱讀1頁,還剩23頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、<p><b>  課程設計說明書</b></p><p>  課 程 名 稱: 數(shù)據(jù)結(jié)構(gòu) </p><p>  課 程 代 碼: </p><p>  題 目: 拓撲排序 </p>

2、<p>  年級/專業(yè)/班:10級計算機科學與技術(shù)軟件工程二班</p><p><b>  目 錄</b></p><p><b>  摘 要2</b></p><p><b>  一、引 言3</b></p><p>  二、設計目的與任務3<

3、;/p><p>  1、課程設計目的3</p><p>  2、課程設計的任務3</p><p><b>  三、設計方案3</b></p><p><b>  1、需求分析3</b></p><p><b>  2、概要設計4</b></p

4、><p><b>  3、詳細設計5</b></p><p>  四、調(diào)試分析與體會26</p><p><b>  五、運行結(jié)果27</b></p><p><b>  六、結(jié) 論27</b></p><p><b>  七、致 謝

5、28</b></p><p><b>  八、參考文獻28</b></p><p><b>  摘 要</b></p><p>  對一個有向無環(huán)圖(Directed Acyclic Graph簡稱DAG)G進行拓撲排序(Topological Sort),是將G中所有頂點排成一個線性序列,使得對圖中任意一

6、對頂點u和v,若<u,v>∈E(G),則u在線性序列中出現(xiàn)在v之前。通常將這樣的線性序列稱為滿足拓撲次序(Topolgical Order)的序列,簡稱拓撲序列。</p><p>  關(guān)鍵詞:拓撲;數(shù)據(jù)結(jié)構(gòu);C;C++;</p><p><b>  Abstract </b></p><p>  For a directed acyclic g

7、raph ( Directed Acyclic Graph DAG) G topological sort ( Topological Sort ), G is all vertices into a linear sequence of arbitrary graph, makes a pair of vertices u and V, if < u, V > E ( G ), u in linear occur in t

8、he sequence before v. Usually such linear sequences called meet the topological order ( Topolgical Order ) sequences, referred to as the topological sequence.</p><p>  Keywords: Topology; data structure; C;

9、 C + +;</p><p>  《數(shù)據(jù)結(jié)構(gòu)》課程設計</p><p><b>  ----拓撲排序</b></p><p><b>  一、引 言</b></p><p>  數(shù)據(jù)結(jié)構(gòu)是計算機程序設計的重要理論技術(shù)基礎(chǔ),它不僅是計算機學科的核心課程,而且已成為其他理工專業(yè)的熱門選修課。<

10、/p><p>  采用鄰接表存儲結(jié)構(gòu)實現(xiàn)有向圖;有向圖需通過頂點數(shù)、弧數(shù)、頂點以及弧等信息建立。</p><p>  用鄰接表構(gòu)造圖 然后進行拓撲排序,輸出拓撲排序序列。</p><p><b>  二、設計目的與任務</b></p><p><b>  1、課程設計目的 </b></p>

11、<p>  1、選擇合適的存儲結(jié)構(gòu),建立有向無環(huán)圖,并輸出該圖;</p><p>  2、實現(xiàn)拓撲排序算法;</p><p>  3、運用拓撲排序?qū)崿F(xiàn)對教學計劃安排的檢驗。</p><p><b>  2、課程設計的任務</b></p><p>  在AOV網(wǎng)中為了更好地完成工程,必須滿足活動之間先后關(guān)系,需

12、要將各活動排一個先后次序即為拓撲排序。拓撲排序可以應用于教學計劃的安排,根據(jù)課程之間的依賴關(guān)系,制定課程安排計劃。按照用戶輸入的課程數(shù),課程間的先后關(guān)系數(shù)目以及課程間兩兩間的先后關(guān)系,程序執(zhí)行后會給出符合拓撲排序的課程安排計劃。</p><p><b>  三、設計方案</b></p><p><b>  1、需求分析</b></p>

13、<p><b>  1) 問題描述</b></p><p>  本次課程設計題目是:用鄰接表構(gòu)造圖 然后進行拓撲排序,輸出拓撲排序序列</p><p>  拓撲排序的基本思想為:</p><p>  1).從有向圖中選一個無前驅(qū)的頂點輸出; </p><p>  2).將此頂點和以它為起點的弧刪除;

14、 </p><p>  3). 重復1),2)直到不存在無前驅(qū)的頂點; </p><p>  4). 若此時輸出的頂點數(shù)小于有向圖中的頂點數(shù),則說明有向圖中存在回路,否則輸出的頂點的順序即為一個拓撲序列。 </p><p>  2) 基于鄰接表的存儲結(jié)構(gòu)</p><p>  入度為零的頂點即為沒有前驅(qū)的頂點, 我們可

15、以附設一個存放各頂點入度的數(shù)組indegree[ ],于是有</p><p>  1)找G中無前驅(qū)的頂點——查找indegree[i]為零的頂點vi;</p><p>  2)刪除以i為起點的所有弧——對鏈在頂點i后面的所有鄰接頂點k,將對應的indegree[k] 減1。 </p><p>  為了避免重復檢測入度為零的頂點,可以再設置一個輔助棧,若某一頂點的入度

16、減為0,則將它入棧。每當輸出某一入度為0的頂點時,便將它從棧中刪</p><p><b>  3) 基本要求</b></p><p>  1) 首先是輸入要排序的頂點數(shù)和弧數(shù),都為整型,中間用分隔符隔開;再輸入各頂點的值,為正型,中間用分隔符隔開;然后輸入各條弧的兩個頂點值,先輸入弧頭,再輸入弧尾,中間用分隔符隔開,輸入的值只能是開始輸入的頂點值否則系統(tǒng)會提示輸入的值

17、的頂點值不正確,請重新輸入,只要繼續(xù)輸入正確的值就行。</p><p><b>  2) 輸出的形式;</b></p><p>  首先輸出建立的鄰接表,然后是最終各頂點的出度數(shù),再是拓撲排序的序列,并且每輸出一個頂點,就會輸出一次各頂點的入度數(shù)。</p><p>  3) 程序所能達到的功能;</p><p>  因為

18、該程序是求拓撲排序,所以算法的功能就是要輸出拓撲排序的序列,在一個有向圖中,若用頂點表示活動,有向邊就表示活動間先后順序,那么輸出的拓撲序列就表示各頂點間的關(guān)系為反映出各點的存儲結(jié)構(gòu),以鄰接表存儲并輸出各頂點的入度。</p><p><b>  2、概要設計</b></p><p>  抽象數(shù)據(jù)類型(ADT)如下:</p><p>  ADT

19、ToplogicalSort</p><p>  { 數(shù)據(jù)對象V:V是且有相同特性的數(shù)據(jù)元素的集合,稱為頂點集</p><p>  數(shù)據(jù)關(guān)系:R={VR}</p><p>  VR={<v,w>|v,w∈v且p(v,w),<v,w>表示從v到w的弧,</p><p>  謂詞p(v,w)定義了<v,w>的

20、意義或信息}</p><p><b>  基本操作:</b></p><p>  LocateVex(ALGraph G,VertexType u)</p><p>  初始條件: 圖G存在,u和G中頂點有相同特征 </p><p>  操作結(jié)果: 若G中存在頂點u,則返回該頂點在圖中位置;否則返回-1</p>

21、;<p>  NextAdjVex(ALGraph G,VertexType v,VertexType w)</p><p>  初始條件: 圖G存在,v是G中某個頂點,w是v的鄰接頂點 </p><p>  操作結(jié)果: 返回v的(相對于w的)下一個鄰接頂點的序號。 </p><p>  VertexType* GetVex(ALGraph G

22、,int v)</p><p>  初始條件: 圖G存在,v是G中某個頂點的序號。</p><p>  操作結(jié)果: 返回v的值 */</p><p>  NextAdjVex(ALGraph G,VertexType v,VertexType w)</p><p>  初始條件: 圖G存在,v是G中某個頂點,w是v的鄰接頂點 </p&g

23、t;<p>  操作結(jié)果: 返回v的(相對于w的)下一個鄰接頂點的序號。 </p><p>  若w是v的最后一個鄰接點,則返回-1 </p><p>  VertexType* GetVex(ALGraph G,int v)</p><p>  初始條件: 圖G存在,v是G中某個頂點的序號。</p><p>  操作結(jié)果: 返

24、回v的值 </p><p><b>  }</b></p><p><b>  存儲結(jié)構(gòu)</b></p><p>  typedef struct SqStack</p><p>  {SElemType *base; /* 在棧構(gòu)造之前和銷毀之后,base的值為NULL */</p>

25、<p>  SElemType *top; /* 棧頂指針 */</p><p>  int stacksize; /* 當前已分配的存儲空間,以元素為單位 */</p><p>  }SqStack; /* 順序棧 */</p><p>  typedef struct ArcNode</p><p><b>  {

26、</b></p><p>  int adjvex; /* 該弧所指向的頂點的位置 */</p><p>  struct ArcNode *nextarc; /* 指向下一條弧的指針 */</p><p>  InfoType *info; /* 網(wǎng)的權(quán)值指針) */</p><p>  }ArcNode; /* 表結(jié)點 */&

27、lt;/p><p>  typedef struct</p><p><b>  {</b></p><p>  VertexType data; /* 頂點信息 */</p><p>  ArcNode *firstarc; /* 第一個表結(jié)點的地址,指向第一條依附該頂點的弧的指針 */</p><p&

28、gt;  }VNode,AdjList[MAX_VERTEX_NUM]; /* 頭結(jié)點 */</p><p>  typedef struct</p><p><b>  {</b></p><p>  AdjList vertices;</p><p>  int vexnum,arcnum; /* 圖的當前頂點數(shù)和弧

29、數(shù) */</p><p>  int kind; /* 圖的種類標志 */</p><p><b>  }ALGraph;</b></p><p><b>  流程圖</b></p><p><b>  詳細設計</b></p><p>  #inclu

30、de<stdio.h> </p><p>  #include<math.h> </p><p>  #include<string.h></p><p>  #include<stdlib.h></p><p>  #define FALSE 0</p><p>  #

31、define OK 1</p><p>  #define ERROR 0</p><p>  #define INFEASIBLE -1</p><p>  typedef int Status; /* Status是函數(shù)的類型,其值是函數(shù)結(jié)果狀態(tài)代碼,如OK等 */</p><p>  typedef int Boolean; /* Bo

32、olean是布爾類型,其值是TRUE或FALSE */</p><p>  #define MAX_NAME 5 /* 頂點字符串的最大長度 */</p><p>  typedef int InfoType;</p><p>  typedef char VertexType[MAX_NAME]; /* 字符串類型 */</p><p> 

33、 #define MAX_VERTEX_NUM 20</p><p>  typedef enum{DG,DN,AG,AN}GraphKind; /* {有向圖,有向網(wǎng),無向圖,無向網(wǎng)} */</p><p>  typedef struct ArcNode</p><p><b>  {</b></p><p>  i

34、nt adjvex; /* 該弧所指向的頂點的位置 */</p><p>  struct ArcNode *nextarc; /* 指向下一條弧的指針 */</p><p>  InfoType *info; /* 網(wǎng)的權(quán)值指針) */</p><p>  }ArcNode; /* 表結(jié)點 */</p><p>  typedef stru

35、ct</p><p><b>  {</b></p><p>  VertexType data; /* 頂點信息 */</p><p>  ArcNode *firstarc; /* 第一個表結(jié)點的地址,指向第一條依附該頂點的弧的指針 */</p><p>  }VNode,AdjList[MAX_VERTEX_NUM

36、]; /* 頭結(jié)點 */</p><p>  typedef struct</p><p><b>  {</b></p><p>  AdjList vertices;</p><p>  int vexnum,arcnum; /* 圖的當前頂點數(shù)和弧數(shù) */</p><p>  int kin

37、d; /* 圖的種類標志 */</p><p><b>  }ALGraph;</b></p><p>  int LocateVex(ALGraph G,VertexType u)</p><p>  { /* 初始條件: 圖G存在,u和G中頂點有相同特征 */</p><p>  /* 操作結(jié)果: 若G中存在頂點u,

38、則返回該頂點在圖中位置;否則返回-1 */</p><p><b>  int i;</b></p><p>  for(i = 0;i < G.vexnum; ++i)</p><p>  if(strcmp(u,G.vertices[i].data) == 0)</p><p><b>  retur

39、n i;</b></p><p>  return -1;</p><p><b>  }</b></p><p>  Status CreateGraph(ALGraph *G)</p><p>  { /* 采用鄰接表存儲結(jié)構(gòu),構(gòu)造沒有相關(guān)信息的圖G(用一個函數(shù)構(gòu)造4種圖) */</p>&

40、lt;p>  int i,j,k;</p><p>  int w; /* 權(quán)值 */</p><p>  VertexType va,vb;</p><p>  ArcNode *p;</p><p>  printf("請輸入圖的類型(有向圖:0,有向網(wǎng):1,無向圖:2,無向網(wǎng):3): ");</p>

41、<p>  scanf("%d",&(*G).kind);</p><p>  printf("請輸入圖的頂點數(shù),邊數(shù): ");</p><p>  scanf("%d,%d",&(*G).vexnum,&(*G).arcnum);</p><p>  printf(&

42、quot;請輸入%d個頂點的值(<%d個字符):\n",(*G).vexnum,MAX_NAME);</p><p>  for(i = 0;i < (*G).vexnum; ++i) /* 構(gòu)造頂點向量 */</p><p><b>  {</b></p><p>  scanf("%s",(*G).

43、vertices[i].data);</p><p>  (*G).vertices[i].firstarc = NULL;</p><p><b>  }</b></p><p>  if((*G).kind == 1 || (*G).kind == 3) /* 網(wǎng) */</p><p>  printf("

44、請順序輸入每條弧(邊)的權(quán)值、弧尾和弧頭(以空格作為間隔):\n");</p><p>  else /* 圖 */</p><p>  printf("請順序輸入每條弧(邊)的弧尾和弧頭(以空格作為間隔):\n");</p><p>  for(k = 0;k < (*G).arcnum; ++k) /* 構(gòu)造表結(jié)點鏈表 */&

45、lt;/p><p><b>  {</b></p><p>  if((*G).kind == 1 || (*G).kind == 3) /* 網(wǎng) */</p><p>  scanf("%d%s%s",&w,va,vb);</p><p>  else /* 圖 */</p>&l

46、t;p>  scanf("%s%s",va,vb);</p><p>  i = LocateVex(*G,va); /* 弧尾 */</p><p>  j = LocateVex(*G,vb); /* 弧頭 */</p><p>  p = (ArcNode*)malloc(sizeof(ArcNode));</p>&l

47、t;p>  p -> adjvex = j;</p><p>  if((*G).kind == 1 || (*G).kind == 3) /* 網(wǎng) */</p><p><b>  {</b></p><p>  p -> info = (int *)malloc(sizeof(int));</p><p

48、>  *(p -> info) = w;</p><p><b>  }</b></p><p><b>  else</b></p><p>  p -> info = NULL; /* 圖 */</p><p>  p -> nextarc = (*G).vertices

49、[i].firstarc; /* 插在表頭 */</p><p>  (*G).vertices[i].firstarc = p;</p><p>  if((*G).kind >= 2) /* 無向圖或網(wǎng),產(chǎn)生第二個表結(jié)點 */</p><p><b>  {</b></p><p>  p = (ArcNode

50、*)malloc(sizeof(ArcNode));</p><p>  p -> adjvex = i;</p><p>  if((*G).kind == 3) /* 無向網(wǎng) */</p><p><b>  {</b></p><p>  p -> info = (int*)malloc(sizeof(

51、int));</p><p>  *(p -> info) = w;</p><p><b>  }</b></p><p><b>  else</b></p><p>  p -> info = NULL; /* 無向圖 */</p><p>  p ->

52、; nextarc = (*G).vertices[j].firstarc; /* 插在表頭 */</p><p>  (*G).vertices[j].firstarc=p;</p><p><b>  }</b></p><p><b>  }</b></p><p>  return OK;&

53、lt;/p><p><b>  }</b></p><p>  VertexType* GetVex(ALGraph G,int v)</p><p>  { /* 初始條件: 圖G存在,v是G中某個頂點的序號。操作結(jié)果: 返回v的值 */</p><p>  if(v >= G.vexnum || v<0)&l

54、t;/p><p>  exit(ERROR);</p><p>  return &G.vertices[v].data;</p><p><b>  }</b></p><p>  int FirstAdjVex(ALGraph G,VertexType v)</p><p>  { /*

55、初始條件: 圖G存在,v是G中某個頂點 */</p><p>  /* 操作結(jié)果: 返回v的第一個鄰接頂點的序號。若頂點在G中沒有鄰接頂點,則返回-1 */</p><p>  ArcNode *p;</p><p><b>  int v1;</b></p><p>  v1 = LocateVex(G,v); /*

56、v1為頂點v在圖G中的序號 */</p><p>  p = G.vertices[v1].firstarc;</p><p><b>  if(p)</b></p><p>  return p -> adjvex;</p><p><b>  else</b></p><

57、;p>  return -1;</p><p><b>  }</b></p><p>  int NextAdjVex(ALGraph G,VertexType v,VertexType w)</p><p>  { /* 初始條件: 圖G存在,v是G中某個頂點,w是v的鄰接頂點 */</p><p>  /*

58、操作結(jié)果: 返回v的(相對于w的)下一個鄰接頂點的序號。 */</p><p>  /* 若w是v的最后一個鄰接點,則返回-1 */</p><p>  ArcNode *p;</p><p>  int v1,w1;</p><p>  v1 = LocateVex(G,v); /* v1為頂點v在圖G中的序號 */&l

59、t;/p><p>  w1 = LocateVex(G,w); /* w1為頂點w在圖G中的序號 */</p><p>  p = G.vertices[v1].firstarc;</p><p>  while(p && p -> adjvex != w1) /* 指針p不空且所指表結(jié)點不是w */</p><p>  p

60、 = p -> nextarc;</p><p>  if(!p || !p -> nextarc) /* 沒找到w或w是最后一個鄰接點 */</p><p>  return -1;</p><p>  else /* p->adjvex==w */</p><p>  return p -> nextarc -&g

61、t; adjvex; /* 返回v的(相對于w的)下一個鄰接頂點的序號 */</p><p><b>  }</b></p><p>  Boolean visited[MAX_VERTEX_NUM]; /* 訪問標志數(shù)組(全局量) */</p><p>  void(*VisitFunc)(char* v); /* 函數(shù)變量(全局量) */&

62、lt;/p><p>  void DFS(ALGraph G,int v)</p><p>  { /* 從第v個頂點出發(fā)遞歸地深度優(yōu)先遍歷圖G。*/</p><p><b>  int w;</b></p><p>  VertexType v1,w1;</p><p>  strcpy(v1,*G

63、etVex(G,v));</p><p>  visited[v] = TRUE; /* 設置訪問標志為TRUE(已訪問) */</p><p>  VisitFunc(G.vertices[v].data); /* 訪問第v個頂點 */</p><p>  for(w = FirstAdjVex(G,v1); w >= 0; w = NextAdjVex(G

64、,v1,strcpy(w1,*GetVex(G,w))))</p><p>  if(!visited[w])</p><p>  DFS(G,w); /* 對v的尚未訪問的鄰接點w遞歸調(diào)用DFS */</p><p><b>  }</b></p><p>  typedef int QElemType; /* 隊列類

65、型 */</p><p>  typedef struct QNode</p><p><b>  {</b></p><p>  QElemType data;</p><p>  struct QNode *next;</p><p>  }QNode,*QueuePtr;</p>

66、<p>  typedef struct</p><p><b>  {</b></p><p>  QueuePtr front,rear; /* 隊頭、隊尾指針 */</p><p>  }LinkQueue;</p><p>  Status InitQueue(LinkQueue *Q)</p

67、><p>  { /* 構(gòu)造一個空隊列Q */</p><p>  (*Q).front = (*Q).rear = (QueuePtr)malloc(sizeof(QNode));</p><p>  if(!(*Q).front)</p><p>  exit(OVERFLOW);</p><p>  (*Q).fro

68、nt -> next = NULL;</p><p>  return OK;</p><p><b>  }</b></p><p>  Status QueueEmpty(LinkQueue Q)</p><p>  { /* 若Q為空隊列,則返回TRUE,否則返回FALSE */</p><

69、;p>  if(Q.front == Q.rear)</p><p>  return TRUE;</p><p><b>  else</b></p><p>  return FALSE;</p><p><b>  }</b></p><p>  Status E

70、nQueue(LinkQueue *Q,QElemType e)</p><p>  { /* 插入元素e為Q的新的隊尾元素 */</p><p>  QueuePtr p = (QueuePtr)malloc(sizeof(QNode));</p><p>  if(!p) /* 存儲分配失敗 */</p><p>  exit(OVERF

71、LOW);</p><p>  p -> data = e;</p><p>  p -> next = NULL;</p><p>  (*Q).rear -> next = p;</p><p>  (*Q).rear = p;</p><p>  return OK;</p>&l

72、t;p><b>  }</b></p><p>  Status DeQueue(LinkQueue *Q,QElemType *e)</p><p>  { /* 若隊列不空,刪除Q的隊頭元素,用e返回其值,并返回OK,否則返回ERROR */</p><p>  QueuePtr p;</p><p>  if

73、((*Q).front == (*Q).rear)</p><p>  return ERROR;</p><p>  p = (*Q).front -> next;</p><p>  *e = p -> data;</p><p>  (*Q).front -> next = p -> next;</p>

74、;<p>  if((*Q).rear == p)</p><p>  (*Q).rear=(*Q).front;</p><p><b>  free(p);</b></p><p>  return OK;</p><p><b>  }</b></p><p&

75、gt;  void BFSTraverse(ALGraph G,void(*Visit)(char*))</p><p>  {/*按廣度優(yōu)先非遞歸遍歷圖G。使用輔助隊列Q和訪問標志數(shù)組visited。算法7.6 */</p><p>  int v,u,w;</p><p>  VertexType u1,w1;</p><p>  Lin

76、kQueue Q;</p><p>  for(v = 0; v < G.vexnum; ++v)</p><p>  visited[v] = FALSE; /* 置初值 */</p><p>  InitQueue(&Q); /* 置空的輔助隊列Q */</p><p>  for(v = 0;v < G.vexnum

77、; v++) /* 如果是連通圖,只v=0就遍歷全圖 */</p><p>  if(!visited[v]) /* v尚未訪問 */</p><p><b>  {</b></p><p>  visited[v] = TRUE;</p><p>  Visit(G.vertices[v].data);</p&g

78、t;<p>  EnQueue(&Q,v); /* v入隊列 */</p><p>  while(!QueueEmpty(Q)) /* 隊列不空 */</p><p><b>  {</b></p><p>  DeQueue(&Q,&u); /* 隊頭元素出隊并置為u */</p><

79、;p>  strcpy(u1,*GetVex(G,u));</p><p>  for(w=FirstAdjVex(G,u1);w>=0;w= NextAdjVex(G,u1,strcpy(w1,*GetVex(G,w))))</p><p>  if(!visited[w]) /* w為u的尚未訪問的鄰接頂點 */</p><p><b> 

80、 {</b></p><p>  visited[w] = TRUE;</p><p>  Visit(G.vertices[w].data);</p><p>  EnQueue(&Q,w); /* w入隊 */</p><p><b>  }//end if</b></p><

81、p>  }//end while</p><p><b>  }//end if</b></p><p>  printf("\n");</p><p><b>  }</b></p><p>  void Display(ALGraph G)</p><

82、;p>  { /* 輸出圖的鄰接矩陣G */</p><p><b>  int i;</b></p><p>  ArcNode *p;</p><p>  switch(G.kind)</p><p><b>  {</b></p><p>  case DG: p

83、rintf("有向圖\n");</p><p><b>  break;</b></p><p>  case DN: printf("有向網(wǎng)\n");</p><p><b>  break;</b></p><p>  case AG: printf(&q

84、uot;無向圖\n");</p><p><b>  break;</b></p><p>  case AN: printf("無向網(wǎng)\n");</p><p><b>  }</b></p><p>  printf("%d個頂點:\n",G.v

85、exnum);</p><p>  for(i = 0;i < G.vexnum; ++i)</p><p>  printf("%s ",G.vertices[i].data);</p><p>  printf("\n%d條弧(邊):\n",G.arcnum);</p><p>  for(i

86、 = 0;i < G.vexnum; i++)</p><p><b>  {</b></p><p>  p = G.vertices[i].firstarc;</p><p><b>  while(p)</b></p><p><b>  {</b></p&g

87、t;<p>  if(G.kind <= 1) /* 有向 */</p><p><b>  {</b></p><p>  printf("%s→%s ",G.vertices[i].data,G.vertices[p -> adjvex].data);</p><p>  if(G.kind =

88、= DN) /* 網(wǎng) */</p><p>  printf(":%d ",*(p -> info));</p><p><b>  }</b></p><p>  else /* 無向(避免輸出兩次) */</p><p><b>  {</b></p>&

89、lt;p>  if(i < p -> adjvex)</p><p><b>  {</b></p><p>  printf("%s-%s ",G.vertices[i].data,G.vertices[p -> adjvex].data);</p><p>  if(G.kind == AN) /

90、* 網(wǎng) */</p><p>  printf(":%d ",*(p -> info));</p><p><b>  }</b></p><p><b>  }</b></p><p>  p = p -> nextarc;</p><p>

91、<b>  }</b></p><p>  printf("\n");</p><p><b>  }</b></p><p><b>  }</b></p><p>  void FindInDegree(ALGraph G,int indegree[])

92、</p><p>  { /* 求頂點的入度*/</p><p><b>  int i;</b></p><p>  ArcNode *p;</p><p>  for(i = 0;i < G.vexnum; i++)</p><p>  indegree[i] = 0; /* 賦初值 *

93、/</p><p>  for(i = 0;i < G.vexnum; i++)</p><p><b>  {</b></p><p>  p = G.vertices[i].firstarc;</p><p><b>  while(p)</b></p><p>&

94、lt;b>  {</b></p><p>  indegree[p -> adjvex]++;</p><p>  p = p-> nextarc;</p><p><b>  }</b></p><p><b>  }</b></p><p>

95、<b>  }</b></p><p>  typedef int SElemType; /* 棧類型 */</p><p>  #define STACK_INIT_SIZE 10 /* 存儲空間初始分配量 */</p><p>  #define STACKINCREMENT 2 /* 存儲空間分配增量 */</p><

96、p>  typedef struct SqStack</p><p><b>  {</b></p><p>  SElemType *base; /* 在棧構(gòu)造之前和銷毀之后,base的值為NULL */</p><p>  SElemType *top; /* 棧頂指針 */</p><p>  int sta

97、cksize; /* 當前已分配的存儲空間,以元素為單位 */</p><p>  }SqStack; /* 順序棧 */</p><p>  Status InitStack(SqStack *S)</p><p>  { /* 構(gòu)造一個空棧S */</p><p>  (*S).base = (SElemType *)malloc(STA

98、CK_INIT_SIZE*sizeof(SElemType));</p><p>  if(!(*S).base)</p><p>  exit(OVERFLOW); /* 存儲分配失敗 */</p><p>  (*S).top = (*S).base;</p><p>  (*S).stacksize = STACK_INIT_SIZE;

99、</p><p>  return OK;</p><p><b>  }</b></p><p>  Status StackEmpty(SqStack S)</p><p>  { /* 若棧S為空棧,則返回TRUE,否則返回FALSE */</p><p>  if(S.top == S.b

100、ase)</p><p>  return TRUE;</p><p><b>  else</b></p><p>  return FALSE;</p><p><b>  }</b></p><p>  Status Push(SqStack *S,SElemType

101、e)</p><p>  { /* 插入元素e為新的棧頂元素 */</p><p>  if((*S).top - (*S).base >= (*S).stacksize) /* 棧滿,追加存儲空間 */</p><p>  { (*S).base=(SElemType*)realloc((*S).base,((*S).stacksize+</p>

102、;<p>  STACKINCREMENT)*sizeof(SElemType));</p><p>  if(!(*S).base)</p><p>  exit(OVERFLOW); /* 存儲分配失敗 */</p><p>  (*S).top = (*S).base + (*S).stacksize;</p><p> 

103、 (*S).stacksize += STACKINCREMENT;</p><p><b>  }</b></p><p>  *((*S).top)++ = e;</p><p>  return OK;</p><p><b>  }</b></p><p>  Sta

104、tus Pop(SqStack *S,SElemType *e)</p><p>  { /* 若棧不空,則刪除S的棧頂元素,用e返回其值,并返回OK;否則返回ERROR */</p><p>  if((*S).top == (*S).base)</p><p>  return ERROR;</p><p>  *e = *--(*S).

105、top;</p><p>  return OK;</p><p><b>  }</b></p><p>  Status TopologicalSort(ALGraph G)</p><p>  { /* 有向圖G采用鄰接表存儲結(jié)構(gòu)。若G無回路,則輸出G的頂點的一個拓撲序列并返回OK, */</p>&

106、lt;p>  /* 否則返回ERROR。*/</p><p>  int i,k,count,indegree[MAX_VERTEX_NUM];</p><p>  SqStack S;</p><p>  ArcNode *p;</p><p>  FindInDegree(G,indegree); /* 對各頂點求入度indegre

107、e[0..vernum-1] */</p><p>  InitStack(&S); /* 初始化棧 */</p><p>  for(i = 0; i < G.vexnum; ++i) /* 建零入度頂點棧S */</p><p>  if(!indegree[i])</p><p>  Push(&S,i); /*

108、入度為0者進棧 */</p><p>  count = 0; /* 對輸出頂點計數(shù) */</p><p>  while(!StackEmpty(S))</p><p>  { /* 棧不空 */</p><p>  Pop(&S,&i);</p><p>  printf("%s &quo

109、t;,G.vertices[i].data); /* 輸出i號頂點并計數(shù) */</p><p><b>  ++count;</b></p><p>  for(p = G.vertices[i].firstarc; p; p = p -> nextarc)</p><p>  { /* 對i號頂點的每個鄰接點的入度減1 */</p

110、><p>  k = p -> adjvex;</p><p>  if(!(--indegree[k])) /* 若入度減為0,則入棧 */</p><p>  Push(&S,k);</p><p><b>  }</b></p><p><b>  }</b>

111、</p><p>  if(count < G.vexnum)</p><p><b>  {</b></p><p>  printf("此有向圖有回路\n");</p><p>  return ERROR;</p><p><b>  }</b>

112、;</p><p><b>  else</b></p><p><b>  {</b></p><p>  printf("為一個拓撲序列。\n");</p><p>  return OK;</p><p><b>  }</b>

113、</p><p><b>  }</b></p><p>  int main()</p><p><b>  {</b></p><p>  ALGraph f;</p><p>  printf("請選擇有向圖\n");</p><

114、p>  CreateGraph(&f);</p><p>  Display(f);</p><p>  TopologicalSort(f);</p><p>  system("pause");</p><p><b>  return 0;</b></p><p

115、><b>  }</b></p><p><b>  重要程序段1:</b></p><p>  Status CreateGraph(ALGraph *G)</p><p>  { /* 采用鄰接表存儲結(jié)構(gòu),構(gòu)造沒有相關(guān)信息的圖G(用一個函數(shù)構(gòu)造4種圖) */</p><p>  int i

116、,j,k;</p><p>  int w; /* 權(quán)值 */</p><p>  VertexType va,vb;</p><p>  ArcNode *p;</p><p>  printf("請輸入圖的類型(有向圖:0,有向網(wǎng):1,無向圖:2,無向網(wǎng):3): ");</p><p>  sc

117、anf("%d",&(*G).kind);</p><p>  printf("請輸入圖的頂點數(shù),邊數(shù): ");</p><p>  scanf("%d,%d",&(*G).vexnum,&(*G).arcnum);</p><p>  printf("請輸入%d個頂點的值

118、(<%d個字符):\n",(*G).vexnum,MAX_NAME);</p><p>  for(i = 0;i < (*G).vexnum; ++i) /* 構(gòu)造頂點向量 */</p><p><b>  {</b></p><p>  scanf("%s",(*G).vertices[i].dat

119、a);</p><p>  (*G).vertices[i].firstarc = NULL;</p><p><b>  }</b></p><p>  if((*G).kind == 1 || (*G).kind == 3) /* 網(wǎng) */</p><p>  printf("請順序輸入每條弧(邊)的權(quán)值、

120、弧尾和弧頭(以空格作為間隔):\n");</p><p>  else /* 圖 */</p><p>  printf("請順序輸入每條弧(邊)的弧尾和弧頭(以空格作為間隔):\n");</p><p>  for(k = 0;k < (*G).arcnum; ++k) /* 構(gòu)造表結(jié)點鏈表 */</p><

121、p><b>  {</b></p><p>  if((*G).kind == 1 || (*G).kind == 3) /* 網(wǎng) */</p><p>  scanf("%d%s%s",&w,va,vb);</p><p>  else /* 圖 */</p><p>  scanf(

122、"%s%s",va,vb);</p><p>  i = LocateVex(*G,va); /* 弧尾 */</p><p>  j = LocateVex(*G,vb); /* 弧頭 */</p><p>  p = (ArcNode*)malloc(sizeof(ArcNode));</p><p>  p ->

123、; adjvex = j;</p><p>  if((*G).kind == 1 || (*G).kind == 3) /* 網(wǎng) */</p><p><b>  {</b></p><p>  p -> info = (int *)malloc(sizeof(int));</p><p>  *(p ->

124、 info) = w;</p><p><b>  }</b></p><p><b>  else</b></p><p>  p -> info = NULL; /* 圖 */</p><p>  p -> nextarc = (*G).vertices[i].firstarc; /

125、* 插在表頭 */</p><p>  (*G).vertices[i].firstarc = p;</p><p>  if((*G).kind >= 2) /* 無向圖或網(wǎng),產(chǎn)生第二個表結(jié)點 */</p><p><b>  {</b></p><p>  p = (ArcNode*)malloc(sizeof

126、(ArcNode));</p><p>  p -> adjvex = i;</p><p>  if((*G).kind == 3) /* 無向網(wǎng) */</p><p><b>  {</b></p><p>  p -> info = (int*)malloc(sizeof(int));</p>

127、;<p>  *(p -> info) = w;</p><p><b>  }</b></p><p><b>  else</b></p><p>  p -> info = NULL; /* 無向圖 */</p><p>  p -> nextarc = (*G

128、).vertices[j].firstarc; /* 插在表頭 */</p><p>  (*G).vertices[j].firstarc=p;</p><p><b>  }</b></p><p><b>  }</b></p><p>  return OK;</p><

129、p><b>  }</b></p><p><b>  重要程序段2:</b></p><p>  int NextAdjVex(ALGraph G,VertexType v,VertexType w)</p><p><b>  { </b></p><p>  Arc

130、Node *p;</p><p>  int v1,w1;</p><p>  v1 = LocateVex(G,v); /* v1為頂點v在圖G中的序號 */</p><p>  w1 = LocateVex(G,w); /* w1為頂點w在圖G中的序號 */</p><p>  p = G.vertices[v1].firstarc;&l

131、t;/p><p>  while(p && p -> adjvex != w1) /* 指針p不空且所指表結(jié)點不是w */</p><p>  p = p -> nextarc;</p><p>  if(!p || !p -> nextarc) /* 沒找到w或w是最后一個鄰接點 */</p><p>  re

132、turn -1;</p><p>  else /* p->adjvex==w */</p><p>  return p -> nextarc -> adjvex; /* 返回v的(相對于w的)下一個鄰接頂點的序號 */</p><p><b>  }</b></p><p><b>  重

133、要程序段3:</b></p><p>  void DFS(ALGraph G,int v)</p><p>  { /* 從第v個頂點出發(fā)遞歸地深度優(yōu)先遍歷圖G。*/</p><p><b>  int w;</b></p><p>  VertexType v1,w1;</p><p&

134、gt;  strcpy(v1,*GetVex(G,v));</p><p>  visited[v] = TRUE; /* 設置訪問標志為TRUE(已訪問) */</p><p>  VisitFunc(G.vertices[v].data); /* 訪問第v個頂點 */</p><p>  for(w = FirstAdjVex(G,v1); w >= 0;

135、 w = NextAdjVex(G,v1,strcpy(w1,*GetVex(G,w))))</p><p>  if(!visited[w])</p><p>  DFS(G,w); /* 對v的尚未訪問的鄰接點w遞歸調(diào)用DFS */</p><p><b>  }</b></p><p><b>  重要程

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論