Dijkstra - 最短路径打印

时间:2017-05-09 22:50:38

标签: c++ algorithm graph shortest-path dijkstra

我对dijkstra打印路径有点问题,它正在处理小图形大小,如10-20等。在100上有问题,因为打印循环进入无限,当我尝试重复方法,VS显示我的exepction throw,堆栈溢出(同样的问题,比如^)。你知道怎么修这个人吗?有我的代码。

#include <stdio.h>
#include <iostream>
#include <limits.h>
#include <conio.h>

using namespace std;



struct graphNode {
    int weight;
    int v;
    graphNode *next;
};

class Graph {


public:
    graphNode *head, *tail;
    int size, vIndex;                  
    int  currentWeight;
    char type;                     

    void addNode(int v_temp, int v_weight) {
        graphNode *temp = new graphNode;
        temp->next = nullptr;

        if (head == nullptr) {
            temp->v = v_temp;
            temp->weight = v_weight;
            head = temp;

        }
        else {
            tail->next = temp;
            temp->v = v_temp;
            temp->weight = v_weight;
        }

        size++;
        tail = temp;
    }




    // GET SET METHODS


    char returnType() {
        return type;
    }

    int returnCurrentWeight() {
        return currentWeight;
    }

    void setCurrentWeight(int weight) {

        currentWeight = weight;
    }

    void setVIndex(int temp) {

        vIndex = temp;
    }

    void setType(char type_temp) {
        type = type_temp;
    }

    // Constructor

    Graph() {
        head = nullptr;
        tail = nullptr;
        vIndex = 0;
        size = 0;
        currentWeight = 0;
    }


};


struct heapNode {
    int v;
    int distance;


};



class Heap {
private:
    Graph *graphArray;
    heapNode **heapArray;
    heapNode *root;
    int vNumber, size;
    int *position, *parent;

public:
    heapNode *addEdge(int temp_v, int temp_distance) {

        heapNode *temp = new heapNode;
        temp->v = temp_v;
        temp->distance = temp_distance;

        return temp;
    }


    graphNode *returnVertexHead(int i) {
        return graphArray[i].head;
    }

    char returnType(int i) {
        return graphArray[i].returnType();
    }

    int *returnParent() {
        return parent;
    }

    int returnWeight(int i) {
        return graphArray[i].returnCurrentWeight();
    }

    void setWeight(int i, int weight) {
        graphArray[i].setCurrentWeight(weight);
    }

    bool isInHeap(int temp_v) {
        if (position[temp_v] < vNumber) return true;
        return false;
    }

    bool isEmpty(int vNumber) {
        if (vNumber == 0) return true;

        return false;
    }

    void decrestDistans(int temp_v, int temp_distance) {
        int index = position[temp_v];
        heapNode *temp;

        heapArray[index]->distance = temp_distance;


        while (index && (heapArray[index]->distance < heapArray[(index - 1) / 2]->distance)) {

            position[heapArray[index]->v] = (index - 1) / 2;
            position[heapArray[(index - 1) / 2]->v] = index;

            temp = heapArray[index];


            heapArray[index] = heapArray[(index - 1) / 2];
            heapArray[(index - 1) / 2] = temp;

            index = (index - 1) / 2;
        }
    }


    heapNode *removeMin() {

        if (vNumber == 0) return nullptr;
        root = heapArray[0];
        heapArray[0] = heapArray[vNumber - 1];


        position[root->v] = vNumber - 1;
        position[heapArray[vNumber - 1]->v] = 0;

        --vNumber;

        repairHeapDown(0);
        return root;
    }

    void repairHeapDown(int index) {
        heapNode *temp;
        int parentIndex = index;
        int left = index * 2 + 1;
        int right = index * 2 + 2;

        if (left <= vNumber && heapArray[parentIndex]->distance > heapArray[left]->distance) parentIndex = left;
        if (right <= vNumber && heapArray[parentIndex]->distance > heapArray[right]->distance) parentIndex = right;
        if (index != parentIndex) {

            position[heapArray[parentIndex]->v] = index;
            position[heapArray[index]->v] = parentIndex;

            temp = heapArray[index];
            heapArray[index] = heapArray[parentIndex];
            heapArray[parentIndex] = temp;


            repairHeapDown(index);
        }
    }






    int dijkstra(int start, int target) {

        int *distance = new int[vNumber];
        int i, v, weight;
        graphNode *current_graph;
        heapNode *current_heap;

        for (int i = 0; i < vNumber; i++)
        {
            distance[i] = INT_MAX;
            heapArray[i] = addEdge(i, distance[i]);
            position[i] = i;
            parent[i] = 0;

        }

        parent[start] = -1;
        heapArray[start] = addEdge(start, distance[start]);
        position[start] = start;
        distance[start] = 0;

        decrestDistans(start, distance[start]);


        while (!isEmpty(vNumber)) {


            current_heap = removeMin();

            i = current_heap->v;

            if (i == target) {

                int temp = 2 * distance[target];    

                parent[v] = i;
                delete[] position;
                delete[] distance;
                delete[] heapArray;

                return temp;
            }

            current_graph = returnVertexHead(i);


            while (current_graph != nullptr) {

                v = current_graph->v;

                weight = current_graph->weight + returnWeight(i) + distance[i];

                if (weight < distance[v]) {
                    distance[v] = weight;
                    decrestDistans(v, distance[v]);
                    parent[v] = i;
                }

                current_graph = current_graph->next;
            }
        }

        return 0;
    }



    Heap(Graph *table, int temp_vNumber) {
        vNumber = temp_vNumber;
        size = temp_vNumber;


        root = nullptr;

        heapArray = new heapNode*[size];
        position = new int[size];
        parent = new int[size];


        graphArray = table;
    }

    ~Heap() {
        delete[] parent;

    }
};



void printPath(int *parent, int start,  int target)
{

    int current = target;

    while (current != start) {
        cout << current << " ";
        current = parent[current];
    }

    cout << current << " ";
}


int main() {
    int n, time_knight, patch_number, temp_v, temp_weight, i,
        home_index, gral_index, ni_index, ni_weight, krzak_index;
    char type;

    gral_index = home_index = ni_index = krzak_index = 0;
    i = 0;


    cin >> n >> time_knight;
    Graph *table = new Graph[n];

    while (1) {
        cin >> type;

        table[i].setType(type);

        if (type == '5') gral_index = i;
        if (type == '4') home_index = i;
        if (type == '3') ni_index = i;
        if (type == '2') table[i].setCurrentWeight(time_knight);
        if (type == '1') krzak_index = i;

        cin >> patch_number;
        for (int j = 0; j < patch_number; j++)
        {
            cin >> temp_v >> temp_weight;
            table[i].setVIndex(i);
            table[i].addNode(temp_v, temp_weight);

        }
        i++;

        if (i == n) break;
    }

    Heap *object = new Heap(table, n);
    Heap *object2 = new Heap(table, n);
    ni_weight = object->dijkstra(ni_index, krzak_index);
    table[ni_index].setCurrentWeight(ni_weight);

    cout << endl << endl << endl;



    printPath(object->returnParent(), ni_index, krzak_index);

    cout << endl << endl << endl;

    object2->dijkstra(home_index, gral_index);


    printPath(object2->returnParent(), home_index, gral_index);






    _getch();

    return 0;
}

0 个答案:

没有答案