我是code::blocks
的新手以及它是如何工作的但是我正在将它用于uni的任务,基本上,它使用ADT和邻接列表实现dijkstra的算法,代码可以正常工作,我得到一个输出但我收到了错误
处理返回-1073741819(0xC0000005)
最小堆的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "graph.h"
#include "MinHeap.h"
#include "dynamicarraylist.h"
#include "singlelinkedlist.h"
#define CHAR_MAX 50
#define INFINITY 9999
///constructor function for the total heap, taking the capacity of the heap
///as an argument and returning the MinHeap struct
struct MinHeap* HeapConstructor(int V)
{
//create and allocate memory for a new heap struct
struct MinHeap* minHeap;
minHeap = malloc(sizeof(struct MinHeap));
//copy over the value of capacity and set numentities to 0
minHeap->numentities = 0;
//assign memory for the position pointer and for the node pointer
minHeap->Node = malloc(V * sizeof(struct MinHeapNode));
return minHeap;
}
struct MinHeapNode* HeapNodeConstructor(int distance,char* city)
{
struct MinHeapNode* minHeapNode;
minHeapNode = malloc(sizeof(struct MinHeapNode));
minHeapNode->distance = distance;
strcpy(minHeapNode->city,city);
return minHeapNode;
}
struct ShortestPath* ShortestPathConstructor()
{
//allocate enough memory for the struct
struct ShortestPath* shortestPath;
shortestPath = malloc(sizeof(struct ShortestPath));
//initialize with sensible values
shortestPath->distance = malloc(sizeof(int));
shortestPath->parent = NULL;
shortestPath->size = 0;
return shortestPath;
}
/// function to swap two nodes within a minimum heap, this allows us to sort
/// the heap, this is based on code found on stack overflow for swapping
/// two pointers found here: https://stackoverflow.com/questions/8403447/swapping-pointers-in-c-char-int
/// look at swap5 function of top answer
void NodeSwap(struct MinHeapNode** a, struct MinHeapNode** b)
{
//create a temporary node to copy the value of a across to
//using pointers so we dont have to return various structs
struct MinHeapNode* temp;
temp = *a;
*a = *b;
*b = temp;
}
///function to heapify a min Heap and update position of all nodes within heap
///this is required for updating distances from vertex when carrying out dijkstra's algorithm
/// code for parts of the heapify function is based on psuedo code from the wikipedia article about
/// binary heaps found at: https://en.wikipedia.org/wiki/Binary_heap
void minHeapify(struct MinHeap* minHeap, int index)
{
int smallest, left, right;
smallest = index;
left = (index * 2);
right = (index * 2) + 1;
//if we arent at the end of the heap and the left node is smaller than the node above it
if(left <= minHeap->numentities && minHeap->Node[left]->distance < minHeap->Node[smallest]->distance)
{
//smallest becomes the left child node of the heap
smallest = left;
}
// exact same procedure but they must be 2 separate if statements so that the function compares both both numbers
// in all cases
if(right <= minHeap->numentities && minHeap->Node[right]->distance < minHeap->Node[smallest]->distance)
{
smallest = right;
}
//if the smallest node is different from before starting the function then the heap is not yet heapified
if(smallest != index)
{
//swap nodes
NodeSwap(&minHeap->Node[smallest],&minHeap->Node[index]);
//recursive function so minHeapify is carried out within the function
minHeapify(minHeap,smallest);
}
}
/// simple function to check whether the heap is empty or not
/// so the function performing dijkstra's algorithm knows when to finish
/// takes the minHeap as parameters returning 0 if heap is empty and 1 if it isn't
int HeapIsEmpty(struct MinHeap* minHeap)
{
if(minHeap->numentities == 0)
{
return 0;
}
return 1;
}
///Builds our minimum heap using the graph and assigns the distances as infinite or
///0 for the source node then it heapifies until heap property is achieved
struct ShortestPath* BuildMinHeap(struct MinHeap* minHeap, struct List* graph, char* srccity,int V)
{
struct ShortestPath* shortestpath = ShortestPathConstructor();
int i;
//for total size of the minHeap
for(i = 0; i <= V; i++)
{
//if the source city and the city we're currently at are 0
//distance from source is 0
if(strcmp(srccity,graph->vertices[i].cityname) == 0)
{
minHeap->Node[minHeap->numentities + 1] = HeapNodeConstructor(0,srccity);
shortestpath[shortestpath->size + 1].distance = 0;
strcpy(shortestpath[shortestpath->size + 1].city,srccity);
}
//otherwise the distance is infinite
else
{
minHeap->Node[minHeap->numentities + 1] = HeapNodeConstructor(INFINITY,graph->vertices[i].cityname);
shortestpath[shortestpath->size + 1].distance = INFINITY;
strcpy(shortestpath[shortestpath->size + 1].city,graph->vertices[i].cityname);
}
shortestpath->size++;
minHeap->numentities++;
}
//moves through the heap making sure heap property is satisfied
for(i = minHeap->numentities / 2; i > 0; i--)
{
minHeapify(minHeap,i);
}
return shortestpath;
}
///takes out and returns the minimum node from a heap given as an input
struct MinHeapNode* removeMin(struct MinHeap* minHeap)
{
if(minHeap->numentities != 0)
{
//remove the root node of the minimum heap and store it
struct MinHeapNode* root = minHeap->Node[1];
//move the last element of the heap to the top
minHeap->Node[1] = minHeap->Node[(minHeap->numentities) - 1];
minHeap->numentities--;
minHeapify(minHeap,1);
return root;
}
else
{
printf("\nheap is empty \n");
}
}
///search through the heap for given city name returning the index
///utilises a linear search algorithm
int HeapSearch(struct MinHeap* minHeap,char* cityname)
{
int i;
for(i = 1; i <= minHeap->numentities; i++)
{
if(strcmp(minHeap->Node[i]->city,cityname) == 0)
{
return i;
}
}
return -1;
}
/// decreases key(value) stored within the node from what we defined infinity as being to the shortest currently available path from our source node
/// to the current node
void DecreaseKey(struct MinHeap* minHeap,int x,int newdistance)
{
//find a return the index of our required city to decrease the key of
int i = x;
//compares new distance with currently stored distance and if bigger than the other function stops
if(newdistance > minHeap->Node[i]->distance)
{
return;
}
else
{
//move to index node and update value of distance with distance
minHeap->Node[i]->distance = newdistance;
}
//travel up tree until it is heapified by comparing the index node with its parent node
while(minHeap->Node[i]->distance < minHeap->Node[i/2]->distance && i > 1)
{
//swap node with parent node
NodeSwap(&minHeap->Node[i],&minHeap->Node[i/2]);
//move to parent node
i = i/2;
}
}
void levelorderTraversal(struct MinHeap* minHeap)
{
int i ;
for(i = 1; i < minHeap->numentities; i++)
{
printf("\n %s %d ",minHeap->Node[i]->city, minHeap->Node[i]->distance);
}
}
void shortestPathDisplay(struct ShortestPath* shortestPath)
{
int i;
printf("City Distance From Source");
for(i = 1; i < shortestPath->size;i++)
{
printf("\n%s \t\t %d",shortestPath[i].city,shortestPath[i].distance);
}
}
///search the array list and return index of that search or a -1 if failure
///very important function used in AddEdge function, takes a List struct and a cityname
///as arguments
int ShortestPathSearch(struct ShortestPath* shortestPath, char* cityname)
{
int i;
//seaches from beginning to end of arraylist
for(i = 1 ; i <= shortestPath->size; i++)
{
//strcmp() function compares two input strings, if they are the same it returns a 0
if(strcmp(shortestPath[i].city,cityname) == 0)
{
// we want the index this vertex was found at
return i;
}
}
//if failure return -1
return -1;
}
void dijkstra(struct List* graph,char* startcity)
{
//two intermediate integer variables to find distance at various vertices to get minimum weight overall
int V = graph->numcities;
int added_distance;
struct MinHeap* minHeap = HeapConstructor(V);
struct ShortestPath* shortestPath = ShortestPathConstructor();
//builds our minimum heap and heapifies it
shortestPath = BuildMinHeap(minHeap,graph,startcity,V);
///shortestPathDisplay(shortestPath,V);
///levelorderTraversal(minHeap);
while(minHeap->Node != NULL)
{
levelorderTraversal(minHeap);
//extract shortest distance in heap
struct MinHeapNode* shortestNode = removeMin(minHeap);
printf("removed node is %s distance %d \n",shortestNode->city,shortestNode->distance);
//searches for removed city within index and adds the current distance associated with this
//city
int z = ShortestPathSearch(shortestPath,shortestNode->city);
added_distance = shortestPath[z].distance;
printf("current dist from source: %d \n",added_distance);
//searches for the index of the removed city within our adjacency list and stores it
int u = ArrayListSearch(graph,shortestNode->city);
//assigns a new struct of linkedNode type for traversing through adjacenct nodes
struct linkedNode* adjListTraverse = graph->vertices[u].linkedList->head;
//while not at end of list
while(adjListTraverse != NULL)
{
printf("city: %s distance: %d \n",adjListTraverse->cityname,adjListTraverse->weight);
//looks for the new adjacenct city within the heap and our output array
int v = ShortestPathSearch(shortestPath,adjListTraverse->cityname);
printf("v = %d \n",v);
int x = HeapSearch(minHeap,adjListTraverse->cityname);
printf("x = %d \n",x);
//if it is in the array and the minHeap and the final distance is not finalised
//if x = -1 city is not in heap anymore and can be skipped entirely
if(adjListTraverse->weight + added_distance < shortestPath[v].distance)
{
shortestPath[v].distance = adjListTraverse->weight + added_distance;
//update with new distances
DecreaseKey(minHeap,x,shortestPath[v].distance);
}
adjListTraverse = adjListTraverse->next;
}
shortestPathDisplay(shortestPath);
printf("\n");
}
}
对不起,代码非常长,我一直试图找到问题的原因,我想这可能是因为没有分配内存的指针,但我找不到像这样的指针