數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)---關(guān)于最短路徑問(wèn)題 和 二叉樹(shù)排序問(wèn)題_第1頁(yè)
已閱讀1頁(yè),還剩33頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、<p>  課程設(shè)計(jì)綜合成績(jī)?cè)u(píng)定</p><p>  設(shè)計(jì)題目一: 二 叉 排 序 樹(shù) </p><p>  設(shè)計(jì)題目二: 最 短 路 徑 問(wèn) 題 </p><p>  設(shè)計(jì)題目三: <

2、/p><p><b>  目 錄</b></p><p><b>  1.二叉排序樹(shù)1</b></p><p>  1.1 問(wèn)題描述1</p><p>  1.2 設(shè)計(jì)方案與概要設(shè)計(jì)2</p><p>  1.3 詳細(xì)設(shè)計(jì)4</p><p>

3、;  1.4 程序運(yùn)行說(shuō)明與結(jié)果11</p><p>  2.最短路徑問(wèn)題13</p><p>  2.1 問(wèn)題描述13</p><p>  2.2 設(shè)計(jì)方案與概要設(shè)計(jì)16</p><p>  2.3 詳細(xì)設(shè)計(jì)17</p><p>  2.4 程序運(yùn)行說(shuō)明與結(jié)果27</p><

4、p>  3.總結(jié)與分析32</p><p><b>  1. 二叉排序樹(shù)</b></p><p><b>  1.1 問(wèn)題描述</b></p><p>  知二叉排序樹(shù)的二叉鏈表存儲(chǔ)結(jié)構(gòu)的類(lèi)型定義如下:</p><p>  typedef struct node{ &l

5、t;/p><p>  int data; //用整數(shù)表示一個(gè)結(jié)點(diǎn)的名</p><p>  struct node *LChild,*RChild; //左右指針域</p><p>  }BSTNode,*BSTree; </p><p> ?。?)鍵盤(pán)輸入一個(gè)元素序列創(chuàng)建一棵如圖(1)的二叉排序樹(shù),并輸出該二叉排序樹(shù)的中序遍

6、歷序列;</p><p><b>  圖(1)</b></p><p> ?。?)在圖(1)中所得的二叉排序樹(shù)中插入一個(gè)值為58的結(jié)點(diǎn),輸</p><p>  出它的中序遍歷序列; </p><p>  (3)在題(2)中所得的二叉排序樹(shù)中刪除值為45的結(jié)點(diǎn),輸出它的中序遍歷序列;</p><p&

7、gt;  (4)我們知道教材中P220給出的二叉排序樹(shù)的刪除操作算法中,是用左子樹(shù)中最右下結(jié)點(diǎn)來(lái)替代要被刪除的結(jié)點(diǎn)(即為要被刪除結(jié)點(diǎn)的中序前驅(qū)),也可以用右子樹(shù)中最左下結(jié)點(diǎn)來(lái)替代要被刪除的結(jié)點(diǎn)(即為要被刪除結(jié)點(diǎn)的中序后繼),根據(jù)此思路修改P220算法在寫(xiě)一個(gè)刪除操作,并利用修改后的刪除算法刪除圖(1)中二叉排序樹(shù)的值為45的結(jié)點(diǎn),輸出它的中序遍歷序列;</p><p> ?。?)利用題(2)中所得的二叉排序樹(shù)的所

8、有葉子結(jié)點(diǎn)構(gòu)造一個(gè)帶頭結(jié)點(diǎn)的單鏈表L。要求不能破壞這棵二叉排序樹(shù)。所得的單鏈表L元素遞增,并輸出單鏈表L。</p><p> ?。?)設(shè)計(jì)算法將圖(1)的二叉排序樹(shù)的左右子樹(shù)進(jìn)行交換。最后輸出所得到的二叉樹(shù)的中序遍歷序列。</p><p>  所得二叉排序樹(shù)如圖所示:</p><p><b>  圖(2)</b></p><

9、p> ?。?)用計(jì)算法統(tǒng)計(jì)并輸出圖(1)中所得的二叉排序樹(shù)中只有一個(gè)孩子結(jié)點(diǎn)的結(jié)點(diǎn)個(gè)數(shù)。</p><p> ?。?)由圖(1)的二叉排序樹(shù),用計(jì)算法并編寫(xiě)程序輸出結(jié)點(diǎn)40的所有祖先結(jié)點(diǎn)。</p><p>  1.2 設(shè)計(jì)方案與概要設(shè)計(jì)</p><p>  二叉排序樹(shù)應(yīng)用的存儲(chǔ)結(jié)構(gòu)</p><p>  typedef struct no

10、de{ // 二叉排序樹(shù)的存儲(chǔ)結(jié)構(gòu)</p><p>  int data; </p><p>  struct node *LChild,*RChild; </p><p>  }BSTNode,*BSTree; </p><p>  typedef struct LNode{ //單鏈表的存儲(chǔ)結(jié)構(gòu)

11、</p><p><b>  int data;</b></p><p>  struct LNode *next;</p><p>  }LNode,*LinkList;</p><p>  二叉排序樹(shù)的設(shè)計(jì)用到了單鏈表L。</p><p>  單鏈表L主要用于題(5)的設(shè)計(jì),用來(lái)存儲(chǔ)圖(1)的

