

版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)
- 《數(shù)據(jù)結(jié)構(gòu)》課程設(shè)計(jì)--二叉排序樹(shù)調(diào)整為平衡二叉樹(shù)
- 《數(shù)據(jù)結(jié)構(gòu)遍歷二叉樹(shù)》課程設(shè)計(jì)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)---二叉排序樹(shù)和平衡二叉樹(shù)的判別
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)---計(jì)算二叉樹(shù)高度
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--二叉排序樹(shù)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)----二叉樹(shù)的應(yīng)用
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)---判別給定的二叉樹(shù)是否為二叉排序樹(shù)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--二叉樹(shù)及應(yīng)用
- 課程設(shè)計(jì) 排序二叉樹(shù)
- 數(shù)據(jù)結(jié)構(gòu),課程設(shè)計(jì),校園最短路徑問(wèn)題
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告---線索二叉樹(shù)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--二叉樹(shù)的遍歷
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)---二叉樹(shù)的操作
- 數(shù)據(jù)結(jié)構(gòu)樹(shù)和二叉樹(shù)ppt
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--二叉樹(shù)的相關(guān)操作
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告--二叉樹(shù)的算法
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)----二叉樹(shù)平衡的判定
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)--按層次遍歷二叉樹(shù)
- 數(shù)據(jù)結(jié)構(gòu)二叉排序樹(shù)課程設(shè)計(jì)報(bào)告
評(píng)論
0/150
提交評(píng)論