两种算法的讲解请观看:
https://www.bilibili.com/video/BV1Eb41177d1?from=search&seid=5569805741961941597
先来prim算法
//0:first vertex 1:second vertex 3:arc value
int primArc[14][3] =
{
{0, 1, 4},
{0, 7, 8},
{1, 7, 11},
{1, 2, 8},
{2, 3, 7},
{2, 5, 4},
{2, 8, 2},
{3, 4, 9},
{3, 5, 14},
{4, 5, 10},
{5, 6, 2},
{6, 7, 1},
{6, 8, 6},
{7, 8, 7}
};
typedef struct{
int selected; //vertex selected or not
int miniDistance; //distance between parent and this vetex
int parant; //parent of this vertex, not use now
}primAsistArray;
void primGraph_Init(int (*G)[9], primAsistArray *primArr)
{
memset(G, 0, 81 * sizeof(int));//init this graph element by 0
int j = 0;
for(int i = 0; i < 9; i++)
{
while(i == primArc[j][0])
{
G[i][primArc[j][1]] = primArc[j][2];
G[primArc[j][1]][i] = primArc[j][2];
j++;
}
primArr[i].miniDistance = 99;
primArr[i].selected = 0;
primArr[i].parant = 99;
}
//printf this graph element
for(int i = 0; i < 9; i++)
{
for(int j = 0; j < 9; j++)
{
std::cout << std::setw(3) << G[i][j] ;
}
std::cout << std::endl;
}
std::cout << std::endl;
}
int findMiniDistance(primAsistArray *primArr, int *tempValue)
{
int miniDistance = 99;
int k;
for(int i = 0; i < 9; i++)
{
if (miniDistance > primArr[i].miniDistance)
{
miniDistance = primArr[i].miniDistance;
//primArr[i].parant = temp;
*tempValue = miniDistance;
k = i;
}
}
return k;
}
void primResolv(int (*Graph)[9], primAsistArray *primArr, const int n)
{
int temp = n;
int tempMiniValue[8];
memset(tempMiniValue, 0, 8 * sizeof(int));
//std::cout << std::setw(3) << temp; //cout the first element
primArr[temp].selected = 1;
//find the last 8 rout
for(int i = 0; i < 8; i++)
{
for(int j = 0; j < 9; j++)
{
if(Graph[temp][j] != 0 && primArr[j].selected == 0 )
{
//primArr[j].miniDistance = primArr[j].miniDistance > Graph[temp][j] ? Graph[temp][j] : primArr[j].miniDistance;
if(primArr[j].miniDistance > Graph[temp][j])
{
primArr[j].miniDistance = Graph[temp][j];//find the mini value of the prim array
primArr[j].parant = temp; //update the element's parament value
}
}
}
// std::cout << std::setw(3) << temp << " ---> ";
temp = findMiniDistance(primArr, &tempMiniValue[i]);
//printf relation vertex of mini arc value which is separated with ','
std::cout << primArr[temp].parant << "[" << tempMiniValue[i] << "]" << temp << " , " ;
primArr[temp].selected = 1; //set the vertex as a selected element
primArr[temp].miniDistance = 99;
}
//output sum value
int sum = 0;
for(int i = 0; i < 8; i++)
{
sum = sum + tempMiniValue[i];
}
std::cout << "sum value is:" << sum;
std::cout << std::endl;
}
//
void additionaryArr_Init(primAsistArray *primArr)
{
for(int i = 0; i < 9; i++)
{
primArr[i].miniDistance = 99;
primArr[i].selected = 0;
primArr[i].parant = 99;
}
}
void PRIM_Test(void)
{
primAsistArray usrPrimArr[9];
int primGraph[9][9];
primGraph_Init(primGraph, usrPrimArr);
for(int i = 0; i < 9; i++)
{
primResolv(primGraph, usrPrimArr, i);
std::cout << std::endl;
additionaryArr_Init(usrPrimArr);
}
}
运行结果如下:
再来kruskal
//kruskal
//1:start 2:end 3:weight of arc
int kArc [14][3] =
{
{0, 1, 4},
{0, 7, 8},
{1, 2, 8},
{1, 7, 11},
{2, 3, 7},
{2, 5, 4},
{2, 8, 2},
{3, 4, 9},
{3, 5, 14},
{4, 5, 10},
{5, 6, 2},
{6, 7, 1},
{6, 8, 6},
{7, 8, 7}
};
//reference kArc[][]
typedef struct
{
int start;
int end;
int weigth;
}krArc;
int findTreeRoot(krArc *Tree, int *parentArr, int vertex)
{
int tempval = vertex;
while(parentArr[tempval] != -1)
{
tempval = parentArr[tempval];
}
return tempval;
}
//return 0: find a ring, 1: no ring
//parentArr[14] index of arc's parent, such as ParentArr[5] = 8 means vertex 5's parent is 8
//numberOfArc: how many arcs of this tree now
bool kFindRing(int *parentArr, krArc *miniSizeTree, int numberOfarc, krArc newArc)
{
parentArr[newArc.end] = newArc.start;//smaller vertex number value is configur as father
int rootA = -1;
int rootB = -1;
for(int i = 0; i < numberOfarc; i++)
{
if(miniSizeTree[i].start == newArc.start || miniSizeTree[i].end == newArc.start)
{
rootA = findTreeRoot(miniSizeTree, parentArr, newArc.start);
}
else if(miniSizeTree[i].start == newArc.end || miniSizeTree[i].end == newArc.end)
{
rootB = findTreeRoot(miniSizeTree, parentArr, newArc.end);
}
}
if(rootA == rootB && rootA != -1 && rootA != newArc.start)//if two vertices have the same root, the tree has a ring ,abandon this arc.
{
parentArr[newArc.end] = -1;
std::cout << "find a ring" << std::endl;
return 0;
}
return 1;
}
//union a new arc to minisizeTree
void unionArc(krArc *minisizeTree, int *n, krArc newArc, int *parentArr)
{
if(kFindRing(parentArr, minisizeTree, *n, newArc))//no ring
{
minisizeTree[*n] = newArc;
*n += 1;//the number of arcs ++
}
}
//find the minist arc value from KArc
void findMiniValue(int (*kArc)[3], int *isVisited, krArc *newArc)
{
int tempArcValue = 99;
int tempi;
for(int i = 0; i < 14; i++)
{
if(tempArcValue > kArc[i][2] && isVisited[i] == -1)
{
tempArcValue = kArc[i][2];
tempi = i;
}
}
isVisited[tempi] = 1;
newArc->start = kArc[tempi][0];
newArc->end = kArc[tempi][1];
newArc->weigth = kArc[tempi][2];
}
void kruskal_Test(void)
{
krArc newArc;
krArc minisizeTree[8];//mini size tree
int parentArr[9];
int isVisited[14];
memset(parentArr, -1, 9 * sizeof(int)); //init aux array parentArr which corrospanding the index of parent value
memset(isVisited, -1, 14 * sizeof(int));//note which arcs had been selected
int n = 0;
for(int i = 0; i < 14; i++)
{
findMiniValue(kArc, isVisited, &newArc); //find mini arc
unionArc(minisizeTree, &n, newArc, parentArr); //union arc
if(n == 8) //end of this mini tree
{
std::cout << "find mini tree" << std::endl;
return;
}
}
}
运行结果如下: