绣春刀修罗战场豆瓣:一步一步写算法(之prim算法 中)

来源:百度文库 编辑:中财网 时间:2024/05/05 06:56:19

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】


C)编写最小生成树,涉及创建、挑选和添加过程

view plaincopy to clipboardprint?

  1. MINI_GENERATE_TREE* get_mini_tree_from_graph(GRAPH* pGraph)
  2. {
  3. MINI_GENERATE_TREE* pMiniTree;
  4. DIR_LINE pDirLine;
  5. if(NULL == pGraph || NULL == pGraph->head)
  6. return NULL;
  7. pMiniTree = (MINI_GENERATE_TREE*)malloc(sizeof(MINI_GENERATE_TREE));
  8. assert(NULL != pMiniTree);
  9. memset(pMiniTree, 0, sizeof(MINI_GENERATE_TREE));
  10. pMiniTree->node_num = 1;
  11. pMiniTree->pNode = (int*)malloc(sizeof(int) * pGraph->count);
  12. memset(pMiniTree->pNode, 0, sizeof(int) * pGraph->count);
  13. pMiniTree->pNode[0] = pGraph->head->start;
  14. while(1){
  15. memset(&pDirLine, 0, sizeof(DIR_LINE));
  16. get_dir_line_from_graph(pGraph, pMiniTree, &pDirLine);
  17. if(pDirLine.start == 0)
  18. break;
  19. pMiniTree->line_num ++;
  20. insert_line_into_queue(&pMiniTree->pLine, pDirLine.start, pDirLine.end, pDirLine.weight);
  21. insert_node_into_mini_tree(&pDirLine, pMiniTree);
  22. }
  23. return pMiniTree;
  24. }

d) 构建挑选函数,选择最合适的边

view plaincopy to clipboardprint?

  1. void get_dir_line_from_graph(GRAPH* pGraph, MINI_GENERATE_TREE* pMiniTree, DIR_LINE* pDirLine)
  2. {
  3. DIR_LINE* pHead;
  4. DIR_LINE* prev;
  5. VECTEX* pVectex;
  6. LINE* pLine;
  7. int index;
  8. int start;
  9. pHead = NULL;
  10. for(index = 0; index < pMiniTree->node_num; index++){
  11. start = pMiniTree->pNode[index];
  12. pVectex = find_vectex_in_graph(pGraph->head, start);
  13. pLine = pVectex->neighbor;
  14. while(pLine){
  15. insert_line_into_queue(&pHead, start, pLine->end, pLine->weight);
  16. pLine = pLine->next;
  17. }
  18. }
  19. if(NULL == pHead)
  20. return;
  21. delete_unvalid_line_from_list(&pHead, pMiniTree);
  22. if(NULL == pHead)
  23. return;
  24. sort_for_line_list(&pHead);
  25. memmove(pDirLine, pHead, sizeof(DIR_LINE));
  26. while(pHead){
  27. prev = pHead;
  28. pHead = pHead->next;
  29. free(prev);
  30. }
  31. return;
  32. }


e)添加节点函数,将尚不是最小生成树的点纳入到最小生成树当中去

view plaincopy to clipboardprint?

  1. void insert_node_into_mini_tree(DIR_LINE* pLine, MINI_GENERATE_TREE* pMiniTree)
  2. {
  3. int index;
  4. for(index = 0; index < pMiniTree->node_num; index ++){
  5. if(pLine->start == pMiniTree->pNode[index]){
  6. pMiniTree->pNode[pMiniTree->node_num++] = pLine->end;
  7. return;
  8. }
  9. }
  10. pMiniTree->pNode[pMiniTree->node_num++] = pLine->start;
  11. return;
  12. }

注意事项:

(1)d、e是c中调用的子函数,如果大家观察一下就明白了

(2)最小生成树是按照自顶向下的顺序编写的,虽然c中的子函数完成了,但是d中还有两个子函数没有着落

(3)d中的函数delete_unvalid_line_from_list、sort_for_line_list会在下一篇中继续介绍

(4)算法只要能够按照手工计算的流程编写出来,基本上问题不大,但是一些细节还是要小心注意的


【待续】