• 图的相关操作


      1 #include <iostream>
      2 #include <algorithm>
      3 
      4 using namespace std;
      5 const int MaxNum = 100;
      6 const int INF = 99999;
      7 typedef struct srcNode {
      8     int Vem;
      9     struct srcNode * next;
     10 } srcNode;
     11 
     12 typedef struct vNode {
     13     char data;
     14     srcNode *src;
     15 } vNode;
     16 
     17 typedef struct GNode {
     18     int vNum, srcNum;
     19     vNode vNodeList[MaxNum];
     20 } Graph, GNode;
     21 
     22 
     23 /**
     24 *BFS
     25 */
     26 void BFS(Graph *G) {
     27 //    广度优先遍历需要维护一个队列
     28     int v[MaxNum*MaxNum];
     29     int front = -1, rear = -1;
     30     bool visited[MaxNum];
     31     for(int i=0; i<G->vNum; ++i) {
     32         visited[i] = false;
     33     }
     34     v[++rear] = 0;
     35     while(rear!=front) {
     36         int vnow = v[++front];
     37         if(!visited[vnow]) {
     38 //            访问
     39             cout<<G->vNodeList[vnow].data<<endl;
     40             visited[vnow] = true;
     41             srcNode *p = G->vNodeList[vnow].src;
     42             while(p) {
     43                 v[++rear] = p->Vem;
     44                 p = p->next;
     45             }
     46 
     47         }
     48     }
     49 }
     50 
     51 /**
     52 *DFS
     53 */
     54 void DFS(Graph *G) {
     55     int stack[MaxNum*MaxNum];
     56     int top = -1;
     57     bool visited[G->vNum];
     58     for(int i=0; i<G->vNum; ++i) {
     59         visited[i] = false;
     60     }
     61 
     62     stack[++top] = 0;
     63     while(top!=-1) {
     64         int vnow = stack[top--];
     65         if(!visited[vnow]) {
     66             cout<<G->vNodeList[vnow].data<<endl;
     67             visited[vnow] = true;
     68             srcNode *p = G->vNodeList[vnow].src;
     69             while(p) {
     70                 stack[++top] = p->Vem;
     71                 p = p->next;
     72             }
     73         }
     74     }
     75 }
     76 
     77 /**
     78 *DFS递归遍历
     79 */
     80 bool isvisited[MaxNum*MaxNum]= {0};
     81 void DFS(Graph *G, int v) {
     82     cout<<G->vNodeList[v].data<<endl;
     83     isvisited[v] = true;
     84 
     85     srcNode *p = G->vNodeList[v].src;
     86     while(p) {
     87         if(!isvisited[p->Vem]) {
     88             DFS(G, p->Vem);
     89         }
     90         p = p->next;
     91     }
     92 }
     93 
     94 /**
     95 *构造图的邻接链表
     96 */
     97 Graph *createGraph(char v[], int src[][6], int n) {
     98     Graph *G = new Graph();
     99     G->srcNum = 7;
    100     G->vNum = 6;
    101     for(int i=0; i<n; i++) {
    102         G->vNodeList[i].data = v[i];
    103         G->vNodeList[i].src = NULL;
    104 
    105         for(int j=0; j<n; j++) {
    106             if(src[i][j] != INF) {
    107                 srcNode *srcNow = new srcNode();
    108                 srcNow->Vem = j;
    109                 srcNow->next = G->vNodeList[i].src;
    110                 G->vNodeList[i].src = srcNow;
    111             }
    112         }
    113     }
    114     return G;
    115 }
    116 
    117 
    118 /**
    119 *最小生成树
    120 */
    121 void prime(Graph *G, int src[][6]) {
    122 //    维护两个数组
    123     bool isVisited[G->vNum];
    124 //    就是结果集
    125     int parents[G->vNum];
    126 
    127 //    初始化数组
    128     for(int i=0; i<G->vNum; i++) {
    129         isVisited[i] = false;
    130         parents[i] = -1;
    131     }
    132 
    133     isVisited[0] = true;
    134     int n=1;
    135     while(n<G->vNum) {
    136         int minL = INF;
    137         //未访问的节点和已经访问的节点,这两点构成的边
    138         int unvisited, visited;
    139         for(int i=0; i<G->vNum; ++i) {
    140             if(isVisited[i]) {
    141                 visited = i;
    142                 for(int j=0; j<G->vNum; ++j) {
    143                     if(!isVisited[j] && src[i][j] < minL) {
    144                         minL = src[i][j];
    145                         unvisited = j;
    146                     }
    147                 }
    148             }
    149 
    150         }
    151 
    152         isVisited[unvisited] = true;
    153         parents[unvisited] = visited;
    154         n++;
    155     }
    156 
    157 //    输出树
    158     for(int i=0; i<G->vNum; i++) {
    159         cout<<i<<":"<<parents[i]<<endl;
    160     }
    161 
    162 }
    163 
    164 /**
    165 *Kruskal
    166 */
    167 //点边对
    168 typedef struct VS {
    169     int x, y;
    170     int length;
    171 } VS;
    172 int com(VS vs1, VS vs2) {
    173     return vs1.length>vs2.length;
    174 }
    175 //讲边按照长度进行排序
    176 int VSsort(VS vsarray[], int src[][6], int vNum) {
    177     int top = -1;
    178 //    将所有节点封装成点边对,装入数组
    179     for(int i=0; i<vNum; ++i) {
    180         for(int j=0; j<vNum; ++j) {
    181             if(src[i][j] != INF) {
    182                 VS vsnode;
    183                 vsnode.x = i;
    184                 vsnode.y = j;
    185                 vsnode.length = src[i][j];
    186                 vsarray[++top] = vsnode;
    187             }
    188         }
    189     }
    190     sort(vsarray, vsarray+top+1, com);
    191     return top;
    192 }
    193 
    194 int findRoot(int v, int parents[]) {
    195     if(parents[v] == -1) {
    196         return v;
    197     }
    198     return findRoot(parents[v], parents);
    199 }
    200 
    201 bool unionV(int v1, int v2, int parents[]) {
    202     int v1root = findRoot(v1, parents);
    203     int v2root = findRoot(v2, parents);
    204     if(v1root == v2root) {
    205         return false;
    206     }
    207     parents[v1root] = v2root;
    208     return true;
    209 }
    210 
    211 void Kruskal(int src[][6], int vNum) {
    212     VS vsArray[MaxNum];
    213     int top = VSsort(vsArray, src, vNum);
    214     //并查集 ,并非结果集
    215     int parents[vNum];
    216     int result[vNum];
    217     for(int i=0; i<vNum; ++i) {
    218         parents[i] = -1;
    219         result[i] = -1;
    220     }
    221 
    222     int n=0;
    223     while(n < vNum-1) {
    224         VS vsnode = vsArray[top--];
    225         if(unionV(vsnode.x, vsnode.y, parents)) {
    226             result[vsnode.x] = vsnode.y;
    227             n++;
    228         }
    229     }
    230 
    231     //    输出树
    232     for(int i=0; i<vNum; i++) {
    233         cout<<i<<":"<<result[i]<<endl;
    234     }
    235 }
    236 /**
    237 *多源最短路径
    238 */
    239 void flyoed(int src[][6], int origition, int destination) {
    240     int length[6][6];
    241     int parents[6][6];
    242 //    备份路径长度,不能在原来上边更改
    243     for(int i=0; i<6; i++) {
    244         for(int j=0; j<6; ++j) {
    245             length[i][j] = src[i][j];
    246             parents[i][j] = j;
    247         }
    248 
    249     }
    250 
    251     for(int i=0; i<6; i++) {
    252         for(int j=0; j<6; j++) {
    253             for(int k=0; k<6; k++) {
    254                 if((length[j][i] + length[i][k]) < length[j][k]) {
    255                     length[j][k] = (length[j][i] + length[i][k]);
    256                     parents[j][k] = parents[j][i];
    257                 }
    258             }
    259         }
    260     }
    261     cout<<length[origition][destination]<<endl;
    262     cout<<origition<<" ";
    263     int ori = origition;
    264     while(ori != destination) {
    265         cout<<parents[ori][destination]<<" ";
    266         ori = parents[ori][destination];
    267     }
    268 
    269 }
    270 /**
    271 *单源最短路径
    272 */
    273 void Dijkstra(int src[][6], int origition, int destination) {
    274     int path[6];
    275 //    表示到目标点距离
    276     int length[6];
    277     bool isvisited[6];
    278     for(int i=0; i<6; i++) {
    279         path[i] = -1;
    280         length[i] = src[i][destination];
    281         isvisited[i] = false;
    282     }
    283     isvisited[destination] = true;
    284     for(int i=0; i<6; i++) {
    285         int nowShortestNode = destination;
    286 //        从未收录的点中找一个到目标点距离最小的
    287         for(int j=0; j<6; j++){
    288             if(!isvisited[j] && length[j] < length[nowShortestNode]){
    289                 nowShortestNode = j;
    290             }
    291         }
    292         isvisited[nowShortestNode] = true;
    293 //        刷新其他顶点经过这个最小的点,到目标顶点的距离
    294         for(int j=0; j<6; j++){
    295             if(!isvisited[j] && (src[j][nowShortestNode] +length[nowShortestNode])< length[j]){
    296                 length[j] = src[j][nowShortestNode] +length[nowShortestNode];
    297                 path[j] = nowShortestNode;
    298             }
    299         }
    300 
    301     }
    302 
    303 //    输出路径
    304     cout<<length[origition]<<endl;
    305     int p = origition;
    306     cout<<p<<" ";
    307     while(path[p] != -1){
    308         cout<<path[p]<<" ";
    309         p = path[p];
    310     }
    311     cout<<destination;
    312 
    313 }
    314 void show(Graph *G) {
    315     for(int i=0; i<G->vNum; i++) {
    316         srcNode *p = G->vNodeList[i].src;
    317         while(p) {
    318             cout<<G->vNodeList[p->Vem].data<<"  ";
    319             p = p->next;
    320         }
    321         cout<<endl;
    322     }
    323 }
    324 
    325 int main() {
    326     char v[]= {'a', 'b', 'c', 'd', 'e', 'f'};
    327     int src[6][6] = {
    328 
    329         { INF, 6,INF,INF, 7,INF},
    330         {  6,INF, 2, 3,INF, 5 },
    331         { INF, 2,INF,INF, 1, 5 },
    332         { INF, 3,INF,INF,INF, 4 },
    333         {  7,INF, 1,INF,INF,INF},
    334         { INF, 5, 5, 4,INF,INF},
    335     };
    336 
    337     Graph *G = createGraph(v, src, 6);
    338 //    prime(G, src);
    339 //    Kruskal(src, 6);
    340 //    show(G);
    341 //    BFS(G);
    342 //    DFS(G);
    343 //    cout<<"**********************"<<endl;
    344 //    DFS(G, 0);
    345     flyoed(src,5, 4);
    346     cout<<endl;
    347     Dijkstra(src, 5, 4);
    348 }
    View Code
  • 相关阅读:
    struct 结构体解析(原)
    C++标准编程:虚函数与内联
    基于 IOCP 的通用异步 Windows Socket TCP 高性能服务端组件的设计与实现
    直接用编译器按ctrl+F5运行和双击运行结果不一样
    驱动编译的时候注意编译工程选项
    驱动编译的时候注意编译工程选项
    'ddkbuild.cmd' 不是内部或外部命令,也不是可运行的程序
    'ddkbuild.cmd' 不是内部或外部命令,也不是可运行的程序
    NtOpenProcess被HOOK,跳回原函数地址后仍然无法看到进程
    NtOpenProcess被HOOK,跳回原函数地址后仍然无法看到进程
  • 原文地址:https://www.cnblogs.com/zhishoumuguinian/p/11761443.html
Copyright © 2020-2023  润新知