尝试使用书中的最小生成树示例,但它不适用于大数据
Trying to use Minimum Spanning Tree example from the book but It doesn't work with large data
注意:这不是我的代码
我正在尝试将数据结构与C++教科书的最小生成树算法一起使用,但如您所见,我制作了一个边缘 [] 边缘数组并注释掉了旧的 edges[] 数组,但看起来它不适用于更大的边缘或其他东西。(顺便说一下,我只是使用字符作为整数)
有谁知道为什么?我没有改变太多,我只是改变了边缘数组。它编译得很好,但如果你运行它,你会看到它不适用于我的数据,但它将适用于原始数据。
数组就在主数组的正上方(最后一件事)
另外,如果您不想打开IDE,这是我在在线IDE上的代码:http://goo.gl/35KMcK
这是代码:
#include <iostream>
using namespace std;
class MSTEdge
{
char src;
char dest;
int weight;
public:
MSTEdge(char s = 0, char d = 0, int w = 0) : src(s), dest(d), weight(w) { }
char& getSrc() { return src; }
char& getDest() { return dest; }
int& getWeight() { return weight; }
int& get() { return getWeight(); }
};
// undirected and weighted graph
class Graph
{
int V, E;
MSTEdge* edge;
int icount;
public:
Graph(int v, int e) : V(v), E(e), icount(0)
{
edge = new MSTEdge[e];
}
int& getVertexAmount() { return V; }
int& getEdgeAmount() { return E; }
MSTEdge*& getEdges() { return edge; }
MSTEdge& operator [](int x) { return edge[x]; }
void insert(MSTEdge& e)
{
edge[icount++] = e;
}
};
// subset for union-find
class subset
{
int parent;
int rank;
public:
subset(int p = 0, int r = 0) : parent(p), rank(r) {}
int& getTheParent() { return parent; }
int& getTheRank() { return rank; }
};
// find set of an element i
int find(subset* subsets, int i)
{
// find root and make root as parent of i (path compression)
if (subsets[i].getTheParent() != i)
subsets[i].getTheParent() = find(subsets, subsets[i].getTheParent());
return subsets[i].getTheParent();
}
// union of two sets of x and y
void Union(subset* subsets, int x, int y)
{
int x_root = find(subsets, x);
int yroot = find(subsets, y);
// Attach smaller rank tree under root of high rank tree
// (Union by Rank)
if (subsets[x_root].getTheRank() < subsets[yroot].getTheRank())
subsets[x_root].getTheParent() = yroot;
else if (subsets[x_root].getTheRank() > subsets[yroot].getTheRank())
subsets[yroot].getTheParent() = x_root;
// If ranks are same, then make one as root and increment its rank by one
else
{
subsets[yroot].getTheParent() = x_root;
subsets[x_root].getTheRank()++;
}
}
template <typename T>
void partition_array(T* arr, int& i, int& j, T pivot)
{
while (i <= j)
{
while (arr[i].get() < pivot.get())
i++;
while (arr[j].get() > pivot.get())
j--;
if (i <= j)
{
T tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
};
}
template <typename T>
void quickSort_array(T* arr, int left, int right)
{
int i = left, j = right;
T pivot = arr[(left + right) / 2];
// partition
partition_array(arr, i, j, pivot);
// recursion
if (left < j)
quickSort_array(arr, left, j);
if (i < right)
quickSort_array(arr, i, right);
}
// The main function to construct MST
void MST(Graph& graph)
{
int V = graph.getVertexAmount();
MSTEdge* result = new MSTEdge[V]; // Tnis will store the resultant MST
int e = 0; // An index variable, used for result[]
int i = 0; // An index variable, used for sorted edges
quickSort_array(graph.getEdges(), 0, graph.getEdgeAmount());
// Allocate memory for creating V ssubsets
subset* subsets = new subset[V];
// Create V subsets with single elements
for (int v = 0; v < V; ++v)
{
subsets[v].getTheParent() = v;
subsets[v].getTheRank() = 0;
}
// Number of edges to be taken is equal to V-1
while (e < V - 1)
{
// Step 2: Pick the smallest edge. And increment the index
// for next iteration
MSTEdge next_edge = graph[i++];
int x = find(subsets, next_edge.getSrc());
int y = find(subsets, next_edge.getDest());
// If including this edge does't cause cycle, include it
// in result and increment the index of result for next edge
if (x != y)
{
result[e++] = next_edge;
Union(subsets, x, y);
}
// Else discard the next_edge
}
// print the contents of result[] to display the built MST
cout << "Following are the edges in the constructed MSTn";
for (i = 0; i < e; ++i)
cout
<< result[i].getSrc()
<< " -- "
<< result[i].getDest()
<< " == "
<< result[i].getWeight()
<< endl;
return;
}
/* weighted graph
10
0-------- 1
| |
6| 5 |15
| |
2 --------3
4
*/
//MSTEdge edges[] = //THIS WORKS
//{
// MSTEdge(0,1,10),
// MSTEdge(0,2,6),
// MSTEdge(0,3,5),
// MSTEdge(1,3,15),
// MSTEdge(2,3,4)
//};
MSTEdge edges[] = // CAUSES PROBLEMS
{
MSTEdge('A','B',5),
MSTEdge('A','C',1),
MSTEdge('B','C',10),
MSTEdge('B','E',13),
MSTEdge('C','D',5),
MSTEdge('D','E',15),
MSTEdge('D','F',10),
MSTEdge('E','F',17)
};
// Driver program to test above functions
int main()
{
int count = sizeof(edges) / sizeof(MSTEdge);
int V = count - 1; // Number of vertices in graph
Graph graph(V, count);
for (int e = 0; e < count; e++)
graph.insert(edges[e]);
MST(graph);
return 1;
}
// Following are the edges in the constructed MST
// 2 -- 3 == 4
// 0 -- 3 == 5
// 0 -- 1 == 10
subsets
数组使用以下代码初始化:
// Create V subsets with single elements
for (int v = 0; v < V; ++v)
{
subsets[v].getTheParent() = v;
subsets[v].getTheRank() = 0;
}
这为您提供了具有从 0 到 V-1 parent
值的子集
然后,代码尝试使用此行查找这些子集
int x = find(subsets, next_edge.getSrc());
但是您的边将源和目标设置为"A"、"B"、"C"等。所以它永远无法在subsets
中找到任何东西.它可能正在访问数组边界之外的subsets
项目并导致未定义的行为。
要修复它,请将edges
数组更改为使用 0、1、2 作为节点 ID(可能是最简单的),或者更改初始化代码subsets
将父级设置为"A"、"B"、"C"等。 注意:可能还有更多地方假定节点 ID 从 0 开始。
相关文章:
- FLTK 2.0构建和演示,适用于VS2019的2011年左右的代码库
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 为什么这适用于 G++ 而不是 CLANG?
- 为什么不区分大小写适用于 std::unordered_set的 std::hash 函数?
- 声明适用于 auto,但不能显式声明类型?
- 什么是通用运行时组件 #ifdef 适用于Windows(UWP)而不是iOS
- Windows 上的 Cmake 不添加共享库路径(适用于 linux)
- Typedef适用于结构,但不适用于枚举,仅适用于C++
- 为什么函数模板不理解 NULL,但适用于 nullptr
- 链接器读取库,但在其中找不到符号?未解析的外部符号,但仅适用于 Win32 而不是 x64
- Netbeans 8.1(适用于 C/C++)找不到我的编译器(gcc-6.0.0 开发版本)
- random_shuffle() 适用于 Windows,但不能在 Linux 上编译
- C++指针到方法模板推导在面向 x86 时不编译,但适用于 x64
- 不在异常中嵌入std::字符串的规则是否仍然适用于move构造函数
- 移动文件夹Windows c++:适用于Vista及以上版本,不包括XP
- 适用于Android的Qt找不到任何兼容的设备答案找到但不知道如何
- 在Windows 7上不起作用,但它适用于Windows 8 dll。
- 可变参数模板转换为 std::function<R(ARGS...)>适用于 GCC 而不是 MSVC2013,为什么?
- C++11 cmath 函数不在 std 命名空间中,适用于 android NDK w/gcc-4.8 或 clang