一步两步学算法之图的广度搜索

bfs利用队列搜索    详细看代码

#define VERTEX_MAX 26                //图的最大定点数
#define MAXVALUE 32767                 //最大值
#include "stdio.h"
#define QUEUE_MAXSIZE 10             //队列最大容量
typedef struct
{
    char Vertex[VERTEX_MAX];            //保存定点信息的数组
    int Edges[VERTEX_MAX][VERTEX_MAX];    //边的权
    int IsTrav[VERTEX_MAX];                 //遍历标记
    int VertexNum;                        //定点数量
    int EdgeNum;                        //边的数量
    int GraphType;                        //图的类型
}MatrixGraph;                            //邻接矩阵结构
typedef struct
{
    int Data[QUEUE_MAXSIZE];
    int head;
    int tail;
}SeqQueue;                //队列结构
void BFSM(MatrixGraph *G,int k);
void CreateMatrixGraph(MatrixGraph *G);
void OutMatrix(MatrixGraph *G); 

void CreateMatrixGraph(MatrixGraph *G)
{
    int i,j,k,weight;
    char start,end;
    printf("输入各顶点信息\n");
    for(i=0;i<G->VertexNum;i++)
    {
        getchar();
        printf("第%d个顶点:",i+1);
        scanf("%c",&(G->Vertex[i]));            //输入顶点信息
    }
    printf("输入构成各边的两个顶点及权值(用逗号分隔):\n");
    for(k=0;k<G->EdgeNum;k++)
    {
        getchar();
        printf("第%d条边:",k+1);
        scanf("%c,%c,%d",&start,&end,&weight);            //输入边的两头节点 和权值
        for(i=0;i<G->VertexNum;i++)                //从已有的顶点信息数组找这两个顶点并赋予权值
        {
            if(start==G->Vertex[i]){
                for(j=0;j<G->VertexNum;j++)
                {
                    if(end==G->Vertex[j])
                    {
                        G->Edges[i][j]=weight;
                            if(G->GraphType==0)
                                G->Edges[j][i]=weight;
                    }
                }
            }

        }
    }
} 

void OutMatrix(MatrixGraph *G)
{
    int i,j;
    for(j=0;j<G->VertexNum;j++)
        printf("\t%c",G->Vertex[j]);
    printf("\n");
    for(i=0;i<G->VertexNum;i++)
    {
        printf("%c",G->Vertex[i]);
        for(j=0;j<G->VertexNum;j++)
        {
            if(G->Edges[i][j]==MAXVALUE)
                printf("\t*");
            else
                printf("\t%d",G->Edges[i][j]);
        }
        printf("\n");
    }
}
void QueueInit(SeqQueue *Q)
{
    Q->head=Q->tail=0;
}
int QueueIsEmpty(SeqQueue *Q)
{
    return Q->head==Q->tail;
}
int QueueIn(SeqQueue *Q,int ch)
{
    if((Q->tail+1)%QUEUE_MAXSIZE==Q->head)
        return 0;
    Q->Data[Q->tail]=ch;
    Q->tail=(Q->tail+1)%QUEUE_MAXSIZE;
    return 1;
}
int QueueOut(SeqQueue *Q,int *ch)
{
    if(Q->head==Q->tail)
        return 0;
    *ch=Q->Data[Q->head];
    Q->head=((Q->head+1)%QUEUE_MAXSIZE);
    return 1;
}

void BFSraverse(MatrixGraph *G)
{
    int i;
    for(i=0;i<G->VertexNum;i++)
        G->IsTrav[i]=0;
    printf("广度优先遍历节点");
    for(i=0;i<G->VertexNum;i++)
        if(!G->IsTrav[i])
            BFSM(G,i);
    printf("\n");
}

void BFSM(MatrixGraph *G,int k)
{
    int i,j;
    SeqQueue Q;
    QueueInit(&Q);
    G->IsTrav[k]=1;
    printf("->%c",G->Vertex[k]);

    QueueIn(&Q,k);
    while(!QueueIsEmpty(&Q))
    {
        QueueOut(&Q,&i);
        for(j=0;j<G->VertexNum;j++)
        {
            if(G->Edges[i][j]!=MAXVALUE&&!G->IsTrav)
            {
                printf("->%c",G->Vertex[j]);
                G->IsTrav[j]=1;
                QueueIn(&Q,j);
            }
        }
    }
}
时间: 2024-10-09 20:16:58

一步两步学算法之图的广度搜索的相关文章

算法_图的深度优先搜索和广度优先搜索