12、二叉排序樹(shù)中所有葉子結(jié)點(diǎn),并將其輸出。</p><p><b>  2.方案設(shè)計(jì)</b></p><p>  本方案設(shè)計(jì)主要應(yīng)用二叉樹(shù)的性質(zhì)。創(chuàng)建空二叉排序樹(shù)T,再輸入圖(1)中的元素后向T插入所有元素,在插入時(shí)比根結(jié)點(diǎn)小的放在樹(shù)的左子樹(shù),比根結(jié)點(diǎn)大則放在樹(shù)的右子樹(shù),同時(shí)樹(shù)的左右子樹(shù)也要遵循這個(gè)規(guī)律。</p><p>  在刪除操作中當(dāng)只有一個(gè)

13、結(jié)點(diǎn)時(shí)可直接刪除,否則用左子樹(shù)中最右下結(jié)點(diǎn)來(lái)替代要被刪除的結(jié)點(diǎn)進(jìn)行刪除操作,亦可用右子樹(shù)中最左下結(jié)點(diǎn)來(lái)替代要被刪除的結(jié)點(diǎn)進(jìn)行刪除操作,可視為同種刪除方法。</p><p>  尋找葉子節(jié)點(diǎn)時(shí)主要采用遞歸方法,從根結(jié)點(diǎn)開(kāi)始遍歷當(dāng)發(fā)現(xiàn)結(jié)點(diǎn)無(wú)左右孩子時(shí)則得到當(dāng)前的結(jié)點(diǎn)元素并用尾插法將其放入單鏈表中直至遍歷完畢,最后輸出單鏈表L。</p><p>  在二叉排序樹(shù)進(jìn)行左右子樹(shù)交換時(shí)新創(chuàng)建樹(shù)R避免對(duì)

14、樹(shù)T的干擾,把樹(shù)T復(fù)制給樹(shù)R,調(diào)用樹(shù)R采用遞歸法和交換法進(jìn)行左右子樹(shù)的交換。</p><p>  尋找只有一個(gè)孩子結(jié)點(diǎn)的結(jié)點(diǎn)個(gè)數(shù)時(shí)也是采用遞歸法,從根結(jié)點(diǎn)開(kāi)始遍歷當(dāng)發(fā)現(xiàn)結(jié)點(diǎn)只有左孩子或右孩子是則計(jì)數(shù)加1直至遍歷完畢,輸出最后的計(jì)數(shù)。</p><p>  在取某元素的祖先結(jié)點(diǎn)時(shí),從根結(jié)點(diǎn)與該元素對(duì)比并尋找該元素,其所走路徑即為該元素的祖先結(jié)點(diǎn)路徑,因此用數(shù)組將該路徑存儲(chǔ)起來(lái),并將其輸出。&l

15、t;/p><p>  設(shè)計(jì)程序的整體功能結(jié)構(gòu)(整體算法的描述)</p><p>  void create(BSTree &T):用來(lái)創(chuàng)建樹(shù),輸入樹(shù)的所有元素;</p><p>  int search(BSTree T,int K,BSTree &q):對(duì)樹(shù)進(jìn)行查找,判斷元素是否存在樹(shù)中;</p><p>  void inse

16、rt(BSTree &T,int e):對(duì)樹(shù)進(jìn)行元素插入;</p><p>  void deleteBST(BSTree &T,int k,int &e):刪除中序前驅(qū),用左子樹(shù)中最右下結(jié)點(diǎn)來(lái)替代要被刪除的結(jié)點(diǎn);</p><p>  void deleteBST1(BSTree &T,int k,int &e):刪除中序后驅(qū),用右子樹(shù)中最左下結(jié)點(diǎn)來(lái)

17、替代要被刪除的結(jié)點(diǎn);</p><p>  void outTree(BSTree &T):中序遍歷函數(shù),并輸出T;</p><p>  int createList(LinkList &L): 創(chuàng)建單鏈表L并為空;</p><p>  int insertList(LinkList &L,int e):用尾插法向單鏈表插入元素;</p&

18、gt;<p>  void leaf(BSTree T,LinkList &L):得到樹(shù)T的葉子節(jié)點(diǎn),并得到其結(jié)點(diǎn); </p><p>  void outList(LinkList L):輸出點(diǎn)鏈表; </p><p>  BSTree copy(BSTree T):創(chuàng)建樹(shù)R,把樹(shù)T復(fù)制給R;</p><p>  void create1(

19、BSTree &R):把樹(shù)R的左右子樹(shù)進(jìn)行交換; </p><p>  int jie(BSTree R):計(jì)算只有一個(gè)孩子結(jié)點(diǎn)元素的個(gè)數(shù); </p><p>  void bstree(BSTree R,int e):得到某元素的祖先結(jié)點(diǎn)并將其輸出; </p><p>  int main():主函數(shù); </p><p

20、><b>  1.3 詳細(xì)設(shè)計(jì)</b></p><p>  #include <stdio.h></p><p>  #include <stdlib.h></p><p>  #define TRUE 1</p><p>  #define FALSE 0</p><

21、p>  #define MAX 20</p><p>  typedef struct node{ // 二叉排序樹(shù)的存儲(chǔ)結(jié)構(gòu) </p><p>  int data; //用整數(shù)表示一個(gè)結(jié)點(diǎn)的名</p><p>  struct node *LChild,*RChild; //左右指針域</p><

