总结_图_v1.1

 

1.图的数字特性:

1.1 握手定理: 图中的节点度数等于边数的2 倍。

clip_image002

公式表达为

clip_image002[8]

 

2.欧拉公式:

记忆公式为: 顶+ 面= 2+边

设G是任意的联通图,则有

clip_image002[10]

n : G 中的顶点数目

m :是边数目

r: 面的数目

即: 联通图中顶点数-边数+面的数目=2;

clip_image002[12]

 

 

 

 

2  图操作:

 

//图的遍历很重要:仅仅给出非递归实现,图的很多操作 CRUD 都是基于R的,只不过是条件中操作

//写代码是从内向外写的。

//这里数据结构选用的是邻接表

1.1 深度遍历(DFS)

思想:

/* Adjlist g ,邻接表

vertype u 遍历的开始节点

vertype v  遍历的结束节点

*/

  void aldfs(Adjlist g,vertype u,vertype v){

      int top=0,s[];

 

//5.初始化栈了:

int top=0,s[]';

s[++top]=u;

visited[u]=1;

//栈操作

while(top>0 || p)

{

//4.temp 从哪儿来,从栈中获得 因为 图是地址结构,需要保存地址,因为沿着图的单向访问到地点就不能回来了所以要保存

   temp=s[top];

//3.P从哪儿来->p 在邻接表的首地址上

p=g[temp].firstarc; //

//7.访问下一个邻接地址:现在到了链表的操作了
while(p!=null && visited[p->adjvex]==1)

  p=p->next;

//8.链表的操作

if(p==null)  //销毁栈

top--;

else

{

//2.i 是从取自邻接点的

   i=p->adjvex;

//1.条件输出栈中的内容

if(i==v)         //起点终点相同则是遍历完全

for(k=1;k<=top;k++)

{printf(“%3d”,s[k]);

  printf("%3d\n",v);

  } 

else   //10.继续压入栈

{

    visited[i]=1;

s[++top]=i;

}

}

 

}

 

1.2 宽度遍历(BFS)

//这时要用的队列来保存对应的地址,为什么??你想想:把这些图看成横向的多链表结构:满足先进先出的特性:

 

void bfs(graph g, vertype v0)

{

   visit(v0);

  visited[v0]=1;

   //1.初始化队列

initqueue(Q);

enqueue(Q,v0);  //V0 入列

   while(!empty(Q))

{

        v=delqueue(Q);

        w=firstadj(g,v); //求顶点的V的第一个临界点

          while(W!=0)

      {

       if(visited[w]==0)  //邻接点没访问

            {

             visit(w);

            visited[w]=1;

          enqueue(Q,w);

              w=nextadj(g,v,w);

             }      

    }

 

void Traver()

{

     for (i=1;i<n;i++)

         for(i=1;i<=n;i++)

                   if(visited[i] ==0)

           bfs(i);

}

 

 

 

 

 

 

 

 

3.图转化

1.讨论如下:

当图向树转化时有

1.最小生成树

2.单源最短路径:

3.对顶点的路径问题:

 

//限于时间写出伪代码:
1.最小生成树

限于时间写出伪代码以后再实现:
如是权值,则“使用破圈方法”

思想: 排序删边测联通,若是联通继续删,指导n-1 条边结束:

 

typdedef stuct

{

  int i;

int j;

int w;//权值

} node ;

node edge[];

scanf(“%d%d”,&e,&n);//输入变数和顶点数目

for(i=0;i<=e;i++)

  scanf(“%d%d%d”,edge[i].i,edge[i].j,edge[i].w);

//插入排序 :

for(i=2;i<=e;i++)

{

   edge[0]=edge[i];   j=i-1;

   while(edge[j].w<edge[0].w)

   edge[j+1]=edge[j--];   //操作后每次地址移动。

  edge[j+1]=edge[0]; 

}

k=1,eg=e;

while(eg>=n) //eg-n>=1 剩下n-1 条边,C语言中非0 为假, 大于1 为真

{

    if(connect(K)) // 注意这里的Connect 是图是否联通的方法

{

//  删除第 K条边是联通的继续删除

      edge[k].w=0;eg—;  //边数减少1
}

  k++;

}

 

 

2.单源最短路径:

Dijikstr思想是:

列表交点求最值,最值点组合该点联通点 再最值

//设数据结构是邻接表实现

 

//定义邻接表的矩阵

struct node

{

  int adjvex, //邻接节点

  int weigth ; //权值

   int strct   * next 

} p;

 


void shorttest_Dijkstra(){

 

//1.初始化

  int dist[],s[];  //dist最短路径, s数组存放顶点是否找到最短路径

for(i=1;i<=n;i++)

{

   dist[i]=MAX;

   s[i]=0;  //0 表示未找到

}

 

//2.

 

for(int j=1;j<=n;j++){

 

     //转换节点状态时的 地址赋值

   for(s[j]==0 && dist[j<max])

          {u=j;max=dist[j]}

  s[u]=1; //标识改点被选中

p=g[u].firstarc; //链表首地址

while(p) //遍历链表

j=p->adjvex;

if(dist[j]=dist[u]+p->weight){ //dist u,v 是边

        dist[j]=dist[u]+p->weight //3.  路径权值再符合

  p=p->next;
}


}

  

}

 

3.对顶点的路径问题:

FLOAY算法:

思想: 不解释:

   三重循环: i ,k,,j 型

 

void Shortpath(AdjMatrix g)

{

//初始化

  AdjMatrix  length; // 邻接矩阵的结构体:

for(i=0;i<=n;i++)

     for(j=1;j<=n;j++)

       length[i][j]=g[i][j];  //初始化

 

   for(k=1;k<=n;k++)

              for(i=1;i<=n;i++)

                          for(j=1;j<=n;j++)

                    if(length[i][k]+length[k][j]<length[i][j]) //i ,k,i 型

                                        ength[i][j]=length[i][k]+length[k][j] ; 

   

}

转载于:https://my.oschina.net/u/578921/blog/184462

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值