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、最短路径问题

  • 相关阅读:
    CSS的选择符
    小例子分析C#继承机制
    socket服务端(.net)代码
    分页代码
    web.config的数据库连接字符串写法与取法
    怎么提高网站速度,对于大访问量网站如何对网站进行优化
    方维分享系统二次开发, 给评论、主题、回复、活动 加审核的功能
    方维分享系统修改,本地安装失败,后台无法登陆
    方维分享系统修改,后台一键更新缓存
    方维分享系统 第三方登录appkey申请
  • 原文地址:https://www.cnblogs.com/fistao/p/3032202.html
Copyright © 2011-2022 走看看