一.图的基本数据结构 图是由一组顶点和一组能够将两个顶点相互连接的边所构成的,一般使用0~V-1这样的数字形式来表示一张含有V个顶点的图.用v-w来指代一张图的边,由于是无向图,因此v-w和w-v是同一种边的两种表示方法.无向图是指边没有方向的图结构在无向图中,边仅仅表示的是两个顶点之间的连接.图的数据结构的可视化如下图所示(其中边上的箭头没有任何意义): 当两个顶点通过一条边相互连接,则称这两个顶点是相邻的.某个顶点的度数即为依附它的边的总数.当两个顶点之间存在一条连接双方的路径的时候,称为这

一步两步学算法之图邻接表实现

图的邻接表实现 这种结构创建邻接表时添加节点较为绕 建议断点调试下看看 邻接表和邻接矩阵相比 邻接表节省空间但是很难判断两个节点之间是否有边  此种结构要在稀疏图下才划算 下面是代码 1 #define VERTEX_MAX 20 2 #include "stdio.h" 3 #include "malloc.h" 4 typedef struct edgeNode 5 { 6 int Vertex; //顶点序号 7 int weight; 8 struct ed

一步两步学算法之图的深度搜素

DFS 与BFS 的不同之处 直接采用递归 从一个点的邻点直接向下搜索 而不是一个点的所有邻点 .可以把BFS想成一张网  DFS相当于一条路走到黑走不通再换别的路 DFS比BFS更容易理解 1 void DFSraverse(MatrixGraph *G) 2 { 3 int i; 4 for(i=0;i<G->VertexNum;i++) 5 G->IsTrav[i]=0; 6 printf("深度优先遍历节点"); 7 for(i=0;i<G->Ve

一步两步学算法之哈夫曼编码(最优二叉树)

比较难理解的 都打了备注了 1 #include "stdio.h" 2 #include "stdlib.h" 3 #include "string.h" 4 char alphabet[]={'A','B','C','D'}; 5 typedef struct 6 { 7 int weight; //权值 8 int parent; //父节点序号 9 int left ; 10 int right; 11 }HuffmanTree; 12

一步两步学算法之树的遍历 非递归实现

递归的程序其实我觉得可读性较高  但是执行效率低下 为了做一道PAT的题 去理解了下非递归实现树的遍历 用一个栈来实现 先序遍历 先访问节点 再把节点push进栈 再访问 再push 直到next=NULL 然后pop出一个节点 也就是弹出一个节点 访问它的右边 再弹出 在访问 中序遍历 把左边节点全部push进栈 然后弹出 访问中间 再访问右边  再弹出 一直循环 后序遍历 比较难理解  要入两次栈才能访问 先左边全部入栈  栈顶是左边的元素 此书不能访问 因为右边还没入栈 下面给出先序和后序

一步两步学算法之最小生成树Prim算法

prim就是一个让树长大的过程  弄一个集合   从一个点开始不断向外搜索 找到权值最小的点 放进集合中  从这个集合所连的边再向外找 1 #define USED 0 2 #define NOADJ -1 3 void Prim(MaxtrixGraph G) 4 { 5 int i,j,k,min,sum=0; 6 int weight[VERTEX_MAX]; 7 char tmpvertex[VERTEX_MAX]; //临时顶点信息 8 9 for(i=1;i<G.VertexNum;

一步两步学算法之中序遍历线索二叉树

1 typedef enum 2 { 3 SubTree, //子树 4 Thread //线索 5 }NodeFlag; 6 7 typedef struct ThreadTree 8 { 9 DATA data; 10 NodeFlag lflag; 11 NodeFlag rflag; 12 struct ThreadTree *left; 13 struct ThreadTree *right; 14 }ThreadBinTree; 15 16 ThreadBinTree *Previo

一步两步学算法之顺序队列

顺序链表代码  非常简单: 但这个代码会有假溢出的状况出现: 就是在队尾已满的情况下,不断出队后 若在此时进行入队操作 判断队列已满的条件是q->head==q->tail 此时这个条件满足. 但实际队列之前已经出队了好几个,前面还有空余空间,这就是假溢出:(原谅我懒得画图) 假溢出解决办法 1.每次出队后 把所有数据都往前移.这种方法要移动大量数据,效率太低. 2.使用循环队列.这种方法明天再打. 1 #define QUEUEMAX 15 2 typedef struct 3 { 4 DA

一步两步学算法之二叉搜索树

Binary Search Tree  又叫二叉查找树,二叉排序树 这是种什么样的树呢? 其实就是根节点的左子树比根节点小  右子树比根节点大  同时 左子树和右子树也是二叉搜索树 代码比较简单 基本用递归实现 比较好理解  只有删除带有左右子树的节点时比较难理解 方法就是 直接在右子树找一个最小的节点 取代要被删除的节点 再继续删除右子树里的节点 详细看代码 1 #include "stdio.h" 2 #include "stdlib.h" 3 typedef