导航:首页 > 源码编译 > 有向图转树算法

有向图转树算法

发布时间:2022-11-20 10:25:48

A. 有向图的最小生成树该怎么求

蛋疼的软件,蛋疼的线性表、栈、队列、数组、树、图…

B. 数据结构,一个有向图及其生成森林

将形成回路的边去掉,然后树转森林,树和图的区别,就是没有回路。比如你这个图中,把fb和ea,cb,de去掉,直接就变成森林了,很简单。

C. 对给定的有向图G及顶点v0,设计算法以判断G是否是一棵以v0为根的有向树。若是有向树返回TRUE否则返回FALS

直接从v0开始BFS,如果搜到环或者没有搜完整个图就是FALSE啊

D. 数据结构图的有向树的问题

那个有向树说的是左边有向图在右边的生成森林的各棵树

E. 生成树的标准有哪些各有什么异同

一 区别

最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径。

最短路径是从一点出发,到达目的地的路径最小。

二 实现方法

  1. 最小生成树

  2. 最小生成树有两种算法来得到:Prims算法和Kruskal算法。

  3. Kruskal算法:根据边的加权值以递增的方式,一次找出加权值最低的边来构建最小生成树,而且规定:每次添加的边不能造成生成树有回路,知道找到N-1个边为止。

  4. Prims算法:以每次加入一个的临界边来建立最小生成树,直到找到N-1个边为止。其规则为:以开始时生成树的集合(集合U)为起始的定点,然后找出与生成树集合邻接的边(集合V)中,加权值最小的边来建立生成树,为了确定新加入的边不会造成回路,所以每一个新加入的边,只允许有一个顶点在生成树集合中,重复执行此步骤,直到找到N-1个边为止。

  5. 2 最短路径

算法描述

(这里描述的是从节点1开始到各点的dijkstra算法,其中Wa->b表示a->b的边的权值,d(i)即为最短路径值)

1. 置集合S={2,3,n}, 数组d(1)=0, d(i)=W1->i(1,i之间存在边) or +无穷大(1.i之间不存在边)

2. 在S中,令d(j)=min{d(i),i属于S},令S=S-{j},若S为空集则算法结束,否则转3

3. 对全部i属于S,如果存在边j->i,那么置d(i)=min{d(i), d(j)+Wj->i},转2


Dijkstra算法思想为:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将 加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

算法具体步骤

(1)初始时,S只包含源点,即S=,v的距离为0。U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边)或 ∞(若u不是v的出边邻接点)。

(2)从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。

(3)以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u(u U)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值为顶点k的距离加上边上的权。

(4)重复步骤(2)和(3)直到所有顶点都包含在S中。

复杂度分析

Dijkstra 算法的时间复杂度为O(n^2)空间复杂度取决于存储方式,邻接矩阵为O(n^2)

F. 树和有向图是什么关系呢

阅读关于Prim算法和Kruskal算法的说明,这两个算法就是用来构造最小生成树的,对于有向图和无向图均可,并不是说有向图要像无向图那样有环才可以有生成树

G. 数据结构图的有向树的问题

第一句话:比如这个有向图可以是这样的
A--->B---->C---->D
在这个有向图中,A的入度为0 其余各点B、C、D均为1
第二句话:他都是树了,他的入度一定是1啊。
所谓树:它具有以下的特点:
1、每个节点有零个或多个子节点;
2、没有父节点的节点称为根节点;
3、每一个非根节点有且只有一个父节点;
4、除了根节点外,每个子节点可以分为多个不相交的子树;(以上特点摘自网络)
你看第3点,只有一个父节点的意思,就是说非根节点的入度只可能为1,如果他入度不是1
他就不是一棵树。
你体会一下。

H. 已知一个有向图如图,请分别写出从顶点a出发进行深度优先遍历和广度优先遍历所得到的顶点序列及生成树。

一、深度生成树:abdcefigh,如下图所示:


相关特点:

(1)生成树协议提供一种控制环路的方法。采用这种方法,在连接发生问题的时候,你控制的以太网能够绕过出现故障的连接。

