c)編寫最小生成樹,涉及建立、挑選和新增過程
mini_generate_tree* get_mini_tree_from_graph(graph* pgraph)
mini_generate_tree* pminitree;
dir_line pdirline;
if(null == pgraph || null == pgraph->head)
return null;
pminitree = (mini_generate_tree*)malloc(sizeof(mini_generate_tree));
assert(null != pminitree);
memset(pminitree, 0, sizeof(mini_generate_tree));
pminitree->node_num = 1;
pminitree->pnode = (int*)malloc(sizeof(int) * pgraph->count);
memset(pminitree->pnode, 0, sizeof(int) * pgraph->count);
pminitree->pnode[0] = pgraph->head->start;
while(1){
memset(&pdirline, 0, sizeof(dir_line));
get_dir_line_from_graph(pgraph, pminitree, &pdirline);
if(pdirline.start == 0)
break;
pminitree->line_num ++;
insert_line_into_queue(&pminitree->pline, pdirline.start, pdirline.end, pdirline.weight);
insert_node_into_mini_tree(&pdirline, pminitree);
return pminitree;
mini_generate_tree* get_mini_tree_from_graph(graph* pgraph)
mini_generate_tree* pminitree;
dir_line pdirline;
if(null == pgraph || null == pgraph->head)
return null;
pminitree = (mini_generate_tree*)malloc(sizeof(mini_generate_tree));
assert(null != pminitree);
memset(pminitree, 0, sizeof(mini_generate_tree));
pminitree->node_num = 1;
pminitree->pnode = (int*)malloc(sizeof(int) * pgraph->count);
memset(pminitree->pnode, 0, sizeof(int) * pgraph->count);
pminitree->pnode[0] = pgraph->head->start;
while(1){
memset(&pdirline, 0, sizeof(dir_line));
get_dir_line_from_graph(pgraph, pminitree, &pdirline);
if(pdirline.start == 0)
break;
pminitree->line_num ++;
insert_line_into_queue(&pminitree->pline, pdirline.start, pdirline.end, pdirline.weight);
insert_node_into_mini_tree(&pdirline, pminitree);
return pminitree;
d) 構建挑選函式,選擇最合適的邊
void get_dir_line_from_graph(graph* pgraph, mini_generate_tree* pminitree, dir_line* pdirline)
dir_line* phead;
dir_line* prev;
vectex* pvectex;
line* pline;
int index;
int start;
phead = null;
for(index = 0; index < pminitree->node_num; index++){
start = pminitree->pnode[index];
pvectex = find_vectex_in_graph(pgraph->head, start);
pline = pvectex->neighbor;
while(pline){
insert_line_into_queue(&phead, start, pline->end, pline->weight);
pline = pline->next;
if(null == phead)
return;
delete_unvalid_line_from_list(&phead, pminitree);
if(null == phead)
return;
sort_for_line_list(&phead);
memmove(pdirline, phead, sizeof(dir_line));
while(phead){
prev = phead;
phead = phead->next;
free(prev);
return;
void get_dir_line_from_graph(graph* pgraph, mini_generate_tree* pminitree, dir_line* pdirline)
dir_line* phead;
dir_line* prev;
vectex* pvectex;
line* pline;
int index;
int start;
phead = null;
for(index = 0; index < pminitree->node_num; index++){
start = pminitree->pnode[index];
pvectex = find_vectex_in_graph(pgraph->head, start);
pline = pvectex->neighbor;
while(pline){
insert_line_into_queue(&phead, start, pline->end, pline->weight);
pline = pline->next;
if(null == phead)
return;
delete_unvalid_line_from_list(&phead, pminitree);
if(null == phead)
return;
sort_for_line_list(&phead);
memmove(pdirline, phead, sizeof(dir_line));
while(phead){
prev = phead;
phead = phead->next;
free(prev);
return;
e)新增節點函式,將尚不是最小生成樹的點納入到最小生成樹當中去
void insert_node_into_mini_tree(dir_line* pline, mini_generate_tree* pminitree)
int index;
for(index = 0; index < pminitree->node_num; index ++){
if(pline->start == pminitree->pnode[index]){
pminitree->pnode[pminitree->node_num++] = pline->end;
return;
pminitree->pnode[pminitree->node_num++] = pline->start;
return;
void insert_node_into_mini_tree(dir_line* pline, mini_generate_tree* pminitree)
int index;
for(index = 0; index < pminitree->node_num; index ++){
if(pline->start == pminitree->pnode[index]){
pminitree->pnode[pminitree->node_num++] = pline->end;
return;
pminitree->pnode[pminitree->node_num++] = pline->start;
return;
注意事項:
(1)d、e是c中呼叫的子函式,如果大家觀察一下就明白了
(2)最小生成樹是按照自頂向下的順序編寫的,雖然c中的子函式完成了,但是d中還有兩個子函式沒有著落
(3)d中的函式delete_unvalid_line_from_list、sort_for_line_list會在下一篇中繼續介紹
(4)演算法只要能夠按照手工計算的流程編寫出來,基本上問題不大,但是一些細節還是要小心注意的
【待續】
一步一步寫演算法(之prim演算法 下)
前兩篇部落格我們討論了prim最小生成樹的演算法,熟悉了基本的流程。基本上來說,我們是按照自上而下的順序來編寫 的。首先我們搭建乙個架構,然後一步一步完成其中的每乙個子功能,這樣最後構成乙個完成prim演算法計算過程。f 將dir line佇列中不符合的資料刪除,主要是雙節點都已經訪問過的dir l...
一步一步寫演算法(之prim演算法 上)
原文 一步一步寫演算法 之prim演算法 上 前面我們討論了圖的建立 新增 刪除和儲存等問題。今天我們將繼續討論圖的一些其他問題,比如說如何在圖的環境下構建最小生成樹。為什麼要構建最小生成樹呢?其實原理很簡單。打個比方,現在某乙個鄉鎮有n個村,那麼這n個村肯定是聯通的。現在我們打算在各個村之間搭建網...
一步一步寫演算法(之 A 演算法)
在前面的部落格當中,其實我們已經討論過尋路的演算法。不過,當時的示例圖中,可選的路徑是唯一的。我們挑選乙個演算法,就是說要把這個唯一的路徑選出來,怎麼選呢?當時我們就是採用窮盡遞迴的演算法。然而,今天的情形有點不太一樣了。在什麼地方呢?那就是今天的路徑有n條,這條路徑都可以達到目的地,然而我們在挑選...