最小二叉树的kruskal
大致思路就是先把所有边长的权值按从下到大进行排序,然后每次选一条放进去,选完后要判断一下是否构成一个环,如果构成就不能选这条边,而是选下一条直到把去所有定点的路径都包括进来,如果是n个顶点的话也就是n-1条边。
具体代码实现:
#include<stdio.h>
#include<stdlib.h>
#define MAX 32767
typedef struct { //邻接矩阵的创建
char* vexs;
int** arcs;
int VexNum, arcNum;
}Graph;
typedef struct Edge {
int start;
int end;
int weight;
}Edge;
Edge* initEdge(Graph* G) { //把边都放进去
int index = 0;
Edge* edge = (Edge*)malloc(sizeof(Edge)*G->arcNum);
for(int i=0;i<G->VexNum;i++)
for (int j = i+1; j < G->VexNum; j++) {
if (G->arcs[i][j] != MAX) {
edge[index].start = i;
edge[index].end = j;
edge[index].weight = G->arcs[i][j];
index++;
}
}
return edge;
}
void sortEdge(Edge* edge, Graph* G) { //把边从小到大排序
Edge temp;
for(int i=0;i<G->arcNum-1;i++)
for (int j = 0; j < G->arcNum-1-i; j++)
if (edge[j].weight > edge[j + 1].weight) {
temp = edge[j];
edge[j] = edge[j + 1];
edge[j + 1] = temp;
}
}
void kruskal(Graph* G) {
int* connected = (int*)malloc(sizeof(int) * G->VexNum);
for (int i = 0; i < G->VexNum; i++)
connected[i] = i;
Edge* edge = initEdge(G);
sortEdge(edge, G);
for (int i = 0; i < G->arcNum; i++) {
int start = connected[edge[i].start];
int end = connected[edge[i].end];
if (start != end) { //起始连通分量不等于终点连通分量
printf("V%c-->V%c weight=%d\n", G->vexs[edge[i].start], G->vexs[edge[i].end], edge[i].weight);
for(int j=0;j<G->VexNum;j++)
if (connected[j] == end) {
connected[j] = start;
}
}
}
}
Graph* initGraph(int VexNum) {
Graph* G = (Graph*)malloc(sizeof(Graph));
G->vexs = (char*)malloc(sizeof(char) * VexNum);
G->arcs = (int**)malloc(sizeof(int*) * VexNum);
for (int i = 0; i < VexNum; i++) {
G->arcs[i] = (int*)malloc(sizeof(int) * VexNum);
}
G->VexNum = VexNum;
G->arcNum = 0;
return G;
}
void CreateGraph(Graph* G, char* vexs, int* arcs) {
for (int i = 0; i < G->VexNum; i++) {
G->vexs[i] = vexs[i];
for (int j = 0; j < G->VexNum; j++) {
//G->arcs[i][j] = arcs[i][j];
//不能直接传二维数组会越界
G->arcs[i][j] = *(arcs + i * G->VexNum + j);
if (G->arcs[i][j] != 0&&G->arcs[i][j]!=MAX)
G->arcNum++;
}
}
G->arcNum /= 2;
}
int main() {
Graph* G = initGraph(6);
//int* visited = (int*)malloc(sizeof(int) * G->VexNum);
//for (int i = 0; i < G->VexNum; i++) {
// visited[i] = 0;
//}
int arcs[6][6] = {
0,6,1,5,MAX,MAX,
6,0,5,MAX,3,MAX,
1,5,0,5,6,4,
5,MAX,5,0,MAX,2,
MAX,3,6,MAX,0,6,
MAX,MAX,4,2,6,0
};
CreateGraph(G, "123456", (int*)arcs);
kruskal(G);
return 0;
}
最短路径的dijkstra算法
每次从 「未求出最短路径的点」中 取出 距离距离起点 最小路径的点,以这个点为桥梁 刷新「未求出最短路径的点」的距离
#include <stdio.h>
#include <stdlib.h>
#define MAX 32767
typedef struct Graph {
char* vexs;
int** arcs;
int vexNum;
int arcNum;
}Graph;
Graph* initGraph(int vexNum) {
Graph* G = (Graph*)malloc(sizeof(Graph));
G -> vexs = (char*)malloc(sizeof(char) * vexNum);
G -> arcs = (int**)malloc(sizeof(int*) * vexNum);
for (int i = 0 ; i < vexNum; i++) {
G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);
}
G -> vexNum = vexNum;
G -> arcNum = 0;
return G;
}
void createGraph(Graph* G, char* vexs, int* arcs) {
for (int i = 0 ; i < G -> vexNum; i++) {
G -> vexs[i] = vexs[i];
for (int j = 0; j < G -> vexNum; j++) {
G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);
if (G -> arcs[i][j] != 0 && G -> arcs[i][j] != MAX)
G -> arcNum ++;
}
}
G -> arcNum /= 2;
}
void DFS(Graph* G, int* visited, int index) {
printf("%c\t", G -> vexs[index]);
visited[index] = 1;
for (int i = 0; i < G ->vexNum; i++) {
if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX && !visited[i]) {
DFS(G, visited, i);
}
}
}
int getMin(int* d, int* s, Graph* G) {
int min = MAX;
int index;
for (int i = 0; i < G -> vexNum; i++) {
if (!s[i] && d[i] < min) {
min = d[i];
index = i;
}
}
return index;
}
void dijkstra(Graph* G, int index) {
// 准备辅助数组
int* s = (int*)malloc(sizeof(int) * G -> vexNum);
int* p = (int*)malloc(sizeof(int) * G -> vexNum);
int* d = (int*)malloc(sizeof(int) * G -> vexNum);
// 初始化辅助数组
for (int i = 0; i < G -> vexNum; i++) {
if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX) {
d[i] = G -> arcs[index][i];
p[i] = index;
}
else {
d[i] = MAX;
p[i] = -1;
}
if (i == index) {
s[i] = 1;
d[i] = 0;
}
else
s[i] = 0;
}
for (int i = 0; i < G -> vexNum - 1; i++) {
int index = getMin(d, s, G);
s[index] = 1;
for (int j = 0; j < G -> vexNum; j++) {
if (!s[j] && d[index] + G -> arcs[index][j] < d[j]) {
d[j] = d[index] + G -> arcs[index][j];
p[j] = index;
}
}
}
for (int i = 0; i < G ->vexNum; i++) {
printf("%d %d %d\n", s[i], p[i], d[i]);
}
}
int main() {
Graph* G = initGraph(7);
int* visited = (int*)malloc(sizeof(int) * G -> vexNum);
for (int i = 0; i < G -> vexNum; i++)
visited[i] = 0;
int arcs[7][7] = {
0, 12, MAX, MAX, MAX, 16, 14,
12, 0, 10, MAX, MAX, 7, MAX,
MAX, 10, 0, 3, 5, 6, MAX,
MAX, MAX, 3, 0, 4, MAX, MAX,
MAX, MAX, 5, 4, 0, 2, 8,
16, 7, 6, MAX, 2, 0, 9,
14, MAX, MAX, MAX, 8, 9, 0
};
createGraph(G, "1234567", (int*)arcs);
DFS(G, visited, 0);
printf("\n");
dijkstra(G, 0);
return 0;
}
具体代码思路来着 tyrantlucifer