#ifndef _DIJKSTRA_
#define _DIJKSTRA_
#include <iostream>
using namespace std;
void TestDijstra();
const int MAX_NODE = 1000;
/*
最简单的:用二维数组来记录Graph和weight
斐波那契堆实现:insert,get
1.最普通实现
2.使用二叉堆实现
3.实现fibonacci堆,进而用其实现
*/
// 用二维数组来记录Graph和weight
// graph[i][j] 从i到j是否有路径:如果为0,没有;>0,有!
void Dijstra1(int graph[][MAX_NODE], int size, int start, int *dist, int *prev);
// 从数组中找到最小值的索引,只查询bool值为false的
int FindMinFromArr(int *arr, int size, bool *used);
void Elasped(int graph[][MAX_NODE], int size, int *dist, int *prev, int tmp, bool *used);
// 打印结果:从s->t的路径
void PrintPath(int *prev, int size, int s, int t);
// 用最小堆实现
/*
最小堆实现:用指针实现
指针实现似乎不太方便
之所以不方便是因为parent指针不好定位!!!
*/
struct HeapNode
{
int node;
int dist;
HeapNode *parent;
HeapNode *left;
HeapNode *right;
HeapNode() : node(-1), dist(-1), parent(0), left(0), right(0)
{}
};
void InsertHeapNode(HeapNode *head, HeapNode *node);
HeapNode *DeleteMin(HeapNode *head);
// 用二叉堆实现
void Dijstra2(int graph[][MAX_NODE], int size, int start, int *dist, int *prev);
#endif
#include "2_Dijkstra.h"
void TestDijstra()
{
cout << "Dijstra" << endl;
HeapNode node;
HeapNode *tmp = NULL;
tmp->dist ;
}
void Dijstra1(int graph[][MAX_NODE], int size, int start, int *dist, int *prev)
{
bool *used = new bool[size];
// 初始化
for (int i = 0; i < size; ++i)
{
used[i] = false;
// 32位的最大值
dist[i] = 0x7FFFFFFF;
prev[i] = start;
}
// 首先初始化与start相连的
for (int i = 0; i < size; ++i)
{
// 如果从start到i有通路
if (graph[start][i] > 0)
{
dist[i] = graph[start][i];
// 由于上面已经设置,因此此步可以略去
//prev[i] = start;
}
}
// 由于一共有size个节点,因此要循环size-1次
for (int i = 1; i < size; ++i)
{
int tmp = FindMinFromArr(dist, size, used);
used[tmp] = true;
// 松弛算法
Elasped(graph, size, dist, prev, tmp, used);
}
delete []used;
}
int FindMinFromArr(int *arr, int size, bool *used)
{
int min = 0x7FFFFFFF;
int index = -1;
for (int i = 0; i < size; ++i)
{
if (!used[i] && arr[i] < min)
{
index = i;
min = arr[i];
}
}
return index;
}
void Elasped(int graph[][MAX_NODE], int size, int *dist, int *prev, int tmp, bool *used)
{
for (int i = 0; i < size; ++i)
{
// 如果tmp到i有通路且i没有被遍历过
if (graph[tmp][i] > 0 && !used[i])
{
// 从s到i的距离大于通过tmp到i的距离
if (dist[i] > dist[tmp] + graph[tmp][i])
{
dist[i] = dist[tmp] + graph[tmp][i];
prev[i] = tmp;
}
}
}
}
// 递归实现
void PrintPath(int *prev, int size, int s, int t)
{
if (s == t)
{
return;
}
PrintPath(prev, size, s, prev[t]);
cout << t << " ";
}
void InsertHeapNode(HeapNode *head, HeapNode *node)
{
}
HeapNode *DeleteMin(HeapNode *head)
{
return NULL;
}
void Dijstra2(int graph[][MAX_NODE], int size, int start, int *dist, int *prev)
{
bool *used = new bool[size];
for (int i = 0; i < size; ++i)
{
used[i] = false;
dist[i] = 0x7FFFFFFF;
prev[i] = start;
}
HeapNode *root = NULL;
for (int i = 0; i < size; ++i)
{
// 如果从start到i有通路
if (graph[start][i] > 0)
{
HeapNode *tmp = new HeapNode();
tmp->node = i;
tmp->dist = graph[start][i];
if (!root)
{
root = tmp;
}
else
{
InsertHeapNode(root, tmp);
}
}
}
}