22、p>  }BSTNode,*BSTree; </p><p>  typedef struct LNode{ //單鏈表的存儲(chǔ)結(jié)構(gòu)</p><p><b>  int data;</b></p><p>  struct LNode *next;</p><p>  }LNode,*LinkList;</

23、p><p><b>  創(chuàng)建樹(shù)函數(shù):</b></p><p>  void create(BSTree &T){</p><p><b>  int e;</b></p><p><b>  BSTree q;</b></p><p><b&g

24、t;  T=NULL;</b></p><p>  printf("請(qǐng)輸入二叉樹(shù)的根:");</p><p>  scanf("%d",&e);</p><p>  printf("依次輸入個(gè)結(jié)點(diǎn)以-1結(jié)束:\n");</p><p>  while(e!=-1)

25、</p><p>  { if(!search(T,e,q)) </p><p>  insert(T,e);</p><p>  scanf("%d",&e);</p><p><b>  }</b></p><p><b>  } </b>

26、;</p><p><b>  樹(shù)元素查找函數(shù):</b></p><p>  int search(BSTree T,int K,BSTree &q){</p><p>  BSTree p,f;</p><p><b>  p=T;</b></p><p><

27、b>  f=NULL;</b></p><p>  if(p==NULL)</p><p>  return FALSE;</p><p><b>  while(p){</b></p><p>  if(K==p->data)</p><p><b>  {

28、 q=p;</b></p><p>  return TRUE;}</p><p>  else if(K<p->data)</p><p><b>  { f=p;</b></p><p>  p=p->LChild;}</p><p><b> 

29、 else</b></p><p>  { f=p; </p><p>  p=p->RChild;}</p><p>  } </p><p><b>  q=f;</b></p><p>  return FALSE;</p><p&

30、gt;<b>  } </b></p><p><b>  對(duì)樹(shù)進(jìn)行插入函數(shù):</b></p><p>  void insert(BSTree &T,int e){</p><p>  BSTree p,q;</p><p>  if(T==NULL)</p><

31、p>  { p=(BSTree)malloc(sizeof(BSTNode));</p><p>  p->data=e;</p><p>  p->LChild=p->RChild=NULL;</p><p><b>  T=p;}</b></p><p><b>  else&

32、lt;/b></p><p>  { if(!search(T,e,q))</p><p>  { p=(BSTree)malloc(sizeof(BSTNode));</p><p>  p->data=e;</p><p>  p->LChild=p->RChild=NULL;</p>&

33、lt;p>  if(e<q->data)</p><p>  q->LChild=p;</p><p><b>  else</b></p><p>  q->RChild=p;}</p><p><b>  }</b></p><p><

34、b>  }</b></p><p>  刪除函數(shù)(刪除中序前驅(qū)):</p><p>  void deleteBST(BSTree &T,int k,int &e){</p><p>  BSTree q,s,v,t;</p><p><b>  q=T;</b></p>

35、<p><b>  v=NULL;</b></p><p><b>  while(q)</b></p><p>  { if(k==q->data) break; </p><p>  else if(k<q->data)</p><p><b&g

36、t;  { v=q;</b></p><p>  q=q->LChild;}</p><p><b>  else</b></p><p><b>  { v=q;</b></p><p>  q=q->RChild;}</p><p>&

37、lt;b>  }</b></p><p>  if(!q) </p><p>  { printf("我要?jiǎng)h除的數(shù)字不存在。\n");</p><p><b>  return;}</b></p><p>  e=q->data;</p><p

38、>  if(q->LChild&&q->RChild)</p><p>  { s=q->LChild;</p><p><b>  v=q;</b></p><p>  while(s->RChild)</p><p><b>  { v=s;<

39、/b></p><p>  s=s->RChild;}</p><p>  q->data=s->data;</p><p><b>  q=s;</b></p><p><b>  }</b></p><p>  if(q->LChild)

40、 t=q->LChild;</p><p>  else t=q->RChild;</p><p>  if(q==T) T=t;</p><p>  else if(q==v->LChild) v->LChild=t;</p><p>  else v->RChild=t;<

41、/p><p><b>  free(q);</b></p><p>  } </p><p>  刪除函數(shù)(刪除中序后繼):</p><p>  void deleteBST1(BSTree &T,int k,int &e){</p><p>  BSTree q,s

42、,v,t;</p><p><b>  q=T;</b></p><p><b>  v=NULL;</b></p><p><b>  while(q)</b></p><p>  { if(k==q->data) break; </p>

43、<p>  else if(k<q->data)</p><p><b>  { v=q;</b></p><p>  q=q->LChild;}</p><p><b>  else</b></p><p><b>  { v=q;</b&g

44、t;</p><p>  q=q->RChild;}</p><p><b>  }</b></p><p>  if(!q) </p><p>  { printf("你要?jiǎng)h除的數(shù)字不存在。\n");</p><p><b>  return;}

45、</b></p><p>  e=q->data;</p><p>  if(q->LChild&&q->RChild)</p><p>  { s=q->RChild;</p><p><b>  v=q;</b></p><p>  w

46、hile(s->LChild)</p><p><b>  { v=s;</b></p><p>  s=s->LChild;}</p><p>  q->data=s->data;</p><p><b>  q=s;</b></p><p>

47、<b>  }</b></p><p>  if(q->RChild) t=q->RChild;</p><p>  else t=q->LChild;</p><p>  if(q==T) T=t;</p><p>  else if(q==v->RChild) v-

48、>RChild=t;</p><p>  else v->LChild=t;</p><p><b>  free(q);</b></p><p><b>  } </b></p><p>  中序遍歷函數(shù): </p><p>  void outTre

49、e(BSTree &T){</p><p><b>  if(T)</b></p><p>  { outTree(T->LChild);</p><p>  printf("%4d",T->data);</p><p>  outTree(T->RChild);<

50、;/p><p><b>  }</b></p><p><b>  }</b></p><p><b>  創(chuàng)建單鏈表: </b></p><p>  int createList(LinkList &L){ //單鏈表初始化 </p><

51、p>  L=(LinkList)malloc(sizeof(LNode));</p><p>  if(!L) return FALSE;</p><p>  L->next=NULL;</p><p>  return TRUE; </p><p><b>  } </b></p&

52、gt;<p><b>  單鏈表插入函數(shù):</b></p><p>  int insertList(LinkList &L,int e){ //向單鏈表插入元素 </p><p>  LNode *p=L,*q;</p><p>  q=(LNode *)malloc(sizeof(LNode));</p>

53、;<p>  if(!q) return FALSE;</p><p>  while(p->next!=NULL)</p><p>  p=p->next;</p><p>  q->data=e;</p><p>  q->next=p->next;</p><p

54、>  p->next=q;</p><p><b>  } </b></p><p>  葉子結(jié)點(diǎn)函數(shù): </p><p>  void leaf(BSTree T,LinkList &L){</p><p><b>  if(T){ </b></p><

55、;p>  if(T->LChild==NULL&&T->RChild==NULL)</p><p>  insertList(L,T->data);</p><p>  leaf(T->LChild,L);</p><p>  leaf(T->RChild,L);} </p><p><

56、;b>  }</b></p><p>  單鏈表輸出函數(shù): </p><p>  void outList(LinkList L){ //輸出單鏈表</p><p><b>  LNode *p;</b></p><p>  p=L->next;</p><p>

57、;<b>  while(p)</b></p><p>  { printf("%4d",p->data); </p><p>  p=p->next;}</p><p><b>  }</b></p><p><b>  創(chuàng)建樹(shù)R函數(shù):</b&

58、gt;</p><p>  BSTree copy(BSTree T){ //把樹(shù)T復(fù)制到樹(shù)R</p><p><b>  BSTree R;</b></p><p>  if(T==NULL) return NULL; </p><p>  R=(BSTree)malloc(sizeof(BSTNode)

59、);</p><p>  R->data=T->data;</p><p>  R->LChild=copy(T->LChild);</p><p>  R->RChild=copy(T->RChild);</p><p><b>  return R;</b></p>

60、<p><b>  }</b></p><p>  樹(shù)R左右子樹(shù)交換函數(shù): </p><p>  void create1(BSTree &R){ </p><p>  BSTree q; </p><p><b>  if(R)</b></p><p&g

61、t;  { create1(R->LChild); </p><p>  create1(R->RChild);</p><p>  q=R->RChild;</p><p>  R->RChild=R->LChild;</p><p>  R->LChild=q;</p><p&

62、gt;<b>  }</b></p><p><b>  }</b></p><p>  計(jì)算只有一個(gè)孩子結(jié)點(diǎn)的函數(shù): </p><p>  int jie(BSTree R){ </p><p>  int left,right,a;</p><p>  if(!

63、R) return 0;</p><p>  if(R->LChild==NULL&&R->RChild!=NULL)</p><p><b>  return 1;</b></p><p>  if(R->LChild!=NULL&&R->RChild==NULL)</p>

64、;<p><b>  return 1;</b></p><p>  left=jie(R->LChild);</p><p>  right=jie(R->RChild); </p><p>  a=left+right;</p><p>  return a; </p>

65、;<p><b>  }</b></p><p>  祖先結(jié)點(diǎn)函數(shù): </p><p>  void bstree(BSTree R,int e){ </p><p>  int v[MAX],i=0,j;</p><p>  BSTree q=R;</p><p><

66、b>  while(q)</b></p><p>  { if(e==q->data) break; </p><p>  else if(e<q->data)</p><p>  { v[i]=q->data;</p><p>  q=q->RChild;}</p&

67、gt;<p><b>  else</b></p><p>  { v[i]=q->data;</p><p>  q=q->LChild;}</p><p><b>  ++i;</b></p><p><b>  }</b></p>

68、;<p>  if(!q) return;</p><p>  for(j=0;j<i;j++)</p><p>  printf("%4d",v[j]);</p><p><b>  } </b></p><p><b>  主函數(shù): </b&

