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

下載本文檔

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

文檔簡介

1、<p>  課程設(shè)計綜合成績評定</p><p>  設(shè)計題目一: 二 叉 排 序 樹 </p><p>  設(shè)計題目二: 最 短 路 徑 問 題 </p><p>  設(shè)計題目三: <

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

17、替代要被刪除的結(jié)點;</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):得到樹T的葉子節(jié)點,并得到其結(jié)點; </p><p>  void outList(LinkList L):輸出點鏈表; </p><p>  BSTree copy(BSTree T):創(chuàng)建樹R,把樹T復(fù)制給R;</p><p>  void create1(

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

20、><b>  1.3 詳細設(shè)計</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{ // 二叉排序樹的存儲結(jié)構(gòu) </p><p>  int data; //用整數(shù)表示一個結(jié)點的名</p><p>  struct node *LChild,*RChild; //左右指針域</p><

22、p>  }BSTNode,*BSTree; </p><p>  typedef struct LNode{ //單鏈表的存儲結(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ù):</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("請輸入二叉樹的根:");</p><p>  scanf("%d",&e);</p><p>  printf("依次輸入個結(jié)點以-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ù):</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>  對樹進行插入函數(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("我要刪除的數(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("你要刪除的數(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é)點函數(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)建樹R函數(shù):</b&

58、gt;</p><p>  BSTree copy(BSTree T){ //把樹T復(fù)制到樹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>  樹R左右子樹交換函數(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>  計算只有一個孩子結(jié)點的函數(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é)點函數(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、該二叉排序樹的中序遍歷序列:\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、請輸入你要刪除的數(shù)字:");</p><p>  scanf("%

72、d",&k);</p><p>  deleteBST(T,k,e);</p><p>  outTree(T);</p><p>  printf("\n4、請輸入你要刪除的數(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é)點構(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、是否輸出二叉排序樹的左右子樹進行交換后的二叉樹 Y or N: ");</p><p>  sc

75、anf("%s",&c);</p><p>  if(c=='Y')</p><p>  outTree(R); </p><p>  printf("\n7、是否輸出二叉排序樹中只有一個孩子結(jié)點的結(jié)點個數(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、請輸入要求祖先結(jié)點的元素: ");</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 程序運行說明與結(jié)果</p><p>  1、創(chuàng)建二叉排序樹,并以中序遍歷輸出圖(1):</p><p>  向二叉排序樹插入元素58:</p><p>  3、刪除二叉排序樹元素45(刪除中序前驅(qū)):</p><p>  4、刪除二叉排序樹元素45(刪除中序后繼):</p><p>  由于在3中已刪除45,故

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

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

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

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

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

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

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

86、成是一個礦區(qū),它有7個礦,分別在頂點0,1,…..,6處,這7個礦每天的礦產(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)在要在頂點0,1,…..,6中選一個來建選礦廠,如果選礦廠建在了頂點i,那么我們關(guān)心的是將各

87、個礦生產(chǎn)的礦石都運到頂點i處的運輸量是多少,然后再來確定在哪里建選礦廠最好。一般情況下,我們以運輸?shù)膖×km數(shù)來度量運輸量的大小,一噸貨物運輸一公里就叫1t×km。例如,如果選礦廠建在頂點0處,則總的運輸量表示為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>  如果選礦廠建在頂點1處,則總的運輸量表示為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>  顯然,選礦廠建在頂點1要比建在頂點0處好,因為建在頂點1處時運輸量較小。當然,頂點1是不是最好的還不能確定,應(yīng)把g(0),g(1),…,g(6)都算出來再比較一下,才可以選出一個最好的建廠地點。</p><p>  一般情況下,給定無向網(wǎng)G=(V,E),采用鄰接矩陣存儲結(jié)構(gòu),每條邊上的權(quán)值均非負,G的每個頂點i還有一個“產(chǎn)量”A(i),對于每個頂點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)表示頂點k到頂點i的最短路徑長度。</p><p>  g(i)代表了把各個點的物資運到頂點i處所花費的t×km,對于具有n個頂點的無向網(wǎng)G來說,使得g(i

91、)達到最小的那個頂點i就稱為該網(wǎng)的中央點,利用dijkstra算法編程求解給定無向網(wǎng)的中央點。</p><p>  例如,上述圖(3)的中央點為頂點2。</p><p>  2.2 設(shè)計方案與概要設(shè)計</p><p>  最短路徑問題應(yīng)用的存儲結(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]用于鄰接矩陣存儲,d[100]用于存儲路徑長度,path[100]用于存儲上一個鄰接點,f

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

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

97、以每個元素的運輸量,得到總運輸量,進行在比較得到運輸量最小的元素即為該網(wǎng)的中央點。</p><p>  設(shè)計程序的整體功能結(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):單目標的最短路徑輸出;</p><p>  void dijkstra(int n,int s,int v):兩定點間的dijkstra算法;</p><p>  void out(int n,int s,int v):兩定點間的路徑輸

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):輸出總運輸量;</p><p>  int main():主函數(shù); &

101、lt;/p><p><b>  2.3 詳細設(shè)計</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]; //頂點類型</p><p>  typedef struct ArcNode{ //有向圖,省略的第二個成員</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("請輸入有向圖的頂點數(shù):\n");</p><p>  scanf("%d",&(G.vexnum));</p><p>  printf(&quo

109、t;請輸入有向圖的邊數(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個頂點: ",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("從源點%d到頂點%d不存在路徑!\n",s,i); </p><p><b>  else{</b></p><p>  printf("從源點%d到頂點%d的最短路徑長度為%d!\n",s,i,d[i]);</p><p

129、>  printf("從源點%d到頂點%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>  單目標輸出函數(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("從源點%d到頂點%d不存在路徑!\n",i,s); </p><p><b>  else{</b></p><p>  printf("從源點%d到頂點%d的最短路徑長度為%d!\n",i,s,d[i]);</p><p>  printf("從源點%d

135、到頂點%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("輸入源點v\n");</p><p>  sca

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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

提交評論