图的最小生成树1
最小生成树指的就是用最少的边让图连通且边的总长度之和最短。
要让边的长度之和最短我们可以先选择最短的边,然后选择次短的边。。。直到选择了n-1条边为止。如果我们选中的边上的两个顶点已经连通,则放弃选用这条边
Chart[] charts = new Chart[9];
int[] arr = new int[6];
private void init() {
charts[0] = new Chart(1, 3, 11);
charts[1] = new Chart(2, 4, 13);
charts[2] = new Chart(3, 5, 3);
charts[3] = new Chart(4, 5, 4);
charts[4] = new Chart(1, 2, 6);
charts[5] = new Chart(3, 4, 7);
charts[6] = new Chart(0, 1, 1);
charts[7] = new Chart(2, 3, 9);
charts[8] = new Chart(0, 2, 2);
for (int i = 0; i <= 5; i++) {
arr[i] = i;
}
}
private void quickSort(int left, int right) {
if (left > right) {
return;
}
int i, j;
Chart temp;
i = left;
j = right;
temp = charts[left];
while (i != j) {
while (charts[j].w >= temp.w && i < j) {
j--;
}
while (charts[i].w <= temp.w && i < j) {
i++;
}
if (i < j) {
Chart t = charts[i];
charts[i] = charts[j];
charts[j] = t;
}
}
charts[left] = charts[i];
charts[i] = temp;
quickSort(left, i - 1);
quickSort(i + 1, right);
}
private int getFather(int index) {
if (index == arr[index]) {
return index;
}
return getFather(arr[index]);
}
private boolean merge(int u, int v) {
int uFather = getFather(u);
int vFather = getFather(v);
if (uFather == vFather) {
return false;
}
arr[vFather] = uFather;
return true;
}
@Test
public void testSmallTree() {
init();
quickSort(0, 8);
int sum = 0, count = 0;
for (Chart c : charts) {
System.out.println(c.w);
if (merge(c.u, c.v)) {
sum += c.w;
count++;
}
if (count == 5) {//6个顶点需要联通,只需要有5条边
break;
}
}
System.out.println(sum);
}
private class Chart {
int u;
int v;
int w;
public Chart() {
}
public Chart(int u, int v, int w) {
this.u = u;
this.v = v;
this.w = w;
}
}