69、gt;</p><p>  int main(){ </p><p>  int e,k,a=0;</p><p><b>  char c;</b></p><p>  BSTree T,R;</p><p>  LinkList L;</p><p>  create

70、(T);</p><p>  printf("1、該二叉排序樹(shù)的中序遍歷序列:\n");</p><p>  outTree(T);</p><p>  R=copy(T);</p><p>  create1(R);</p><p>  printf("\n2、輸入你插入的數(shù)字:&quo

71、t;);</p><p>  scanf("%d",&e);</p><p>  insert(T,e);</p><p>  outTree(T);</p><p>  printf("\n3、請(qǐng)輸入你要?jiǎng)h除的數(shù)字:");</p><p>  scanf("%

72、d",&k);</p><p>  deleteBST(T,k,e);</p><p>  outTree(T);</p><p>  printf("\n4、請(qǐng)輸入你要?jiǎng)h除的數(shù)字:");</p><p>  scanf("%d",&k);</p><p&g

73、t;  deleteBST1(T,k,e);</p><p>  outTree(T); </p><p>  createList(L);</p><p>  printf("\n5、是否輸出葉子結(jié)點(diǎn)構(gòu)成的單鏈表 Y or N: ");</p><p>  scanf("%s",&c);&

74、lt;/p><p>  if(c=='Y')</p><p>  { leaf(T,L);</p><p>  outList(L);}</p><p>  printf("\n6、是否輸出二叉排序樹(shù)的左右子樹(shù)進(jìn)行交換后的二叉樹(shù) Y or N: ");</p><p>  sc

75、anf("%s",&c);</p><p>  if(c=='Y')</p><p>  outTree(R); </p><p>  printf("\n7、是否輸出二叉排序樹(shù)中只有一個(gè)孩子結(jié)點(diǎn)的結(jié)點(diǎn)個(gè)數(shù) Y or N: ");</p><p>  scanf("

76、;%s",&c);</p><p>  if(c=='Y')</p><p>  printf("%4d",jie(R));</p><p>  printf("\n8、請(qǐng)輸入要求祖先結(jié)點(diǎn)的元素: ");</p><p>  scanf("%d",

77、&e);</p><p>  bstree(R,e); </p><p>  system("pause");</p><p><b>  return 0;</b></p><p><b>  } </b></p><p>  1

