一步一步寫演算法(之prim演算法 中)

2021-12-29 20:50:40 字數 4858 閱讀 8774

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條,這條路徑都可以達到目的地,然而我們在挑選...