• 数据结构学习第十七天


    14:39:22 2019-09-01

    学习

    图的两种遍历方法:

    ①DFS 深度优先搜索(Depth First Search)

    ②BFS 广度优先搜索(Breadth First Search)  //利用队列实现广度优先

    //邻接表实现 及 利用 邻接表 实现 深度优先搜索(DFS)

      1 #define _CRT_SECURE_NO_WARNINGS  
      2 #include<stdio.h>
      3 #include<malloc.h>
      4 //表示图的两种方法
      5 //邻接矩阵 G[N][N] N个顶点从0到N-1编号
      6 //邻接表 表示
      7 /*Graph Create();  //建立并返回空图
      8 Graph InsertVertex(Graph G, Vertex v); //将v插入G
      9 Graph InsertEdge(Graph G, Edge e); //将e插入G
     10 void DFS(Graph G, Vertex v); //从顶点v出发深度优先遍历图G
     11 void BFS(Graph G, Vertex v); //从顶点v出发宽度优先遍历图G
     12 void ShortestPath(Graph G, Vertex v, int Dist[]); //计算图G中顶点v到任意其它顶点的最短距离
     13 void MST(Graph G); //计算图G的最小生成树*/
     14 
     15 //图的邻接表表示法
     16 #define MaxVerterNum 100    //最大顶点数
     17 #define INFINITY 65535        //
     18 typedef int Vertex;            //顶点下标表示顶点
     19 typedef int WeightType;        //边的权值
     20 typedef char DataType;        //顶点存储的数据类型
     21 
     22 //边的定义
     23 typedef struct ENode* PtrToENode;
     24 typedef PtrToENode Edge;
     25 struct ENode
     26 {
     27     Vertex V1, V2; //有向边<V1,V2>
     28     WeightType Weight;  //权重
     29 };
     30 
     31 //邻接点的定义
     32 typedef struct AdjVNode* PtrToAdjVNode;
     33 struct AdjVNode
     34 {
     35     Vertex AdjV;  //邻接点下标
     36     WeightType Weight; //边权重
     37     PtrToAdjVNode Next; //指向下一个邻接点的指针
     38 };
     39 
     40 //顶点表头节点的定义
     41 typedef struct Vnode
     42 {
     43     PtrToAdjVNode FirstEdge;  //边表头指针
     44     DataType Data;            //存顶点的数据
     45 }AdjList[MaxVerterNum];        //AdjList是邻接表类型
     46 
     47 //图节点的定义
     48 typedef struct GNode* PtrToGNode;
     49 typedef PtrToGNode LGraph;
     50 struct GNode
     51 {
     52     int Nv;  //顶点数
     53     int Ne;  //边数
     54     AdjList G;  //邻接表
     55 };
     56 
     57 LGraph CreateGraph(int VertexNum)
     58 {//初始化一个有VertexNum个顶点但没有边的图
     59     Vertex V;
     60     LGraph Graph;
     61 
     62     Graph = (LGraph)malloc(sizeof(struct GNode)); //建立图
     63     Graph->Nv = VertexNum;
     64     Graph->Ne = 0;
     65     //初始化邻接表头指针
     66     for (V = 0; V < Graph->Nv; V++)
     67         Graph->G[V].FirstEdge = NULL;
     68     return Graph;
     69 }
     70 
     71 void InsertEdge(LGraph Graph, Edge E)
     72 {
     73     PtrToAdjVNode NewNode;
     74     //插入边<V1,V2>
     75     NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
     76     NewNode->AdjV = E->V2;
     77     NewNode->Weight = E->Weight;
     78     NewNode->Next = Graph->G[E->V1].FirstEdge;
     79     Graph->G[E->V1].FirstEdge = NewNode;
     80 
     81     //若是无向图 还要插入边<V2,V1>
     82     NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
     83     NewNode->AdjV = E->V1;
     84     NewNode->Weight = E->Weight;
     85     NewNode->Next = Graph->G[E->V2].FirstEdge;
     86     Graph->G[E->V2].FirstEdge = NewNode;
     87 }
     88 
     89 LGraph BuildGraph()
     90 {
     91     LGraph Graph;
     92     Edge E;
     93     Vertex V;
     94     int Nv, i;
     95 
     96     scanf("%d", &Nv);   /* 读入顶点个数 */
     97     Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */
     98     scanf("%d", &(Graph->Ne));  //读入边数
     99     if (Graph->Ne != 0) 
    100     { 
    101         E = (Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */
    102         /* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */
    103         for (i = 0; i < Graph->Ne; i++)
    104         {
    105             scanf("%d %d %d", &E->V1, &E->V2, &E->Weight);
    106             InsertEdge(Graph, E);
    107         }
    108     }
    109     /* 如果顶点有数据的话,读入数据 */
    110     for (V = 0; V < Graph->Nv; V++)
    111         scanf(" %c", &(Graph->G[V].Data));
    112     return Graph;
    113 }
    114 
    115 //DFS 利用邻接表存储的图 实现 深度优先搜索
    116 int visited[100];
    117 void Visit(Vertex V)
    118 {
    119     printf("访问顶点%d
    ", V);
    120 }
    121 
    122 // visited[]是全局变量 初始化为0
    123 void DFS(LGraph Graph, Vertex V)   //以V为出发点访对邻接表存储的图进行DFS访问
    124 {
    125     Visit(V);
    126     visited[V] = 1;
    127 
    128     PtrToAdjVNode W; //用来从某个点 出发访问
    129     for (W = Graph->G[V].FirstEdge; W; W = W->Next)
    130     {
    131         if (!visited[W->AdjV])   //若 W->Adjv未被访问 则递归访问
    132             DFS(Graph, W->AdjV);
    133     }
    134 }
    View Code

    //邻接矩阵实现 及 利用 邻接矩阵 实现 广度优先搜索(BFS)

      1 #define _CRT_SECURE_NO_WARNINGS  
      2 #include<stdio.h>
      3 #include<malloc.h>
      4 //表示图的两种方法
      5 //邻接矩阵 G[N][N] N个顶点从0到N-1编号
      6 //邻接表 表示
      7 /*Graph Create();  //建立并返回空图
      8 Graph InsertVertex(Graph G, Vertex v); //将v插入G
      9 Graph InsertEdge(Graph G, Edge e); //将e插入G
     10 void DFS(Graph G, Vertex v); //从顶点v出发深度优先遍历图G
     11 void BFS(Graph G, Vertex v); //从顶点v出发宽度优先遍历图G
     12 void ShortestPath(Graph G, Vertex v, int Dist[]); //计算图G中顶点v到任意其它顶点的最短距离
     13 void MST(Graph G); //计算图G的最小生成树*/
     14 
     15 //图的邻接矩阵表示法
     16 #define MaxVerterNum 100    //最大顶点数
     17 #define INFINITY 65535        //
     18 typedef int Vertex;            //顶点下标表示顶点
     19 typedef int WeightType;        //边的权值
     20 typedef char DataType;        //顶点存储的数据类型
     21 
     22 //边的定义
     23 typedef struct ENode* PtrToENode;
     24 typedef PtrToENode Edge;
     25 struct ENode
     26 {
     27     Vertex V1, V2; //有向边<V1,V2>
     28     WeightType Weight;  //权重
     29 };
     30 
     31 //图节点的定义
     32 typedef struct GNode* PtrToGNode;
     33 typedef PtrToGNode MGraph;   //以邻接矩阵存储的图类型
     34 struct GNode
     35 {
     36     int Nv;    //顶点数
     37     int Ne;    //边数
     38     WeightType G[MaxVerterNum][MaxVerterNum];   //邻接矩阵
     39     DataType Data[MaxVerterNum];            //存顶点的数据
     40 };
     41 
     42 MGraph CreateGraph(int VertexNum)
     43 {//初始化一个有VerterNum个顶点但没有边的图
     44     Vertex V, W;
     45     MGraph Graph;
     46 
     47     Graph = (MGraph)malloc(sizeof(struct GNode));  //建立图
     48     Graph->Nv = VertexNum;
     49     Graph->Ne = 0;
     50     //初始化邻接矩阵
     51     for (V = 0; V < Graph->Nv; V++)
     52         for (W = 0; W < Graph->Nv; W++)
     53             Graph->G[V][W] = INFINITY;
     54     return Graph;
     55 }
     56 
     57 void InsertEdge(MGraph Graph, Edge E)
     58 {
     59     //插入边<V1,V2>
     60     Graph->G[E->V1][E->V2] = E->Weight;
     61     //如果是无向图 还要插入边<V2,V1>
     62     Graph->G[E->V2][E->V1] = E->Weight;
     63 }
     64 
     65 MGraph BuildGraph()
     66 {
     67     MGraph Graph;
     68     Edge E;
     69     Vertex V;
     70     int Nv, i;
     71 
     72     scanf("%d", &Nv);  //读入顶点个数
     73     Graph = CreateGraph(Nv);  //初始化有Nv个顶点但没有边的图
     74 
     75     scanf("%d", &(Graph->Ne));  //读入边数
     76     if (Graph->Ne != 0)        //如果有边
     77     {
     78         E = (Edge)malloc(sizeof(struct  ENode));  //建立边节点
     79         //读入边 格式为 起点 终点 权重 插入邻接矩阵
     80         for (int i = 0; i < Graph->Ne; i++)
     81         {
     82             scanf("%d %d %d", &(E->V1), &(E->V2), &(E->Weight));
     83             InsertEdge(Graph, E);
     84         }
     85     }
     86     //若顶点有数据 读入数据
     87     for (V = 0; V < Graph->Nv; V++)
     88         scanf("%c", &(Graph->Data[V]));
     89     return Graph;
     90 }
     91 
     92 //邻接矩阵 实现广度优先搜索 BFS  利用队列
     93 #define Size 50
     94 int Queue[Size];
     95 int Front=1;
     96 int Rear=0;
     97 int size;
     98 
     99 int Succ(int Value)
    100 {
    101     if (Value < Size)
    102         return Value;
    103     else
    104         return 0;
    105 }
    106 
    107 int IsEmpty()
    108 {
    109     return (size == 0) ? 1 : 0;
    110 }
    111 int IsFull()
    112 {
    113     return (size == Size) ? 1 : 0;
    114 }
    115 void EnQueue(int Element)
    116 {
    117     Rear = Succ(Rear+1);
    118     Queue[Rear] = Element;
    119     size++;
    120 }
    121 int DeQueue()
    122 {
    123     int Element = Queue[Front];
    124     Front = Succ(Front+1);
    125     size--;
    126     return Element;
    127 }
    128 
    129 //利用队列  与树的层序遍历相似
    130 int visited[50];
    131 int IsEdge(MGraph Graph, int V, int W)  //IsEdge 检查<V,W>是否是图Graph中的一条边
    132 {
    133     return (Graph->G[V][W] < INFINITY) ? 1 : 0;
    134 }
    135 void Visit(Vertex V)
    136 {
    137     printf("访问节点%d
    ", V);
    138 }
    139 void BFS(MGraph Graph, Vertex S)    //从节点S出发对以邻接矩阵存储的图Graph进行BFS搜索
    140 {
    141     EnQueue(S);
    142     Visit(S);
    143     visited[S] = 1;
    144 
    145     while (!IsEmpty())
    146     {
    147         Vertex V=DeQueue();
    148         for (int W = 0; W < Graph->Nv; W++)
    149             if (!visited[W] && IsEdge(Graph, V, W))
    150             {
    151                 EnQueue(W);
    152                 Visit(W);
    153                 visited[W] = 1;
    154             }
    155     }
    156 }
    View Code

    PTA第15题 利用 邻接矩阵实现 图 并 用 深度优先搜索(DFS) 和 广度优先搜索(BFS) 输出数据

      1 #define _CRT_SECURE_NO_WARNINGS  
      2 #include<stdio.h>
      3 #include<malloc.h>
      4 #define True 1
      5 #define False 0
      6 typedef struct ENode* Edge;
      7 struct ENode
      8 {
      9     int V1, V2;
     10 };
     11 
     12 typedef struct Graph* MGraph;
     13 struct Graph
     14 {
     15     int Nv;
     16     int Ne;
     17     int G[10][10];
     18 };
     19 
     20 MGraph CreateGraph(int MaxVertex)  //初始化一个没有边的图
     21 {
     22     MGraph Graph = (MGraph)malloc(sizeof(struct Graph));
     23     Graph->Nv = MaxVertex;
     24     Graph->Ne = 0;
     25     for (int i = 0; i < Graph->Nv; i++)
     26         for (int j = 0; j < Graph->Nv; j++)
     27             Graph->G[i][j] =False;
     28     return Graph;
     29 }
     30 
     31 void Insert(MGraph Graph, Edge E)
     32 {    //插入一个无向图
     33     Graph->G[E->V1][E->V2] = 1;
     34     Graph->G[E->V2][E->V1] = 1;
     35 }
     36 
     37 MGraph BuildGraph()
     38 {
     39     MGraph Graph;
     40     Edge E;
     41     int V;
     42     int Nv;
     43     scanf("%d", &Nv);
     44     Graph = CreateGraph(Nv);
     45     scanf("%d
    ", &(Graph->Ne));
     46     if (Graph->Ne)
     47     {
     48         E = (Edge)malloc((sizeof(struct ENode)));
     49         for (int i = 0; i < Graph->Ne; i++)
     50         {
     51             scanf("%d %d
    ", &(E->V1), &(E->V2));
     52             Insert(Graph, E);
     53         }
     54     }
     55     return Graph;
     56 }
     57 //DFS 深度优先遍历
     58 int visited1[11];
     59 int IsEdge(MGraph Graph,int V, int W)
     60 {
     61     return (Graph->G[V][W]==True)? 1 : 0;
     62 }
     63 void Visit(int V)
     64 {
     65     printf("%d ", V);
     66 }
     67 void DFS(MGraph Graph, int V)  //默认从编号最小的点出发 即从V=0出发
     68 {
     69     Visit(V);
     70     visited1[V] = 1;
     71     for (int i = 0; i < Graph->Nv; i++)
     72     {
     73         if (!visited1[i] && IsEdge(Graph, V, i))
     74             DFS(Graph, i);
     75     }
     76 }
     77 void ListComponetsForDFS(MGraph Graph)  //解决图不连通的问题
     78 {
     79     for (int i = 0; i < Graph->Nv; i++)
     80     {
     81         if (!visited1[i])
     82         {
     83             printf("{ ");
     84             DFS(Graph, i);
     85             printf("}
    ");
     86         }
     87     }
     88 }
     89 
     90 //BFS 广度优先遍历
     91 #define Size 11
     92 int visited2[11];
     93 int Queue[11];
     94 int Front = 1;
     95 int Rear = 0;
     96 int size = 0;
     97 int IsEmpty()
     98 {
     99     return (size == 0) ? 1 : 0;
    100 }
    101 int Succ(int Value)
    102 {
    103     if (Value < Size)
    104         return Value;
    105     else
    106         return 0;
    107 }
    108 void EnQueue(int V)
    109 {
    110     Rear = Succ(Rear + 1);
    111     Queue[Rear] = V;
    112     size++;
    113 }
    114 int DeQueue()
    115 {
    116     int V = Queue[Front];
    117     Front = Succ(Front + 1);
    118     size--;
    119     return V;
    120 }
    121 void BFS(MGraph Graph, int V)
    122 {
    123     EnQueue(V);
    124     Visit(V);
    125     visited2[V] = 1;
    126     while (!IsEmpty())
    127     {
    128         int W=DeQueue();
    129         for (int i = 0; i < Graph->Nv; i++)
    130         {
    131             if (!visited2[i] && IsEdge(Graph, W, i))
    132             {
    133                 EnQueue(i);
    134                 Visit(i);
    135                 visited2[i] = 1;
    136             }
    137         }
    138     }
    139 }
    140 void ListComponetsForBFS(MGraph Graph)
    141 {
    142     for (int i = 0; i < Graph->Nv; i++)
    143     {
    144         if (!visited2[i])
    145         {
    146             printf("{ ");
    147             BFS(Graph, i);
    148             printf("}
    ");
    149         }
    150     }
    151 }
    152 int main()
    153 {
    154     MGraph Graph = BuildGraph();
    155     ListComponetsForDFS(Graph);
    156     ListComponetsForBFS(Graph);
    157     return 0;
    158 }
    View Code

    (os:稍微吐槽一句 我现在才认识什么是深度优先搜索和广度优先搜索 上学期就学的人是大佬)

    PTA第16题 007逃生问题  其实也是建图 然后利用图的 深度优先搜索(DFS) 当然广度优先搜索也可以 

    要计算节点之间的路径 我是新建了一个 存坐标的结构体 利用 元素在图里下标 和在 结构体下标一样 来进行计算

    (os:最后找了快一小时bug 最后发现是因为我对递归的理解不过关 以后要抽空写写递归)

      1 #define _CRT_SECURE_NO_WARNINGS  
      2 #include<stdio.h>
      3 #include<malloc.h>
      4 #include<math.h>
      5 #define True 1
      6 #define False 0
      7 #define SizeOfPosition 100
      8 float Length; //跳跃长度
      9 struct  Position
     10 {
     11     int x;
     12     int y;
     13 }Positions[SizeOfPosition];
     14 
     15 float Distance(float x1, float y1, float x2, float y2)
     16 {
     17     return sqrt(((y2 - y1) * (y2 - y1)) + ((x2 - x1) * (x2 - x1)));
     18 }
     19 
     20 typedef struct ENode* Edge;
     21 struct ENode
     22 {
     23     int V1;
     24     int V2;
     25 };
     26 
     27 typedef struct Graph* MGraph;
     28 struct Graph
     29 {
     30     int Nv;
     31     int Ne;
     32     int G[100][100];
     33 };
     34 
     35 MGraph CreateGraph(int MaxVertex)
     36 {
     37     MGraph Graph = (MGraph)malloc(sizeof(struct Graph));
     38     Graph->Nv = MaxVertex;
     39     Graph->Ne = 0;
     40     for (int i = 0; i < Graph->Nv; i++)
     41         for (int j = 0; j < Graph->Nv; j++)
     42             Graph->G[i][j] = 0;
     43     return Graph;
     44 }
     45 
     46 void Insert(MGraph Graph, Edge E)
     47 {  
     48     Graph->G[E->V1][E->V2] = 1;
     49     Graph->G[E->V2][E->V1] = 1;
     50 }
     51 
     52 MGraph BuildGraph()
     53 {
     54     MGraph Graph;
     55     Edge E;
     56     int Nv;
     57     scanf("%d %f
    ", &Nv, &Length);
     58     Graph = CreateGraph(Nv);
     59     for (int i = 0; i < Graph->Nv; i++)
     60     {
     61         int x, y;
     62         scanf("%d %d
    ", &x, &y);
     63         Positions[i].x = x;
     64         Positions[i].y = y;
     65     }
     66     for(int i=0;i<Graph->Nv;i++)
     67         for (int j =i+1; j < Graph->Nv; j++)
     68         {
     69             float dis = Distance(Positions[i].x, Positions[i].y, Positions[j].x, Positions[j].y);
     70             if (dis <=Length)
     71             {
     72                 E = (Edge)malloc(sizeof(struct ENode));
     73                 E->V1 = i;
     74                 E->V2 = j;
     75                 Insert(Graph, E);
     76             }
     77         }
     78     return Graph;
     79 }
     80 int visited[100];
     81 int IsEdge(MGraph Graph,int V,int W)
     82 {
     83     return (Graph->G[V][W] == 1) ? 1 : 0;
     84 }
     85 int Judget(MGraph Graph,int V,float Length)  //深度优先遍历
     86 {
     87     visited[V] = 1;
     88     if (Distance(0, 50, Positions[V].x, Positions[V].y) <= Length|| Distance(0, -50, Positions[V].x, Positions[V].y) <= Length
     89         || Distance(50,0, Positions[V].x, Positions[V].y) <= Length || Distance(-50, 0, Positions[V].x, Positions[V].y) <= Length)
     90         return 1;
     91     for (int i = 0; i < Graph->Nv; i++)
     92     {
     93         if (!visited[i] && IsEdge(Graph, V, i))
     94             if (Judget(Graph, i, Length))
     95                 return 1;
     96     }
     97     return 0;
     98 }
     99 int ListComponets(MGraph Graph)
    100 {
    101     for (int i = 0; i < Graph->Nv; i++)
    102     {
    103         if (!visited[i] && (Length+7.5)>=Distance(0, 0, Positions[i].x, Positions[i].y))
    104             if (Judget(Graph, i, Length))
    105                 return 1;
    106     }
    107     return 0;
    108 }
    109 int main()
    110 {
    111     MGraph Graph;
    112     Graph = BuildGraph();
    113     if (ListComponets(Graph))
    114         printf("Yes");
    115     else
    116         printf("No");
    117     return 0;
    118 }
    View Code
  • 相关阅读:
    正交矩阵(部分转载)
    向量的点乘和叉乘
    随机森林
    PCA和LDA
    SIFT和SURF特征(草稿)
    12-赵志勇机器学习-Label_Propagation
    11-赵志勇机器学习-DBSCAN聚类
    09-赵志勇机器学习-k-means
    10-赵志勇机器学习-meanshift
    09-numpy-笔记-repeat
  • 原文地址:https://www.cnblogs.com/57one/p/11443303.html
Copyright © 2020-2023  润新知