78、.4 程序運(yùn)行說(shuō)明與結(jié)果</p><p>  1、創(chuàng)建二叉排序樹(shù),并以中序遍歷輸出圖(1):</p><p>  向二叉排序樹(shù)插入元素58:</p><p>  3、刪除二叉排序樹(shù)元素45(刪除中序前驅(qū)):</p><p>  4、刪除二叉排序樹(shù)元素45(刪除中序后繼):</p><p>  由于在3中已刪除45,故

79、給出提示,輸出原樹(shù)。</p><p><b>  5、輸出葉子結(jié)點(diǎn):</b></p><p>  由于樹(shù)T在2中輸入58,故多了元素58。</p><p>  6、交換樹(shù)T的左右子樹(shù),輸出圖(2):</p><p>  中序遍歷輸出的圖(2)是圖(1)的倒序。</p><p>  輸出只有一個(gè)子樹(shù)

80、的結(jié)點(diǎn)個(gè)數(shù):</p><p>  8、查找元素40的祖先結(jié)點(diǎn),并輸出:</p><p>  9、所有的運(yùn)行結(jié)果視圖:</p><p><b>  2. 最短路徑問(wèn)題</b></p><p><b>  2.1 問(wèn)題描述</b></p><p>  假設(shè)網(wǎng)中的頂點(diǎn)用一個(gè)整數(shù)來(lái)

81、表示,并從0開(kāi)始編號(hào),若網(wǎng)中有n個(gè)頂點(diǎn),則這n個(gè)頂點(diǎn)為0,1,……,n-1。并假設(shè)網(wǎng)中不存在頂點(diǎn)到自身的弧。若網(wǎng)采用鄰接矩陣存儲(chǔ)結(jié)構(gòu),則直接用一個(gè)二維數(shù)組來(lái)表示。如下圖所示的一個(gè)有向網(wǎng):</p><p><b>  圖(1)</b></p><p>  (1)基于圖的鄰接表存儲(chǔ)結(jié)構(gòu)重新設(shè)計(jì)dijkstra算法及其輸出算法,并以圖(1)的有向網(wǎng)為測(cè)試實(shí)例編程實(shí)現(xiàn)。<

82、;/p><p> ?。?)dijkstra算法適合求解權(quán)值非負(fù)的單源最短路徑問(wèn)題,即求一個(gè)頂點(diǎn)到其余各個(gè)頂點(diǎn)的最短路徑?,F(xiàn)給定一個(gè)有向網(wǎng)G=(V,E),各條邊上的權(quán)值均非負(fù),給定G中一個(gè)頂點(diǎn)t,要求求出其余各個(gè)頂點(diǎn)到頂點(diǎn)t的最短路徑長(zhǎng)度并構(gòu)造最短路徑,這個(gè)問(wèn)題稱(chēng)為單目標(biāo)最短路徑問(wèn)題。基于鄰接矩陣存儲(chǔ)結(jié)構(gòu)設(shè)計(jì)算法并以圖(1)的有向網(wǎng)為測(cè)試實(shí)例編程實(shí)現(xiàn)。</p><p> ?。?)假設(shè)dijkst

83、ra算法采用鄰接矩陣存儲(chǔ)結(jié)構(gòu),利用dijkstra算法求有向網(wǎng)中任意兩個(gè)頂點(diǎn)間的最短路徑長(zhǎng)度并構(gòu)造最短路徑。以圖(1)的有向網(wǎng)為測(cè)試實(shí)例編程實(shí)現(xiàn)。</p><p> ?。?)假設(shè)dijkstra算法采用鄰接矩陣存儲(chǔ)結(jié)構(gòu),求有向網(wǎng)中頂點(diǎn)i到頂點(diǎn)j的最短路徑長(zhǎng)度并輸出最短路徑,只求頂點(diǎn)i到頂點(diǎn)j的最短路徑,不能有冗余的循環(huán),i和j從鍵盤(pán)輸入,并作為函數(shù)參數(shù)。</p><p> ?。?)dijk

84、stra算法不僅可以求解有向網(wǎng)中權(quán)值非負(fù)的單源最短路徑問(wèn)題,對(duì)于無(wú)向網(wǎng)中權(quán)值非負(fù)的單源最短路徑問(wèn)題,同樣適用。</p><p>  設(shè)G=(V,E)是一個(gè)連通無(wú)向網(wǎng),采用鄰接矩陣存儲(chǔ)結(jié)構(gòu),每條邊上的權(quán)值均非負(fù),從G中任取一個(gè)頂點(diǎn)i,考慮頂點(diǎn)i到各個(gè)頂點(diǎn)的最短路徑長(zhǎng)度:d(i,0),d(i,1),……,d(i,n-1)</p><p>  其中d(i,k)(0≤k≤n-1)表示頂點(diǎn)i到頂點(diǎn)k

