//============================================================================
// Name : ListDijkstra.cpp
// Author : fffff
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================ #include<iostream>
#include<cstdlib>
#include<queue> using namespace std; #define MAXSIZE 100
#define INF (~(0x1<<31)) //最大值 0x7FFFFFFF class ListUDG{
/*
* 内部类
*/
private:
/*
* 邻接表中的边节点
* ivex:下一个节点的编号
* nextEdge:指向下一个边节点的指针
*/
class Enode{
public:
int ivex;
int weight;
Enode *nextEdge;
};
/*
* 邻接表中的顶点节点
* data:顶点节点的数据
* firstEdge:顶点节点的第一条边
*/
class Vnode{
public:
char data;
Enode *firstEdge;
};
private:
int mVexNum;//顶点个数
int mEdgNum;//边的条数
Vnode mVexs[MAXSIZE];
bool visited[MAXSIZE];
public:
ListUDG();
ListUDG(char vexs[],int vlen,char edge[][],int elen,int weigh[]);
~ListUDG();
char rChar();
int getPost(char ch);
int getmVexNum();
int getmEdgNum();
Vnode getVexs(int i){
return mVexs[i];
};
int getWeight(int v,int u);
void print();
void BFS();
void DFS();
void DFSK(int k);
void Dijkstra(ListUDG *listudg,int v,int pre[],int dist[]);
void trace(ListUDG *listudg,int v,int u,int pre[]);
private:
char readChar();
int getPosition(char ch);
void LinkLast(Enode *list,Enode *node);
};
ListUDG::ListUDG(char vexs[],int vlen,char edge[][],int elen,int weigh[]){
/*
* 初始化顶点数与边的条数
*/
mVexNum = vlen;
mEdgNum = elen;
/*
* 初始化邻接表中的顶点节点
*/
for(int i=;i<mVexNum;i++){
mVexs[i].data = vexs[i];
mVexs[i].firstEdge = NULL;
}
/*
* 初始化邻接表中的边节点
*/
for(int i=;i<mEdgNum;i++){
char first = edge[i][];
char second = edge[i][];
int start = getPosition(first);
int end = getPosition(second); Enode *enode1 = new Enode;
enode1->ivex = end;
enode1->weight = weigh[i];
enode1->nextEdge = NULL;
if(mVexs[start].firstEdge==NULL)
mVexs[start].firstEdge = enode1;
else
LinkLast(mVexs[start].firstEdge,enode1); Enode *enode2 = new Enode;
enode2->ivex = start;
enode2->weight = weigh[i];
enode2->nextEdge = NULL;
if(mVexs[end].firstEdge==NULL)
mVexs[end].firstEdge=enode2;
else
LinkLast(mVexs[end].firstEdge,enode2);
}
};
ListUDG::ListUDG(){
/*
* 初始化顶点数与边的条数
*/
cout<<"input num of Vexs and Edges : ";
cin>>mVexNum>>mEdgNum;
/*
* 初始化邻接表中的顶点节点
*/
for(int i=;i<mVexNum;i++){
cout<<"input data of "<<i<<" Vex:";
mVexs[i].data = readChar();
mVexs[i].firstEdge = NULL;
}
/*
* 初始化邻接表中的边节点
*/
for(int i=;i<mEdgNum;i++){
cout<<"input edge("<<i<<"):";
char first = readChar();
char second = readChar();
int start = getPosition(first);
int end = getPosition(second); cout<<"input weight of the edge:";
int weight;
cin>>weight; Enode *enode1 = new Enode;
enode1->ivex = end;
enode1->weight = weight; /********************-----ERROR-----********************
* 两个构造方法都忘掉此句,导致出错,
* 出错地方在调用方法LinkLast的时候无法判断nextEdge是否为空
* 因为nextEdge没有被赋值
*******************************************************/
enode1->nextEdge = NULL;
if(mVexs[start].firstEdge==NULL)
mVexs[start].firstEdge = enode1;
else
LinkLast(mVexs[start].firstEdge,enode1); Enode *enode2 = new Enode;
enode2->ivex = start;
enode2->weight = weight;
enode2->nextEdge = NULL;
if(mVexs[end].firstEdge==NULL)
mVexs[end].firstEdge = enode2;
else
LinkLast(mVexs[end].firstEdge,enode2);
}
};
ListUDG::~ListUDG(){ };
char ListUDG::rChar(){
return readChar();
};
int ListUDG::getPost(char ch){
return getPosition(ch);
};
int ListUDG::getmVexNum(){
return mVexNum;
};
int ListUDG::getmEdgNum(){
return mEdgNum;
};
int ListUDG::getWeight(int v,int u){
Enode *enode;
if(v==u)
return ;
else{
enode = mVexs[v].firstEdge;
while(enode){
if(enode->ivex==u)
return enode->weight;
else
enode = enode->nextEdge;
}
return INF;
}
};
void ListUDG::print(){
cout<<"ListUDG"<<endl;
for(int i=;i<mVexNum;i++){
cout<<i<<" ("<<mVexs[i].data<<"): ";
Enode *p = mVexs[i].firstEdge;
while(p){
cout<<p->ivex<<"("<<mVexs[p->ivex].data<<")["<<p->weight<<"] ";
p = p->nextEdge;
}
cout<<endl;
}
return ;
};
char ListUDG::readChar(){
char cha;
cin>>cha;
while(!((cha>='a'&&cha<='z')||(cha>='A'&&cha<='Z'))){
cin>>cha;
}
return cha;
};
int ListUDG::getPosition(char ch){
for(int i = ;i<mVexNum;i++){
if(mVexs[i].data==ch)
return i;
}
return -;
}
void ListUDG::LinkLast(Enode*list,Enode *node){
Enode *p = list;
while(p->nextEdge)
p = p->nextEdge;
p->nextEdge = node;
return;
};
/*
* Dijkstra 算法----最短路径
*/
void ListUDG::Dijkstra(ListUDG *listudg,int v,int pre[],int dist[]){
bool s[MAXSIZE]; /*
* 第一步:初始化S集合以及距离dist
*/
for(int i=;i<listudg->getmVexNum();i++){
s[i] = false;
dist[i] = listudg->getWeight(v,i);
if(dist[i]==INF)
pre[i] = -;
else
pre[i] = v;
}
s[v] = true;
dist[v] = ;
/*
* 第二步:寻找dist中的最小值加入到S集合中
*/
for(int i=;i<listudg->getmVexNum();i++){
int min = INF;
int u = v;
for(int j=;j<listudg->getmVexNum();j++){
if(s[j]==false&&dist[j]<min){
min = dist[j];
u = j;
}
}
s[u] = true;//将顶点u加入到集合S中
/*
* 第三步:更新dist
*/
for(int j=;j<listudg->mVexNum;j++){
if(s[j]==false&&listudg->getWeight(u,j)<INF){
int newdist = dist[u] + listudg->getWeight(u,j);
if(newdist<dist[j]){
dist[j] = newdist;
pre[j] = u;
}
}
}
}
};
void ListUDG::trace(ListUDG *listudg,int v,int u,int pre[]){
int start = v;
int end = u;
while(start!=end){
cout<<listudg->mVexs[end].data<<"<---";
end = pre[end];
}
cout<<listudg->mVexs[start].data<<endl;
};
/*
* 广度优先搜索邻接表
*/
void ListUDG::BFS(){
for(int i=;i<MAXSIZE;i++)
visited[i] = false;
queue<int>que;
que.push();
visited[] = true;
int out;
Enode *outNext;
while(!que.empty()){
out = que.front();
outNext = mVexs[out].firstEdge;
que.pop();
cout<<mVexs[out].data<<" "; /****************-----ERROR-----*****************
* 此处刚开始将判断条件visited[outNext->ivex]==false
* 写入while循环的判断语句中,导致某一个顶点的边链表没有
* 访问完就结束了循环(可能某边之前已经访问过),丢掉了后面
* 的节点
************************************************/
while(outNext!=NULL){
if(visited[outNext->ivex]==false){
que.push(outNext->ivex);
visited[outNext->ivex] = true;
outNext = outNext->nextEdge;
}else
outNext = outNext->nextEdge;
}
}
cout<<endl;
};
void ListUDG::DFS(){
for(int i=;i<MAXSIZE;i++)
visited[i] = false;
for(int i=;i<mVexNum;i++)
if(visited[i]==false)
DFSK(i);
cout<<endl;
};
void ListUDG::DFSK(int k){
visited[k]=true;
cout<<mVexs[k].data<<" ";
Enode *enode = mVexs[k].firstEdge;
while(enode){
if(visited[enode->ivex]==false){
DFSK(enode->ivex);
enode = enode->nextEdge;
}
else /************-----ERROR-----*************
*开始时候忘掉了写此句,导致顶点的边链表没有访问完
*而到时enode没有向后移动,从而导致循环无法结束,因此
*程序死循环
****************************************/
enode = enode->nextEdge; }
return ;
}
int main(){
char vexs[]={'a','b','c','d','e','f','g'};
char edges[][]={
{'a','b'},
{'a','d'},
{'a','g'},
{'b','f'},
{'c','d'},
{'c','g'},
{'d','f'},
{'e','g'},
{'f','g'}
};
int pre[MAXSIZE];
int dist[MAXSIZE];
int weight[]={,,,,,,,,};
int vlen = sizeof(vexs)/sizeof(vexs[]);
int elen = sizeof(edges)/sizeof(edges[]);
ListUDG *listudg1 = new ListUDG(vexs,vlen,edges,elen,weight);
listudg1->print();
listudg1->BFS();
listudg1->DFS();
listudg1->Dijkstra(listudg1,,pre,dist);
listudg1->trace(listudg1,,,pre);
return ;
} 运行结果如下 ListUDG
(a): (b)[] (d)[] (g)[]
(b): (a)[] (f)[]
(c): (d)[] (g)[]
(d): (a)[] (c)[] (f)[]
(e): (g)[]
(f): (b)[] (d)[] (g)[]
(g): (a)[] (c)[] (e)[] (f)[]
a b d g f c e
a b f d c g e
c<---g<---a

