zoukankan      html  css  js  c++  java
  • 图是一种重要的数据结构,可以用来描述很多实际问题,因此得到了广泛的应用。最典型的应用领域有电路分析、寻找最短路径、项目规划、鉴别化合物、统计力学、遗传学、控制论等学科中。图的主要特点:它的每一个顶点可以与多个其他顶点相关联,各顶点之间的关系时任意的。

    1、图的一些基本概念

    路径:在图G=(V,E)中,若从顶点vi出发沿着一些边经过若干顶点vp1, vp2,vp3,vp4...vpm 到达顶点v则称顶点序列(vi, vp1, vp2,vp3,vp4...vpm, vj)为从顶点i到顶点j的一条路径。

    路径长度:不带权的图,路径长度是指此路径上边的条数。带权图,路径长度是指路径上各个边上的权值之和。

    简单路径:若路径上各个顶点没有重复的,则称该路径为简单路径。若第一个顶点和最后一个顶点重合,则称这样的路径为回路。

    连通图和连通分量:在无向图中,从顶点一到顶点二有路径,则称这两个顶点是连通的,若图中的任一对顶点都是连通的,则称此图是连通的。非连通图的最大连通子图称为该图的连通分量。

    强连通图和强连通分量:在有向图中,若任意两个顶点之间都有两个路径,则称此图是强连通的,非强连通图的极大连通子图是强连通分量。

    生成树:一个无向连通图的生成树是它的极小连通子图。

    2、图的C++实现

    图的邻接表表示法:

    声明一个数组表示各个顶点,以每个顶点为头结点,链接和这个结点相连的边。下图是一个示例图片:

    抽象数据类型表示:

    /*
    有向图边结构体
    */
    struct GraphEdge
    {
    	int cost;	//边的权值
    	int edgedata;	//边的顶点值
    	GraphEdge *nextedge;	//下一个边
    
    	
    	GraphEdge(int cost,int edgedata)
    	{
    		this->cost=cost;
    		this->edgedata=edgedata;
    		this->nextedge=NULL;
    		
    	}
    };
    
    /*
    图顶点:结构体表示,包含顶点的值和边链表指针域,
    顶点表使用数组来表示。
    */
    struct Vertex
    {
    	int data;		//顶点的值
    	GraphEdge *edgehead;	//边链表的头指针
    };
    
    
    //图类
    class LinkedGraph
    {
    public:
    	//构造函数析构函数
    	LinkedGraph()
    	{
    		//初始化参数值
    		v=new Vertex[9];	//创建顶点表数组
    		//加入检测语句
    		if(v==NULL)cout<<"未分配成功"<<endl;
    		for(int i=0;i<9;i++)
    			v[i].edgehead=NULL;	//这里需要用点运算符进行操作
    	}
    	~LinkedGraph()
    	{
    
    	}
    
    	//建立图、输出图
    	void InitGraphOutput(LinkedGraph *lg);
    	
    
    	//深度优先搜索和广度优先搜索
    	void DFSGraph(LinkedGraph *lg);	//深度优先遍历
    	void BFSGraph(LinkedGraph *lg);	//广度优先遍历
    
    private:
    	//声明结点的个数,并分配空间:不能只声明不定义和分配存储空间
    	Vertex *v;
    
    
    };
    

    建立邻接表表示的图(带权无向图)算法:
    1、输入顶点,顶点数组表示。
    2、输入边,将每个顶点之间有关系的边链接起来。
    3、相当于插入顶点,插入边。

    代码:

    void LinkedGraph::InitGraphOutput(LinkedGraph *lg)
    {
    	
    	int data;		//顶点值
    	int dest,cost;	
    	int i=0;
    	while(i<9)	//建立图的顶点数组和这个顶点链接的边
    	{
    		//输入顶点
    		cout<<"请输入顶点值:"<<endl;
    		cin>>data;
    		lg->v[i].data=data;	//要用点运算符来操作结构体的成员
    		
    		GraphEdge *q,*p=lg->v[i].edgehead;	//声明两个指针,一个用于指向当前顶点的边链表头指针,一个用来辅助
    		
    		cin>>dest>>cost;	//输入这个顶点链接的边,以权值为0结束
    		int edgenum=0;	//用来记录边数,用于不同的链接方式,局部变量的位置
    		while(cost!=0)
    		{
    			edgenum++;
    			if(edgenum<=1)
    			{
    				//分配一个存储空间给q,如果是第一条边
    				q=new GraphEdge(cost,dest);
    				if(q==NULL)cout<<"未分配成功"<<endl;
    				//链接
    				lg->v[i].edgehead=q;	//记住这一句
    				p=q;
    				q=q->nextedge;
    			}
    			else
    			{
    				//bug:只能链入两条边
    				cout<<"第二条边链接成功"<<endl;
    				//还有其他边
    				q=new GraphEdge(cost,dest);
    				p->nextedge=q;
    				p=p->nextedge;	
    				q=q->nextedge;
    			}
    			
    			cout<<"请继续输入这个顶点对应的边的值和权值:"<<endl;
    			cin>>dest>>cost;
    		}
    		i++;	//插入顶点的操作
    	}
    	
    	cout<<"-------------输出这个图:-------------"<<endl;
    	//输出这个图
    	for(int i=0;i<9;i++)
    	{
    		cout<<lg->v[i].data<<endl;
    		GraphEdge *p=lg->v[i].edgehead;
    		if(p==NULL)cout<<"这个指针出现问题"<<endl<<endl;
    		while(p!=NULL)
    		{
    			cout<<lg->v[i].data<<"-->"<<p->edgedata<<"  权值为:"<<p->cost<<endl;
    			p=p->nextedge;
    		}
    	}
    
    
    } 

    图的关联算法

    1、克鲁斯卡尔

    2、floyd

    3、图的广度优先搜索和深度优先搜索

    4、普里姆

    5、Bellman-Ford

    6、迪杰斯特拉

    7、SPFA

    8、拓扑排序

    9、最短路径问题

  • 相关阅读:
    【python安装】错误——“User installations are disabled via policy on the machine”
    “金字塔原理”-写作
    【sublime】Pretty Json插件的安装与配置使用
    VMware卸载后再安装时网络连接处没有虚拟网卡
    2019-2020-2《网络对抗技术》Exp4 恶意代码分析
    2020课程设计 Week1 Asn.1格式的学习
    基于BouncyCastle的asn.1分析工具设计与实现的任务理解与分工
    2019-2020-2《网络对抗技术》Exp3 免杀原理与实践
    2019-2020-2 《网络对抗技术》Exp2 后门原理与实践
    2019-2020-2《网络对抗技术》Exp1 PC平台逆向破解
  • 原文地址:https://www.cnblogs.com/fistao/p/3032202.html
Copyright © 2011-2022 走看看