85、的最短路徑長(zhǎng)度,規(guī)定d(i,i)=0。這n個(gè)值中最大的那個(gè)稱(chēng)為頂點(diǎn)i的最大距離,記為L(zhǎng)(i),在所有頂點(diǎn)中,使L(i)達(dá)到最小的頂點(diǎn)稱(chēng)為網(wǎng)G的中心。利用dijkstra算法編程求解給定無(wú)向網(wǎng)的中心。</p><p>  例如,下面這個(gè)無(wú)向網(wǎng)的中心為頂點(diǎn)5</p><p><b>  圖(2)</b></p><p> ?。?)假設(shè)將5題中的網(wǎng)看

86、成是一個(gè)礦區(qū),它有7個(gè)礦,分別在頂點(diǎn)0,1,…..,6處,這7個(gè)礦每天的礦產(chǎn)量分別是0:3000t,1:2000t,2:7000t,3:1000t,4:5000t,5:1000t,6:4000t,如下圖所示。</p><p><b>  圖(3)</b></p><p>  現(xiàn)在要在頂點(diǎn)0,1,…..,6中選一個(gè)來(lái)建選礦廠,如果選礦廠建在了頂點(diǎn)i,那么我們關(guān)心的是將各

87、個(gè)礦生產(chǎn)的礦石都運(yùn)到頂點(diǎn)i處的運(yùn)輸量是多少,然后再來(lái)確定在哪里建選礦廠最好。一般情況下,我們以運(yùn)輸?shù)膖×km數(shù)來(lái)度量運(yùn)輸量的大小,一噸貨物運(yùn)輸一公里就叫1t×km。例如,如果選礦廠建在頂點(diǎn)0處,則總的運(yùn)輸量表示為g(0),它等于</p><p>  g(0)=3000×0+2000×3+7000×5+1000×6.3+5000×9.3+1000

88、×4.5+4000×6=122300(t×km)</p><p>  如果選礦廠建在頂點(diǎn)1處,則總的運(yùn)輸量表示為g(1),它等于</p><p>  g(1)=3000×3+2000×0+7000×2+1000×3.3+5000×6.3+1000×1.5+4000×3=68300(t

89、5;km)</p><p>  顯然,選礦廠建在頂點(diǎn)1要比建在頂點(diǎn)0處好,因?yàn)榻ㄔ陧旤c(diǎn)1處時(shí)運(yùn)輸量較小。當(dāng)然,頂點(diǎn)1是不是最好的還不能確定,應(yīng)把g(0),g(1),…,g(6)都算出來(lái)再比較一下,才可以選出一個(gè)最好的建廠地點(diǎn)。</p><p>  一般情況下,給定無(wú)向網(wǎng)G=(V,E),采用鄰接矩陣存儲(chǔ)結(jié)構(gòu),每條邊上的權(quán)值均非負(fù),G的每個(gè)頂點(diǎn)i還有一個(gè)“產(chǎn)量”A(i),對(duì)于每個(gè)頂點(diǎn)i,令:&

90、lt;/p><p>  g(i)=A(0)×d(0,i)+ A(1)×d(1,i)+……+A(n-1)×d(n-1,i)</p><p>  其中d(k,i)(0≤k≤n-1)表示頂點(diǎn)k到頂點(diǎn)i的最短路徑長(zhǎng)度。</p><p>  g(i)代表了把各個(gè)點(diǎn)的物資運(yùn)到頂點(diǎn)i處所花費(fèi)的t×km,對(duì)于具有n個(gè)頂點(diǎn)的無(wú)向網(wǎng)G來(lái)說(shuō),使得g(i

91、)達(dá)到最小的那個(gè)頂點(diǎn)i就稱(chēng)為該網(wǎng)的中央點(diǎn),利用dijkstra算法編程求解給定無(wú)向網(wǎng)的中央點(diǎn)。</p><p>  例如,上述圖(3)的中央點(diǎn)為頂點(diǎn)2。</p><p>  2.2 設(shè)計(jì)方案與概要設(shè)計(jì)</p><p>  最短路徑問(wèn)題應(yīng)用的存儲(chǔ)結(jié)構(gòu)</p><p>  typedef struct ArcNode{ </p&g

92、t;<p>  int weight;</p><p>  int adjvex; </p><p>  struct ArcNode *nextarc; </p><p>  }ArcNode; </p><p>  typedef struct VNode{</p>

93、<p>  VertexType data; </p><p>  ArcNode *firstarc; </p><p><b>  }VNode; </b></p><p>  typedef struct {</p><p>  VNode vertices[MAX];</p><

94、;p>  int vexnum,arcnum; </p><p><b>  int kind;</b></p><p><b>  }ALGraph;</b></p><p>  應(yīng)用到很多的數(shù)組,其g[100][100]用于鄰接矩陣存儲(chǔ),d[100]用于存儲(chǔ)路徑長(zhǎng)度,path[100]用于存儲(chǔ)上一個(gè)鄰接點(diǎn),f

95、inal[100]用于區(qū)分集合S和V,final[]=1時(shí)在集合S,final[]=0時(shí)在集合V。</p><p><b>  2.方案設(shè)計(jì)</b></p><p>  通過(guò)鄰接表尋找有向圖中源點(diǎn)到各點(diǎn)的最短路徑,要先創(chuàng)建鄰接表。把dijkstra算法設(shè)計(jì)為利用鄰接表查找最短路徑的算法,在輸入源點(diǎn)后調(diào)用方法并進(jìn)行輸出操作。至于單目標(biāo)問(wèn)題創(chuàng)建一個(gè)與原鄰接表相反的逆鄰接表