(2)生成树中的根桥是一个逻辑的中心,并且监视整个网络的通信。最好不要依靠设备的自动选择去挑选哪一个网桥会成为根桥。

(3)生成树协议重新计算是繁冗的。恰当地设置主机连接端口(这样就不会引起重新计算),推荐使用快速生成树协议。

(4)生成树协议可以有效的抑制广播风暴。开启生成树协议后抑制广播风暴,网络将会更加稳定,可靠性、安全性会大大增强。

I. 图的所有生成树的算法

边构成,并包含G的所有顶点的树称为G的生成树(G连通).
加权无向图G的生成树的代价是该生成树的所有边的代码(权)的和.
最小代价生成树是其所有生成树中代价最小的生成树.

参考代码:
(仅为主程序,更多代码在

解压密码: )
#include "Sets.h"
#include "themap.h"
#include "windows.h"
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

/*
功能:
演示Kruskal算法和Prim算法
集合的并,元素查找的操作及应用
说明:
代码均在vc++6.0环境下编译均通过
在非VC++6.0环境下编译请去掉头文件 windows.h 和函数 end()
如果NULL未定义请自定义
#define NULL 0 或
#define NULL ((void*)0)
作者:
hacker
时间:
2007.2.3
*/

const VSIZE = 7;//7个顶点
const INFINITY = 10000;//10000作为无穷大来处理

void LoadData(int cost[][VSIZE+1], Edge edge[]);
void end();

/*
函数名:
Kruskal 和 Prim
参数:
边,代价,边数,顶点数,最小代价生成树的顶点
返回值:
返回值为-1,不存在最小代价生成树
返回值大于0时为最小代价生成树的代价
最小代价生成树的边在vector<Edge>& t
*/
int Kruskal(Edge edge[], int cost[][VSIZE+1], int esize, int vsize, vector<Edge>& t);
int Prim (Edge edge[], int cost[][VSIZE+1], int esize, int vsize, vector<Edge>& t);

int main()
{
int cost[VSIZE+1][VSIZE+1];//0不用
Edge edge[9];//9条边
vector<Edge> t;//用来存储最小代价生成树的顶点
int mincost;//最小代价

LoadData(cost, edge);

if ( (mincost = Kruskal(edge, cost, 9, VSIZE, t))!=-1)
{
cout<<"最小代价是:"<<mincost<<endl<<"边是:";
for (int i = 0;i<t.size();i++)
cout<<t[i];
cout<<endl;
}

t.clear();
if ( (mincost = Prim(edge, cost, 9, VSIZE, t))!=-1)
{
cout<<"最小代价是:"<<mincost<<endl<<"边是:";
for (int i = 0;i<t.size();i++)
cout<<t[i];
cout<<endl;
}

end();
return 1;
}

void LoadData(int cost[][VSIZE+1], Edge edge[])
{
edge[0].u = 1; edge[0].v = 2; edge[0].weight = 28;
edge[1].u = 1; edge[1].v = 6; edge[1].weight = 10;
edge[2].u = 2; edge[2].v = 3; edge[2].weight = 16;
edge[3].u = 2; edge[3].v = 7; edge[3].weight = 14;
edge[4].u = 3; edge[4].v = 4; edge[4].weight = 12;
edge[5].u = 4; edge[5].v = 5; edge[5].weight = 22;
edge[6].u = 4; edge[6].v = 7; edge[6].weight = 18;
edge[7].u = 5; edge[7].v = 6; edge[7].weight = 25;
edge[8].u = 5; edge[8].v = 7; edge[8].weight = 24;

for (int i=1;i<=7;i++)
for (int j=1;j<=i;j++)
cost[i][j] = cost[j][i] = INFINITY;
for (i=0;i<9;i++)
cost[edge[i].u][edge[i].v] =
cost[edge[i].v][edge[i].u] = edge[i].weight;
}