邻接表实现Dijkstra算法以及DFS与BFS算法的更多相关文章

  1. 【数据结构】图的基本操作——图的构造(邻接矩阵,邻接表),遍历(DFS,BFS)

    邻接矩阵实现如下: /* 主题:用邻接矩阵实现 DFS(递归) 与 BFS(非递归) 作者:Laugh 语言:C++ ***************************************** ...

  2. 基于STL优先队列和邻接表的dijkstra算法

    首先说下STL优先队列的局限性,那就是只提供入队.出队.取得队首元素的值的功能,而dijkstra算法的堆优化需要能够随机访问队列中某个节点(来更新源点节点的最短距离). 看似可以用vector配合m ...

  3. dfs和bfs算法

    1. 存储图的方式一般是有两种的:邻接表和邻接矩阵,一般存储链接矩阵的方式是比较简单的,也便于我们去实现这个临接矩阵,他也就是通俗的二维数组,我们平常用到的那种. 2. 这里我们主要记录和讲一下bfs ...

  4. 基本DFS与BFS算法(C++实现)

    样图: DFS:深度优先搜索,是一个不断探查和回溯的过程,每探查一步就将该步访问位置为true,接着在该点所有邻接节点中,找出尚未访问过的一个,将其作为下个探查的目标,接着对这个目标进行相同的操作,直 ...

  5. 图的遍历算法:DFS、BFS

    在图的基本算法中,最初需要接触的就是图的遍历算法,根据访问节点的顺序,可分为深度优先搜索(DFS)和广度优先搜索(BFS). DFS(深度优先搜索)算法 Depth-First-Search 深度优先 ...

  6. 做了一道跑大数据的最短路挂了,基于vector的二维模拟邻接表实现Dijkstra算法(*【模板】)

    代码: #include <stdio.h> #include <string.h> #include <string> #include <vector&g ...

  7. 有向图的邻接矩阵表示法(创建,DFS,BFS)

    package shiyan; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; publi ...

  8. 图论算法之DFS与BFS

    概述(总) DFS是算法中图论部分中最基本的算法之一.对于算法入门者而言,这是一个必须掌握的基本算法.它的算法思想可以运用在很多地方,利用它可以解决很多实际问题,但是深入掌握其原理是我们灵活运用它的关 ...

  9. 数据结构与算法之PHP用邻接表、邻接矩阵实现图的广度优先遍历(BFS)

    一.基本思想 1)从图中的某个顶点V出发访问并记录: 2)依次访问V的所有邻接顶点: 3)分别从这些邻接点出发,依次访问它们的未被访问过的邻接点,直到图中所有已被访问过的顶点的邻接点都被访问到. 4) ...

随机推荐

  1. ASP.NET的SEO--- Global.asax和HttpModule中的RewritePath()方法

    本系列目录 因为在网上搜到了很多这方面的文章,而且UrlRewrite中SEO中的重要性也在逐步下降,所以这一节我就写得简单一些.以下是几个重点: 1.UrlRewrite,顾名思义,只是针对URL进 ...

  2. javascript之值传递与引用传递

    在分析这个问题之前,我们需了解什么是按值传递(call by value),什么是按引用传递(call by reference).在计算机科学里,这个部分叫求值策略(Evaluation Strat ...

  3. AJAX验证用户是否存在

    <html> <head> <title> ajax验证 </title> </head> <body> <input t ...

  4. 九度OJ 1544 数字序列区间最小值

    题目地址:http://ac.jobdu.com/problem.php?pid=1544 题目描述: 给定一个数字序列,查询任意给定区间内数字的最小值. 输入: 输入包含多组测试用例,每组测试用例的 ...

  5. android学习视频分享

    最近整理了大量的安卓开发学习资料,有书籍有视频有代码,老罗的第一季有点老了, 这里就给大家分享下老罗的第二季的视频教程吧,还有源码,初级到高级程序猿都有用. 下载地址:http://51pansou. ...

  6. 使用sqoop将mysql数据导入到hadoop

    hadoop的安装配置这里就不讲了. Sqoop的安装也很简单. 完成sqoop的安装后,可以这样测试是否可以连接到mysql(注意:mysql的jar包要放到 SQOOP_HOME/lib 下): ...

  7. Android计时器TimerTask,Timer,Handler

    Android计时器TimerTask,Timer,若要在TimerTask中更新主线程UI,鉴于Android编程模型不允许在非主线程中更新主线程UI,因此需要结合Android的Handler实现 ...

  8. 【Delphi】从内存(MemoryStream)使用WMP(WindowsMediaPlayer)控件播放视频音频(Play Video with WMP from MemoryStream)

    关键字: MemoryStream.WMP.WindowsMediaPlayer.Play .Load. Delphi.C++.C#.ActiveX控件 作  者: CaiBirdy 问  题:正常使 ...

  9. MIS2000 Lab,我的IT人生与职场--从零开始的前十五年 与 我的微创业

    http://www.dotblogs.com.tw/mis2000lab/archive/2014/09/16/ithome_2014_ironman.aspx [IT邦幫忙]鐵人賽 -- MIS2 ...

  10. 低功耗蓝牙(BLE)透传模块 ——RF-BM-S01(BQB认证)

    本文来源深圳信驰达科技www.szrfstar.com,技术交流群336720020. 低功耗蓝牙(BLE)透传模块 ——RF-BM-S01(BQB认证) 深圳市信驰达科技有限公司 2013年3月18 ...