96、,如果創(chuàng)建成功則與源點(diǎn)問(wèn)題相同。任意兩點(diǎn)間的最短路徑是把個(gè)元素分別作為源點(diǎn),依次調(diào)用方法并進(jìn)行輸出,得到任意兩點(diǎn)間的最短路徑。固定兩點(diǎn)的最短路徑是通過(guò)鄰接矩陣實(shí)現(xiàn),利用dijkstra算法得到所有的最短路徑,在輸出時(shí)只輸出固定兩點(diǎn)的最短路徑。無(wú)向網(wǎng)的最短路徑方法亦可用dijkstra算法實(shí)現(xiàn),得到以所有元素為源點(diǎn)的最短路徑,并獲得每個(gè)元素的最大距離,然后比較每個(gè)元素的最大距離得到最小距離即為網(wǎng)G的中心。在獲得每個(gè)元素到個(gè)頂點(diǎn)距離時(shí)同時(shí)乘

97、以每個(gè)元素的運(yùn)輸量,得到總運(yùn)輸量,進(jìn)行在比較得到運(yùn)輸量最小的元素即為該網(wǎng)的中央點(diǎn)。</p><p>  設(shè)計(jì)程序的整體功能結(jié)構(gòu)(整體算法的描述)</p><p>  int LocateVex(ALGraph &G, VertexType v):查找元素是否存在有向圖中;</p><p>  void CreateDG(ALGraph &G,ALGr

98、aph &L):創(chuàng)建鄰接表有向圖G和其逆鄰接表;</p><p>  void GraphOutput(ALGraph &G):用鄰接表輸出有向圖G;</p><p>  void dijkstra(int s,ALGraph &G) :鄰接表型的dijkstra算法;</p><p>  void out(int s,ALGraph &a

99、mp;G):鄰接表dijkstra算法的輸出;</p><p>  void out1(int s,ALGraph &L):?jiǎn)文繕?biāo)的最短路徑輸出;</p><p>  void dijkstra(int n,int s,int v):兩定點(diǎn)間的dijkstra算法;</p><p>  void out(int n,int s,int v):兩定點(diǎn)間的路徑輸

100、出;</p><p>  void dijkstra(int n, int s):dijkstra算法;</p><p>  void out(int n, int s):最短路徑輸出和獲得最大距離;</p><p>  void out1(int n, int s):輸出總運(yùn)輸量;</p><p>  int main():主函數(shù); &

101、lt;/p><p><b>  2.3 詳細(xì)設(shè)計(jì)</b></p><p>  題(1)、(2)和(3)代碼如下:</p><p>  #include <stdio.h></p><p>  #include <stdlib.h></p><p>  #include <

102、;string.h></p><p>  #define MAX 20</p><p>  typedef char VertexType[MAX]; //頂點(diǎn)類(lèi)型</p><p>  typedef struct ArcNode{ //有向圖,省略的第二個(gè)成員</p><p>  int weight;</p>

103、;<p>  int adjvex; </p><p>  struct ArcNode *nextarc; </p><p>  }ArcNode; </p><p>  typedef struct VNode{</p><p>  VertexType data; </p&

104、gt;<p>  ArcNode *firstarc; </p><p><b>  }VNode; </b></p><p>  typedef struct {</p><p>  VNode vertices[MAX];</p><p>  int vexnum,arcnum; </p&

105、gt;<p><b>  int kind;</b></p><p><b>  }ALGraph;</b></p><p><b>  查找函數(shù): </b></p><p>  int LocateVex(ALGraph &G, VertexType v)</p>

