关于图的一些基本算法实现

	邻接矩阵存储,二维数组创建,暂时没发现什么问题。
			1.深度优先遍历
			2.广度优先遍历
			3.最小生成树(Kruskal)
			4.最短路径(Dijkstra)
			5.关键路径,求事件最早发生(递归和非递归俩种),其他同理。


//
// Created by wen on 2021/2/23.
//GlobalVar.h
//

#ifndef MAIN_CPP_GLOBALVAR_H
#define MAIN_CPP_GLOBALVAR_H

typedef char TElemType;
typedef int EdgeType;

//创建二维数组,返回行为n,列为m的二位数组指针
int** create(int n, int m);

#endif //MAIN_CPP_GLOBALVAR_H

//
// Created by wen on 2021/2/23.
//GlobalVar.cpp

#include<malloc.h>
#include"GlobalVar.h"

int** create(int row,int column) {
    int** num;
    int*** temp;
    temp = &num;
    num = (int**)malloc(sizeof(int*) * row);
    for (int i = 0; i < row; i++)
    {
        num[i] = (int*)malloc(sizeof(int)*column);
    }
    return *temp;
}
//
// Created by wen on 2021/2/23.
//Map.h

#ifndef MAIN_CPP_MAP_H
#define MAIN_CPP_MAP_H
#include"GlobalVar.h"

#define MVALUE 65535    //用65535表示∞
typedef struct {
    int number;
    TElemType info;
}VertexType;
typedef struct
{
    VertexType *vers;   //顶点表,编号和信息
    EdgeType **arc;    //邻接矩阵,可看作边表
    int numVertexes;  //顶点数
    int numEdges;    //边数
    bool *iterate;  //遍历标记
    int *minspantree; //最小生成树
    int *shortestpath;//最短路径
}MGraph;
bool createMGraph(MGraph* M,int **array,int vers,int edges,TElemType *info);//创建

int nextNodeOfMGraph(MGraph* M, int firstnumber,int number);
int firstNodeOfMGraph(MGraph* M, int number);//返回邻接点,用于遍历

void dfsMGraph(MGraph* M);
void dfsMGraphInternal(MGraph* M,int number,void (*iterate)(VertexType));//深度优先

void bfsMGraph(MGraph* M);
void bfsMGraphInternal(MGraph* M,int number,void (*iterate)(VertexType));//广度优先


void printMGraphVers(VertexType vertexType);//遍历方法(打印)

void minimum_Spanning_Tree_Kruskal(MGraph* M,int node);//最小生成树,node为开始节点

void shortest_Route_Dijkstra(MGraph* M,int node);      //最短路径,node为开始节点

int* topological_sorting(MGraph M);//拓扑排序,返回排序后的数组

int event_early_length(MGraph M,int nodenumber);//递归求一点到初始点的最长长度,即单个事件最早发生时间;

int* event_early(MGraph M);//求事件最早发生事件,返回数组,关键路径第一步
#endif //MAIN_CPP_MAP_H

//Map.cpp
#include<stdio.h>
#include<malloc.h>
#include"Map.h"

bool createMGraph(MGraph* M, int** array, int vers, int edges, TElemType* info) {
    //输入数组规范问题,待解决

    M->numEdges = edges;
    M->numVertexes = vers;
    //
    M->vers = (VertexType*)malloc(sizeof(VertexType) * vers);
    M->iterate = (bool*)malloc(sizeof(bool) * vers);
    for (int i = 0; i < vers; i++)
    {
        M->vers[i].number = i;
        M->vers[i].info = info[i];
        M->iterate[i] = false;
    }
    //
    M->arc = create(vers, vers);
    for (int i = 0; i < vers; i++)
    {
        for (int j = 0; j < vers; j++)
        {
            M->arc[i][j] = array[i][j];
        }
    }
    //
    return true;
}


int nextNodeOfMGraph(MGraph* M, int firstnumber, int number) {
    if (number >= M->numVertexes) {
        return -1;
    }

    for (int  i = number+1; i < M->numVertexes; i++)
    {
        if (M->arc[firstnumber][i]!=0)
        {
            return i;
        }
    }
    return -1;
}

int firstNodeOfMGraph(MGraph* M, int number) {
    if (number >= M->numVertexes) {
        return -1;
    }
    for (int i = 0; i < M->numVertexes; i++)
    {
        if (M->arc[number][i] != 0) {
            return i;
        }
    }
    return -1;

}

void dfsMGraph(MGraph* M){
    for (int i = 0; i < M->numVertexes; ++i) {
        M->iterate[i] = false;
    }
    for (int i = 0; i < M->numVertexes; ++i) {
        if(!M->iterate[i]){
            dfsMGraphInternal(M,i,printMGraphVers);
        }
    }
}
void dfsMGraphInternal(MGraph* M,int number,void (*iterate)(VertexType)){
    int node =firstNodeOfMGraph(M, number);
    M->iterate[number]= true;
   // printf("%c",M->vers[number].info);
    iterate(M->vers[number]);
    while(node!=-1){
        if(!M->iterate[node]) {
            dfsMGraphInternal(M, node, iterate);
        }
        node =nextNodeOfMGraph(M,number,node);
    }

}

