(二)Dijkstra算法

#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);
			}			
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值