我将是第一个承认我不太了解C或C ++的人,所以我认为我做到这一点的事实令人惊讶。我一直在趴在桌子上,所以我希望有人愿意帮助我。这是一个班级项目,我认为我完成了大部分工作,但我需要做一些修改,现在我遇到了问题。该项目是在C ++中实现图形,然后在该结构上运行最小生成树算法。这是我到目前为止的代码(对不起它有点长,但我不知道如何呈现它)。通过我当前拥有代码的方式,运行起来,我得到了我期望的结果。现在我需要修改代码以从文本文件中读取。
如果我取消注释// ifstream行,程序会编译并立即崩溃。因为我得到的结果我希望我相当确定代码是正确的但我已经改变了一些事情并改变了一些事情,同时试图弄清楚发生了什么。我没有收到任何编译错误,因此这使得跟踪问题非常困难。我可能的猜测是,这是明显的,因为我没有经验,我没有看到。
非常感谢任何帮助。
的main.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "heap.cpp"
#include "disjointset.cpp"
#include "graph.cpp"
#include <fstream>
using namespace std;
int main()
{
GRAPH* myGraph;
HEAP* myHeap;
DJS* myDJS;
EDGE tempE;
//ifstream inputFile("input.txt");
myDJS = initializeset(6);
myGraph->nV = myDJS;
myHeap = Initialize(8);
myGraph->nE = myHeap; //initialize the heap to size 0
myGraph->nV = initializeset(6);
makeedge(&tempE,1,2,10);
Insert(myGraph->nE,tempE,0);
makeedge(&tempE,1,3,7);
Insert(myGraph->nE,tempE,0);
makeedge(&tempE,2,3,9);
Insert(myGraph->nE,tempE,0);
makeedge(&tempE,2,4,2);
Insert(myGraph->nE,tempE,0);
makeedge(&tempE,3,5,8);
Insert(myGraph->nE,tempE,0);
makeedge(&tempE,4,5,3);
Insert(myGraph->nE,tempE,0);
makeedge(&tempE,4,6,5);
Insert(myGraph->nE,tempE,0);
makeedge(&tempE,5,6,4);
Insert(myGraph->nE,tempE,0);
printset(myGraph->nV);
printHeap(myGraph->nE);
MST_Kruskal(myGraph, 2);
return 0;
}
heap.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "heap.h"
#include <cmath>
#include <math.h>
using namespace std;
HEAP* Initialize(int n)
{
HEAP* heap = new HEAP();
heap->capacity = n;//capacity = n
heap->size = 0;//initial size = 0
delete[] heap->H;
heap->H = new EDGE[n+1];//new array of EDGEs, size n+1
return heap;
}
void BuildHeap(HEAP* heap,int A[],int length)
{
if(length>heap->capacity+1) //determine if heap needs to expand
{
int inc = ceil((log(length)/log(2)) - (log(heap->capacity)/log(2))); //how many orders of 2 does the heap need to expand by
for(int i=0;i<inc;i++) //increase the heap inc number of times
{
IncreaseHeap(heap);
}
}
for(int ix=1;ix<=length;ix++)
{
heap->H[ix].key = A[ix];//copy values of the arrary to the key values of the heap
}
heap->size = length-1; //set the size of the heap
for(int j=(length/2);j>=1;j--)
heapify(heap,j); //heapify the heap
}
void Insert(HEAP* heap,EDGE k,int flag)
{
if(heap->size==heap->capacity) //determine if the heap needs to expand
{
IncreaseHeap(heap);
}
if(flag==1)
printHeap(heap);
heap->H[heap->size+1] = k;//add the new element
heap->size = heap->size + 1;//increase the size
if(heap->size>1)//if size is 0 then first added element does not need heapify
{
heapifyAdd(heap,0);
}
cout << "The item has been added to the heap." << endl;
if(flag==1)
printHeap(heap);
}
void IncreaseHeap(HEAP* heap)
{
int newHeapCap;
newHeapCap = pow(2,(log(heap->capacity) / log(2))+1)+1; //increase the size of the heap as a power of 2
EDGE* newHeapArray = new EDGE[newHeapCap]; //create a new array
for(int ix=1;ix<=heap->size;ix++)
{
newHeapArray[ix] = heap->H[ix]; //copy the elements of the heap array to the new array
}
delete[] heap->H; //release memory used by previous array
heap->H = newHeapArray; //point H to newHeapArray
heap->capacity = newHeapCap-1; //set the capacity to the new heap capacity
cout << "The new heap capacity is " << newHeapCap-1 << endl;
}
EDGE DeleteMin(HEAP* heap,int flag)
{
EDGE min; //element of the smallest node
if(heap->size==0)
{
cout << "The heap is already empty!" << endl;
}
else
{
if(flag==1)
printHeap(heap);
min = heap->H[1]; //min is the root node
heap->H[1] = heap->H[heap->size]; //set the root = the last element of the heap
heap->size = heap->size - 1;//decrement the heap size
if(heap->size>0)
heapify(heap,1); //heapify the whole tree
if(flag==1)
printHeap(heap);
}
return min;
}
void heapify(HEAP* heap,int ix)
{
EDGE edge; //edge placeholder
int left = ix * 2; //index of the left node
int right = ix * 2 + 1; //index of the right node
int smallest = ix; //index of the smallest node
if(left <= heap->size && heap->H[left].key < heap->H[ix].key)
{
smallest = left; //the smallest element is the left node
}
if(right <= heap->size && heap->H[right].key < heap->H[smallest].key)
{
smallest = right; //the smallest element is the right node
}
if(smallest!=ix) //swap the elements
{
edge = heap->H[ix];
heap->H[ix] = heap->H[smallest];
heap->H[smallest] = edge;
heapify(heap,smallest);
}
}
void heapifyAdd(HEAP* heap,int ix)
{
EDGE e;
int next;
if(ix==0)
next = heap->size;
else
next = ix;
e = heap->H[next];
while(next!=1 && heap->H[(next)/2].key > e.key)
{
heap->H[next] = heap->H[(next)/2];
next = (next)/2;
}
heap->H[next] = e;
}
void DecreaseKey(HEAP* heap,int index,int value,int flag)
{
if(value>heap->H[index].key)
{
cout << "ERROR: new key is greater than current key." << endl;
}
else
{
if(flag==1)
printHeap(heap);
heap->H[index].key = value; //decrease the node to the value
heapify(heap,index/2); //heapify from the parent node
if(flag==1)
printHeap(heap);
}
}
void printHeap(HEAP* heap)
{
int ix = 1;
//cout << "Capacity: ";
//cout << heap->capacity << endl;
//cout << "Size: ";
//cout << heap->size << endl;
cout << "Heap Structure: " << endl;
while(ix<=heap->capacity && ix<=heap->size) //loop through the heap array
{
cout << heap->H[ix].v1 << ", " << heap->H[ix].v2 << ", " <<heap->H[ix].key << endl;
ix++;
}
}
void makeedge(EDGE* tempE, int v1, int v2, int cost)
{
tempE->v1 = v1;
tempE->v2 = v2;
tempE->key = cost;
tempE->tflag = 0;
}
disjointset.cpp
#include <iostream>
#include "disjointset.h"
using namespace std;
DJS* initializeset(int ix)
{
DJS* tempDJS = new DJS();
tempDJS->Arr = new int[ix+1]; //array of all zeros
for(int i=0;i<=ix+1;i++)
{
tempDJS->Arr[i] = 0;
}
tempDJS->setSize = ix;
return tempDJS;
}
void makeset(DJS* djs, int ix)
{
if(ix == djs->setSize+1)
{
int* tempArr = new int[ix+1];
for(int i=0;i<=ix;i++)
{
tempArr[i] = djs->Arr[i];
}
tempArr[ix]=0;
djs->Arr = tempArr;
djs->setSize++;
}
}
void link(DJS* djs, int x, int y)
{
if(-(djs->Arr[x]) > -(djs->Arr[y]))
{
djs->Arr[y] = x;
}
else
{
if(-(djs->Arr[x]) == -(djs->Arr[y]))
{
djs->Arr[y]=djs->Arr[y]-1;
}
djs->Arr[x] = y;
}
}
int findset(DJS* djs, int ix)
//findset with path compression
{
if(djs->Arr[ix] <= 0)
{
return ix;
}
else
{
djs->Arr[ix]=findset(djs,djs->Arr[ix]);
return djs->Arr[ix];
}
}
void union_nodes(DJS* djs, int ixX, int ixY)
{
link(djs,findset(djs,ixX),findset(djs,ixY));
}
void printset(DJS* djs)
{
cout << "Set Structure:" << endl;
//cout << "The size of the djs is " << djs->setSize << endl;
for(int ix=1;ix<=djs->setSize;ix++)
{
cout << djs->Arr[ix] << endl;
}
}
graph.cpp
#include <iostream>
#include "disjointset.h"
#include "heap.h"
#include "graph.h"
void MST_Kruskal(GRAPH* graph, int k)
{
int ix = graph->nV->setSize - k;
EDGE tempE;
for(int i=0;i<=ix;i++)
{
tempE = DeleteMin(graph->nE,0);
printHeap(graph->nE);
if(findset(graph->nV,tempE.v1)!=findset(graph->nV,tempE.v2))
{
cout << "Selecting edge (" << tempE.v1 << ", " << tempE.v2 << ", " << tempE.key <<")" << endl;
union_nodes(graph->nV,tempE.v1,tempE.v2);
printset(graph->nV);
}
}
}
heap.h
#ifndef LIST_H_
#define LIST_H_
struct EDGE
{
int v1; //vertex 1
int v2; //vertex 2
int key; //cost leaving this so that all the other code does not have to change
int tflag; //an indicator to determine if the edge is in the tree
};
struct HEAP
{
int capacity;
int size;
EDGE* H;
};
HEAP* Initialize(int n);
void BuildHeap(HEAP* heap,int A[],int length);
void IncreaseHeap(HEAP* heap);
void Insert(HEAP* heap,EDGE k,int flag);
EDGE DeleteMin(HEAP* heap,int flag);
void heapify(HEAP* heap,int ix);
void heapifyAdd(HEAP* heap,int ix);
void DecreaseKey(HEAP* heap,int index,int value,int flag);
void printHeap(HEAP* heap);
#endif
disjointset.h
#ifndef LIST_D_
#define LIST_D_
struct DJS
{
int* Arr; //array
int setSize; //size of the set array
};
DJS* initializeset(int ix);
void makeset(DJS* djs, int ix);
void link(DJS* djs, int x, int y);
int findset(DJS* djs, int ix);
void union_nodes(DJS* djs, int ixX, int ixY);
void printset(DJS* djs);
#endif
graph.h
#ifndef LIST_G_
#define LIST_G_
struct GRAPH
{
DJS* nV; //vertices
HEAP* nE; //Edges
};
#endif
答案 0 :(得分:0)
您将GRAPH *myGraph;
声明为指针,然后取消引用myGraph
而不进行初始化。
将myGraph
声明为指针而不是实例:GRAPH myGraph;
并将所有myGraph->
替换为myGraph.
E.g。将Insert(myGraph->nE, tempE, 0);
替换为Insert(myGraph.nE, tempE, 0);
并将MST_Kruskal(myGraph, 2);
替换为MST_Kruskal(&myGraph, 2);