void bfsMGraph(MGraph* M){
    for (int i = 0; i < M->numVertexes; ++i) {
        M->iterate[i] = false;
    }
    for (int i = 0; i < M->numVertexes; ++i) {
        if(!M->iterate[i]){
            bfsMGraphInternal(M,i,printMGraphVers);
        }
    }
}
void bfsMGraphInternal(MGraph* M,int number,void (*iterate)(VertexType)){
    int front,rear;
    VertexType node;
    int nodeNumber;
    front=rear=0;
    VertexType *vertex = (VertexType*)malloc(sizeof (VertexType)*M->numVertexes);
    rear = (rear+1)%M->numVertexes;
    vertex[rear]=M->vers[number];
    M->iterate[number]= true;
    while (front!=rear){
        front = (front+1)%M->numVertexes;
        node = vertex[front];
        iterate(node);
        //
        nodeNumber = firstNodeOfMGraph(M,node.number);
        while (nodeNumber!=-1){
            if(!M->iterate[nodeNumber]) {
                M->iterate[nodeNumber]= true;
                rear = (rear + 1) % M->numVertexes;
                vertex[rear] = M->vers[nodeNumber];
            }
            nodeNumber = nextNodeOfMGraph(M, node.number, nodeNumber);
        }

    }

}

void printMGraphVers(VertexType vertexType){
    printf("%c", vertexType.info);
}

void minimum_Spanning_Tree_Kruskal(MGraph* M,int node){
    if (node>=M->numVertexes||node<0){
        printf("开始节点错误,结束添加!");
        return;
    }
    //初始化
    int sum=0;
    int count=0;
    M->minspantree =(int *)malloc(sizeof (int)*(M->numVertexes+1));//最后放总长度
    for (int i = 0; i < M->numVertexes ; ++i) {
        M->iterate[i] = false;
        if(node!=i) {
            M->minspantree[i] = M->arc[node][i];
        }
    }
    M->iterate[node]= true;
    printf(" 初始化,根节点%d开始生成树",node);
    count++;

    //开始添加点
    for (int i = 0; i < M->numVertexes-1; ++i) {
        int minnumber=0;//default:0
        int minvalue =M->minspantree[0];
        for (int j = 1; j < M->numVertexes; ++j) {
            if(minvalue>M->minspantree[j]&&(!M->iterate[j])){
                minvalue=M->minspantree[j];
                minnumber =j;
            }
        }
        count++;
        sum +=minvalue;
        M->iterate[minnumber] = true;
        printf("\n 第%d次添加,添加点%d,目前最小生成树长度为%d",count,minnumber,sum);
        for (int j = 0; j < M->numVertexes; ++j) {
            if(!M->iterate[j]){
                M->minspantree[j]= M->arc[minnumber][j] < M->minspantree[j]?M->arc[minnumber][j]:M->minspantree[j];
            }
        }
    }
    M->minspantree[M->numVertexes]=sum;
}
void shortest_Route_Dijkstra(MGraph* M,int node){
    if (node>=M->numVertexes||node<0){
        printf("开始节点错误,结束添加!");
        return;
    }
    int count =0;
    M->shortestpath =(int*)malloc(sizeof (int)*M->numVertexes);
    int *pathlenth =(int*)malloc(sizeof (int)*M->numVertexes);

    for (int i = 0; i < M->numVertexes; ++i) {
        M->iterate[i] = false;
        pathlenth[i] = M->arc[node][i];
        if(node!=i) {
            M->shortestpath[i] = node;
        }
    }
    count++;
    M->iterate[node]= true;

    M->shortestpath[node]=-1;//初始节点

    for (int i = 0; i < M->numVertexes-1; ++i) {
        int minnumber=0;
        int minvalue=pathlenth[0];
        for (int j = 0; j < M->numVertexes; ++j){
            if( (!M->iterate[j]) && minvalue>pathlenth[j]){
                minvalue=pathlenth[j];
                minnumber=j;
            }
        }
        M->iterate[minnumber]= true;
        count++;
        printf("\n第%d次添加,添加节点%d",count,minnumber);
        for (int k = 0; k < M->numVertexes; ++k) {
            if(!M->iterate[k]){
                bool flag;
                pathlenth[k] =  (flag =(pathlenth[minnumber]+M->arc[minnumber][k]   <   pathlenth[k]))?
                               (pathlenth[minnumber]+M->arc[minnumber][k]) : pathlenth[k];
                if(flag) {
                    M->shortestpath[k] = minnumber;//路径更新则更新路径表
                }
            }
        }
    }
}