int Kruskal(Edge edge[], int cost[][VSIZE+1], int esize, int vsize, vector<Edge>& t)
{
Sets s(esize);
priority_queue<Edge, vector<Edge>, EdgeGreater> pq;
int mincost = 0;

for (int i = 0;i<esize;i++)
//把所有的边放入优先队列
pq.push(edge[i]);

i = 0;
while (i<vsize-1 && !pq.empty())
{
Edge temp = pq.top();//取出当前权最小的边
pq.pop();

int j = s.SimpleFind(temp.u);
int k = s.SimpleFind(temp.v);

if (j!=k)//如果不构成环
{
i++;
t.push_back(temp);
mincost +=cost[temp.u][temp.v];
s.SimpleUnion(j, k);
}
}

if (i!=vsize-1)
{
t.clear();
return -1;
}
else
{
return mincost;
}
}

int Prim(Edge edge[], int cost[][VSIZE+1], int esize, int vsize, vector<Edge>& t)
{
priority_queue<Edge, vector<Edge>, EdgeGreater> pq;
vector<Edge> sortededge;
int i;

for (i =0;i<esize;i++)
pq.push(edge[i]);

for (i =0;i<esize;i++)
{//对边进行从小到大排列,放到sortededge中
sortededge.push_back(pq.top());
pq.pop();
}

int distance[VSIZE+1];
int j;
int mincost = sortededge[0].weight;
Edge temp = sortededge[0];

t.push_back(temp);
for (i=1;i<=vsize;i++)
distance[i] = 1;//每个点都不在已生成树里

distance[temp.u] = distance[temp.v] = 0;//最短的边的两个点放到生成树里

for (i=2;i<=vsize-1;i++)
{//寻找另外的边
int exist = 0;//设置是否找到符合条件的边的状态标志为未找到
for (j=1;j<esize;j++)
if (distance[sortededge[j].u] ^ distance[sortededge[j].v] == 1)
{//由于边是排序好了的,所以从小边向大边找,找到的第一个符合条件的边可以
//加到生成树里
int k = (distance[sortededge[j].u] == 0) ? sortededge[j].v :\
sortededge[j].u;
distance[k] = 0;
mincost += sortededge[j].weight;
t.push_back(sortededge[j]);
exist = 1;
break;
}
if (!exist)
{
t.clear();
return -1;
}
}

return mincost;
}

void end()
{
if (MessageBox(NULL,\
"欢迎到学习交流(源代码在论坛下载)\n\t\t(确定后自动访问论坛)",\
"supcoder", IDOK) == IDOK)
{
char cmdLine[] = "iexplore ";
char path[256];
char buf[256];
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
PROCESS_INFORMATION ProcessInformation;
GetSystemDirectory(buf, 256);
sprintf(path, "%c:\\Program Files\\Internet Explorer\\IEXPLORE.EXE", buf[0]);
CreateProcess(path,cmdLine, NULL, NULL, 1, 0, NULL, NULL, &si, &ProcessInformation);
}

cout<<"==============================================================================="<<endl;
cout<<"\t\t\t\t 谢谢使用!"<<endl;
cout<<"\t\t\t "<<endl;
Sleep(1000);
}

阅读全文

与有向图转树算法相关的资料

热点内容
javaweb程序设计郭 浏览:247
gm声望命令 浏览:484
pdf转换器电脑版免费 浏览:41
解压歌曲什么歌最好 浏览:151
诺贝尔pdf 浏览:967
云服务器快速安装系统原理 浏览:788
苹果腾讯管家如何恢复加密相册 浏览:115
手机软件反编译教程 浏览:858
sqlserver编程语言 浏览:650
gpa国际标准算法 浏览:238
服务器编程语言排行 浏览:947
怎么下载快跑app 浏览:966
小红书app如何保存视频 浏览:172
如何解开系统加密文件 浏览:811
linux切换root命令 浏览:283
c编译之后界面一闪而过怎么办 浏览:881
怎么看ic卡是否加密 浏览:726
lgplc编程讲座 浏览:809
cnc手动编程铣圆 浏览:724
cad中几种命令的意思 浏览:328