106、;<p><b>  { int i;</b></p><p>  for (i=0;i<G.vexnum;i++)</p><p>  if(strcmp(G.vertices[i].data,v)==0) </p><p><b>  return i;</b></p><p

107、>  return -1;}</p><p>  創(chuàng)建有向圖: </p><p>  void CreateDG(ALGraph &G,ALGraph &L){ </p><p>  int i,k,j,a,x,y;</p><p>  VertexType v1,v2;</p><p>

108、;  ArcNode *p,*s;</p><p><b>  G.kind=3;</b></p><p>  printf("請(qǐng)輸入有向圖的頂點(diǎn)數(shù):\n");</p><p>  scanf("%d",&(G.vexnum));</p><p>  printf(&quo

109、t;請(qǐng)輸入有向圖的邊數(shù):\n");</p><p>  scanf("%d",&(G.arcnum));</p><p>  L.vexnum=G.vexnum;</p><p>  L.arcnum=G.arcnum;</p><p>  for(k=0;k<G.vexnum;k++)</p

110、><p>  { getchar();</p><p>  printf("輸入第%d個(gè)頂點(diǎn): ",k+1);</p><p>  scanf("%s",G.vertices[k].data);</p><p>  strcpy(L.vertices[k].data,G.vertices[k].dat

111、a);</p><p>  G.vertices[k].firstarc=NULL; </p><p>  L.vertices[k].firstarc=NULL;}</p><p>  for(k=0;k<G.arcnum;k++)</p><p>  { getchar();</p><p>  print

112、f("輸入第%d邊 和 權(quán)值\n",k+1);</p><p>  scanf("%s%s%d",v1,v2,&a);</p><p>  i= LocateVex (G,v1);</p><p>  j= LocateVex (G,v2);</p><p>  x= LocateVex (

113、L,v1);</p><p>  y= LocateVex (L,v2);</p><p>  if(i<0 ||j<0||x<0||y<0) {printf("error!!!!!"); return ;}</p><p>  p=(ArcNode *) malloc(sizeof(ArcNode));</p>

114、;<p>  s=(ArcNode *) malloc(sizeof(ArcNode));</p><p>  p->adjvex=j;</p><p>  s->adjvex=x;</p><p>  p->weight=a;</p><p>  s->weight=a;</p><

115、p>  p->nextarc=G.vertices[i].firstarc;</p><p>  s->nextarc=L.vertices[y].firstarc;</p><p>  G.vertices[i].firstarc =p; </p><p>  L.vertices[y].firstarc =s; </p><

116、p><b>  }</b></p><p><b>  }</b></p><p><b>  輸出鄰接表函數(shù):</b></p><p>  void GraphOutput(ALGraph &G) //鄰接表的輸出</p><p>

117、  { int i;</p><p>  ArcNode *s;</p><p>  for(i=0;i<G.vexnum;i++)</p><p>  { printf("(%d)%s: ",i,G.vertices[i].data);</p><p>  s=G.vertices[i].firstarc;

118、</p><p><b>  while(s)</b></p><p>  { printf("--->%4d 權(quán)值%d",s->adjvex,s->weight); s=s->nextarc; }</p><p>  printf("\n"); } }</p>

119、<p>  鄰接表dijkstra算法函數(shù):</p><p>  int final[100],d[100],path[100];</p><p>  void dijkstra(int s,ALGraph &G) </p><p>  { int i,j,k,min,b;</p><p>  

120、ArcNode *p;</p><p>  p=G.vertices[s].firstarc;</p><p>  final[s]=1;</p><p>  for(i=0;i<G.vexnum;i++)</p><p><b>  if(i!=s){</b></p><p><b&

121、gt;  d[i]=999;</b></p><p>  path[i]=-1;</p><p>  final[i]=0;}</p><p>  while(p){ </p><p>  d[p->adjvex]=p->weight;</p><p>  path[p->adjve

122、x]=s; </p><p>  p=p->nextarc;</p><p><b>  }</b></p><p>  for(j=1;j<G.vexnum;j++)</p><p>  { min=999;</p><p>  for(i=0;i<G.vexnum;

123、i++)</p><p>  if(!final[i]&&d[i]<=min)</p><p>  { min=d[i];</p><p>  k=i; }</p><p>  if(d[k]==999)</p><p><b>  break;</b&

124、gt;</p><p>  final[k]=1;</p><p>  p=G.vertices[k].firstarc;</p><p>  while(p){ </p><p>  b=p->adjvex;</p><p>  if(!final[b]&&p->weight+d[k]&l

125、t;d[b])</p><p>  { d[b]=p->weight+d[k];</p><p>  path[p->adjvex]=k; </p><p><b>  }</b></p><p>  p=p->nextarc;</p><p><b>  }&l

126、t;/b></p><p><b>  }</b></p><p><b>  }</b></p><p>  鄰接表dijkstra算法輸出函數(shù):</p><p>  void out(int s,ALGraph &G){ </p><p>  i

127、nt b[100];</p><p>  int i,j,p,m;</p><p>  dijkstra(s, G);</p><p>  for(i=0;i<G.vexnum;i++)</p><p>  if(i!=s){ </p><p>  p=path[i];</p><p> 

128、 if(p==-1) </p><p>  printf("從源點(diǎn)%d到頂點(diǎn)%d不存在路徑!\n",s,i); </p><p><b>  else{</b></p><p>  printf("從源點(diǎn)%d到頂點(diǎn)%d的最短路徑長(zhǎng)度為%d!\n",s,i,d[i]);</p><p

129、>  printf("從源點(diǎn)%d到頂點(diǎn)%d的最短路徑為:",s, i);</p><p><b>  m=0;</b></p><p><b>  b[m]=i;</b></p><p><b>  m++;</b></p><p>  while(p

130、!=s){ </p><p><b>  b[m]=p;</b></p><p>  p=path[p];</p><p><b>  m++;</b></p><p><b>  }</b></p><p><b>  b[m]=s;&l

131、t;/b></p><p>  for(j=m;j>=0;j--)</p><p>  printf("%4d",b[j]);</p><p>  printf("\n");</p><p><b>  }</b></p><p><b&g

132、t;  }</b></p><p><b>  }</b></p><p><b>  單目標(biāo)輸出函數(shù):</b></p><p>  void out1(int s,ALGraph &L){ </p><p>  int b[100];</p>&l

133、t;p>  int i,j,p,m;</p><p>  dijkstra(s, L);</p><p>  for(i=0;i<L.vexnum;i++)</p><p>  if(i!=s){ </p><p>  p=path[i];</p><p>  if(p==-1) </p>

134、<p>  printf("從源點(diǎn)%d到頂點(diǎn)%d不存在路徑!\n",i,s); </p><p><b>  else{</b></p><p>  printf("從源點(diǎn)%d到頂點(diǎn)%d的最短路徑長(zhǎng)度為%d!\n",i,s,d[i]);</p><p>  printf("從源點(diǎn)%d

135、到頂點(diǎn)%d的最短路徑為:",i,s);</p><p><b>  m=0;</b></p><p><b>  b[m]=i;</b></p><p><b>  m++;</b></p><p>  while(p!=s){ </p><p

136、><b>  b[m]=p;</b></p><p>  p=path[p];</p><p><b>  m++;</b></p><p><b>  }</b></p><p><b>  b[m]=s;</b></p><p

137、>  for(j=0;j<=m;j++)</p><p>  printf("%4d",b[j]);</p><p>  printf("\n");</p><p><b>  }</b></p><p><b>  }</b></p>

138、<p><b>  }</b></p><p><b>  主函數(shù):</b></p><p>  int main()</p><p>  { int v,i;</p><p><b>  char a;</b></p><p&g

139、t;  ALGraph G,L;</p><p>  CreateDG(G,L);</p><p>  printf("有向圖鄰接表\n");</p><p>  GraphOutput(G);</p><p>  printf("輸入源點(diǎn)v\n");</p><p>  sca

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論