int ifexist(MGraph* M){//判断图中是否有入度为0的节点,有则返回,同时置iterate数组中该节点为true
    for (int i = 0; i < M->numVertexes; ++i) {
        if (!M->iterate[i]){
            int count =0;
            for (int j = 0; j < M->numVertexes; ++j) {
                if(M->arc[j][i]==MVALUE){
                    count++;
                }
            }
            if (count==M->numVertexes){
                return i;
            }
        }
    }
    return -1;
}
int*  topological_sorting(MGraph M){
    int* sortedqueue =(int*)malloc(sizeof(int)*M.numVertexes);
    int* re =sortedqueue;
    int nextnumber;
    while ((nextnumber=ifexist(&M))!=-1){
        *sortedqueue=nextnumber;
        sortedqueue++;
        M.iterate[nextnumber]= true;
        for (int i = 0; i < M.numVertexes; ++i) {
            M.arc[nextnumber][i]=MVALUE;
        }
    }
    return re;
}

bool ifexist_node(MGraph M,int nodenumber){
    if (M.numVertexes<nodenumber){
        return false;
    }
    int count =0;
    for (int i = 0; i < M.numVertexes; ++i) {
       if( M.arc[i][nodenumber]==MVALUE){
           count++;
       }
    }
    if (count==M.numVertexes){
        return true;
    }
    return false;
}


int nextPrecursorNode(MGraph *M,int nodenumber){

    for (int i = 0; i < M->numVertexes; ++i) {
        if (M->arc[i][nodenumber]!=MVALUE && !M->iterate[i]){
            M->iterate[i]= true;
            return i;
        }

    }
    return -1;
}


int event_early_length(MGraph M,int nodenumber){
    if (ifexist_node(M,nodenumber)){
        return 0;
    }
    int number;
    int maxlenthofpath=0;
    int maxnumberofpath=-1;
    while ((number=nextPrecursorNode(&M,nodenumber))!=-1){
        int temp=event_early_length(M,number);
        if (maxlenthofpath<(M.arc[number][nodenumber]+temp)){
                maxlenthofpath =M.arc[number][nodenumber]+temp;
                maxnumberofpath =number;
        }
    }

    return maxlenthofpath;
}

int* event_early(MGraph M){
    int *length =(int *)malloc(sizeof(int)*M.numVertexes);
    int *re =length;
    for (int i = 0; i < M.numVertexes; ++i) {
        length[i]=0;
    }
    int number ;
    while ((number=ifexist(&M))!=-1){
        M.iterate[number]= true;
        for (int i = 0; i < M.numVertexes; ++i) {
            if (M.arc[number][i]!=MVALUE){
                length[i] =M.arc[number][i]+length[number] >length[i] ?M.arc[number][i]+length[number]:length[i];
                M.arc[number][i]=MVALUE;
            }

        }
    }
    return re;
}
//main.cpp
#include <stdio.h>
#include <malloc.h>
#include "Map.h"


int main() {
    int array[8][8] ={
            {MVALUE,30,    MVALUE,MVALUE,10,    MVALUE,MVALUE,MVALUE},
            {MVALUE,MVALUE,20,    MVALUE,MVALUE,MVALUE,MVALUE,MVALUE},
            {MVALUE,MVALUE,MVALUE,15,    MVALUE,MVALUE,MVALUE,MVALUE},
            {MVALUE,MVALUE,MVALUE,MVALUE,MVALUE,MVALUE,MVALUE,MVALUE},
            {MVALUE,15,    MVALUE,MVALUE,MVALUE,7,     MVALUE,MVALUE},
            {MVALUE,3,     16,    MVALUE,MVALUE,MVALUE,8,     MVALUE},
            {MVALUE,MVALUE,6,     3,     MVALUE,MVALUE,MVALUE,10},
            {MVALUE,MVALUE,MVALUE,6,     MVALUE,MVALUE,MVALUE,MVALUE},
    };
    int** data = create(8, 8);
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            data[i][j] = array[i][j];
        }
    }
    TElemType info[8] = { 'a','b','c','d','e','f','g','h'};
    MGraph M;
    createMGraph(&M, data, 8, 13, info);
//    dfsMGraph(&M);
//    printf("\n");
//    bfsMGraph(&M);
   // minimum_Spanning_Tree_Kruskal(&M,0);
   // printf("\n长度为%d",M.minspantree[M.numVertexes]);
//   shortest_Route_Dijkstra(&M,0);
//    printf("\n");
//    for (int i = 0; i < M.numVertexes; ++i) {
//        printf("%d ",M.shortestpath[i]);
//    }
   // int *path  =(int *)malloc(sizeof(int)*M.numVertexes);
  //  printf("%d",event_early_length(M,3));
    int *length =event_early(M);
    for (int i = 0; i < M.numVertexes; ++i) {
        printf(" %d",length[i]);
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值