非线性数据结构——图

3 篇文章 0 订阅
2 篇文章 0 订阅

非线性数据结构图

  1. 认识图
  2. 表示图
  3. 图的遍历
  4. 最短路径问题

图的定义:
图中的数据元素通常称为顶点,所有顶点构成顶点集,我们通常用V(Vetex)来表示。
元素间的关系用边来表示,通常用E(edge)来表示边集合。
G1 = { V, E },V = { v1, v2, v3, v4, v5},E = { (v1, v2) , (v1, v4), (v2, v3), (v2, v5), (v3, v4), (v3, v5) }。
咸宏超
图的种类:无向图、有向图。带权图:无向网、有向网。

图的相关术语:

  1. 顶点间的关系:邻接
  2. 邻接点:若图中两个顶点之间存在边,则称两个顶点互为邻接点。
  3. 度:一个顶点的邻接点的个数。
  4. 有向图中,顶点的度分为:
    入度:指以该顶点为起点的边的数目。
    出度:指以该顶点为终点的边的数目。
    在这里插入图片描述
  5. 路径:图G中,从顶点vi到顶点vj的路径是一个顶点序列,起点为vi,终点为vj,可表示为一个这样的序列 (vi,vi0,vi1, ……,vim, vj),其中任意两个相邻的顶点间必须存在邻接关系。
    起点和终点相同的路径称为圈或环。
    有向图的路径也是有向的。
  6. 关于连通:
    连通图:任意两顶点间都有路径连接的图叫做连通图(无向)。
    连通分量:若无向图为非连通图,则图中各个极大连通子图称作此图的连通分量。

没有圈的连通图 ----- 树,一棵树的边数恰好是顶点数减1。 生成树:假设一个连通图有 n 个顶点和 e 条边,其中 n-1 条边和 n 个顶点构成一个极小连通子图,称该极小连通子图为此连通图的生成树。

表示图
两种方法:邻接表、邻接矩阵。

邻接矩阵:
无向图中用二维矩阵 G[ n ][ n ] 来表示任意两点间的邻接关系(是否邻接), G[ i ][ j ] 表示第 i 个顶点与第 j 个顶点是否邻接。若邻接把 G[ i ][ j ] 与 G[ j ][ i ] 标记为1,否则标记为0。
有向图中:G[ i ][ j ] 表示的是顶点 i 是否有能到顶点 j 的边,若有边相连, 则仅将G[ i ][ j ] 置1;否则 G[ i ][ j ] 置0。(都是没有权值时)。
在这里插入图片描述
如图无向图与有向图的矩阵描述方法。
无向图矩阵都是关于对角线对称的有向图一般不是。
在这里插入图片描述
加权无向图
在这里插入图片描述
邻接矩阵储存表示:
char V[MAX_V]; // 顶点向量
int G [MAX_V] [MAX_V]; //邻接矩阵
int vexnum, arcnum; // 顶点和边的个数
邻接矩阵的大小:n^2

//带权无向图的邻接矩阵构建
double g[101][101];//图的二维数组
double w;//权值
int main()
{
   int i,j,k,e,n;//n为顶点数,e为边数
   for(i = 1; i <= n; i++)
     for(j = 1; j <=n; j++)
     g[i][j] = 0x3f3f3f;//初始化,对于不带权的图 g[i][j] = 0;表示没有边相连
     cin>>e;//读入边的条数
     for(k = 1; k <= e; k++)
     {
        cin>>i>>j>>w;// 读入顶点的序号及权值
        g[i][j] = w;  //对于不带权的图 g[i][j] = 1;
        g[j][i] = w;//无向图的对称性,如果是有向图没有这一条
     }
}

初始化数组的小技巧:
(1)如果是int数组,采用memset(g,0x3f3f3f,sizeof(g))可以全部初始化一个很大的数,使用memset(g,0,sizeof(g)),全部清零。memset(g,0x8f,sizeof(g)),全部初始化一个很小的数。
(2)如果是double数组,采用memset(g,127,sizeof(g));可全部初始化一个很大的数1.38*10^306,使用memset(g,0,sizeof(g))全部清零。
邻接表存储表示:
A,B,C,D,E,F分别用0,1,2,3,4,5表示
在这里插入图片描述
如图 A 与之相连的有B,E 所以头结点0 与1相连,1在于4相连,同理后面的也是这样。
一般使用中,常采用数组模拟实现邻接表结构。
n:顶点数,m:边数

int  u[m+1],v[m+1],w[m+1];   //起点、终点、权值
/*每条边对应三个数组:u[i],v[i],w[i]表示从第u[i]号顶点
到第v[i]号顶点有一条权值为w[i]的边*/
int  first[n+1],  next[m+1] ;
//first[i]表示第i个顶点的第一条边在u中的序号,
//相当于链表的头指针
//next[i]表示第i条边的下一条边(与其起点相同的)
//在u中的序号,相当于链表中的next指针

这部分不好理解可以结合下面一起理解。

//初始化first数组,表示当前所有顶点都没有边
for(i=1; i<=n; i++) 
first[i] = -1;

//读入每条边的信息
for(i=1; i<=m; i++)
{  cin>> u[i] >> v[i] >> w[i];
    next[i] = first[u[i]]; //插入到first[u[i]]前
    first[u[i]] = i;  //重新定位头指针指向
}

图的遍历
从图中某个顶点出发游历图,访遍图中其余顶点,并且使图中的每个顶点仅被访问一次的过程。
遇到的问题:图中可能存在回路,且图的任一顶点都可能与其它顶点连通,在访问完某个顶点之后可能会沿着某些边又回到了曾经访问过的顶点。
为避免重复访问,可设一个标志顶点是否被访问过的辅助数组 visited[i],它的初始状态为false,在图遍历过程中,一旦顶点i被访问,就修改 visited[i]为true。

  • 深度优先算法(DFS)
    在这里插入图片描述
    从图中某个顶点V0 出发,访问此顶点,然后选择一个与V0邻接且未被访问的顶点W为初始顶点,再从W出发进行深度优先搜索, 直至图中所有顶点都被访问到。
void DFS(int v)
{
    int n=vertexNum;//顶点数目
    if(v<0||v>=n) return;
    cout<<vertex[v]<<" ";//输出顶点v
    visited[v]=1;//被访问过
    for(int j=0;j<n;j++)
        if(visited[j]==0&&G[v][j]==1)//选择没被访问过且存在边(v,j)的点j
            DFS(j);
}

中间的有空补上先说最短路径问题

最短路径问题
最短路径问题的几种算法

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杜康o

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值