zoukankan      html  css  js  c++  java
  • 图论算法之最短路径

    原创作品,转载请注明出处http://www.cnblogs.com/leo0000/p/5711576.html 

    自己写了有关了图的读入和无权最短路径和含有负边值的最短路径算法实现。

    其中的迪杰斯特拉算法,求解无负边值的最短路径算法,没有写,因为还没有学习这个配对堆,当然不使用配对堆,使用优先队列也是可以的。

    这个实现中涉及到了队列和散列表。有关优先队列或者说堆的一些操作可以看我的另一篇博客。

    原图:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    typedef struct _queue
    {
        int cursor;
        int lastposition;
        int size;
        int *header;
    }queue;
    
    queue *queueinit(int size)
    {
        queue *ptQ = (queue *)malloc(sizeof(queue));
        ptQ->cursor = 0;
        ptQ->lastposition = 0;
        ptQ->size = size;
        ptQ->header = (int *)malloc(sizeof(int)*size);
        return ptQ;
    }
    
    int Enqueue(int i,queue *ptQ)
    {
        if(ptQ->cursor-ptQ->lastposition == 1 || ptQ->lastposition - ptQ->cursor == ptQ->size -1)
            return -1;
        ptQ->header[ptQ->lastposition] = i;
        if(ptQ->lastposition == ptQ->size -1)
            ptQ->lastposition = 0;
        else
            ptQ->lastposition++;
        return i;
    }
    
    int Dequeue(queue *ptQ)
    {
        if(ptQ->cursor == ptQ->lastposition)
            return 0xffffffff;
        if(ptQ->cursor == ptQ->size -1)
        {
            ptQ->cursor = 0;
            return ptQ->header[ptQ->size-1];
        }
        else
        {
            int tmp = ptQ->header[ptQ->cursor++];
            return tmp;
        }
    }
    
    typedef enum _hashstat
    {
        empty = 0,
        occupied = 1,
        deleted = 2
    }hashstat;
    
    #define namelen 100
    
    typedef struct _hashentry
    {
        char name[namelen];
        hashstat stat;
    }hashentry;
    
    typedef struct _hashtable
    {
        int tablesize;
        hashentry *table;
    }hashtable;
    
    int nextprime(int num)
    {
        int flags = 1;
        int i;
        do{
            for(i = 2;i < sqrt((double)num);i++)
                if(num % i == 0)
                {
                    num++;
                    break;
                }
            if(i>=sqrt((double)num))
                break;
        }while(flags);
        return num;
    }
    
    hashtable *hashinit(int tablesize)
    {
        if(tablesize < 10){
            printf("tablesize is too small
    ");
            return 0;
        }
        tablesize = nextprime(tablesize);
        hashtable *tmp = (hashtable *)malloc(sizeof(hashtable));
        tmp->tablesize = tablesize;
        tmp->table = (hashentry *)malloc(sizeof(hashentry)*tablesize);
        memset(tmp->table,0,sizeof(hashentry)*tablesize);
        return tmp;
    }
    
    int hash(char *key,int tablesize)
    {
        int tmp = 0;
        while(*key!= 0)
            tmp = (tmp<<5)+*key++;
        return tmp%tablesize;
    }
    
    int hashfind(char *key,hashtable *htable)
    {
        int position = 0;
        int collisionNum = 0;
    
        position = hash(key,htable->tablesize);
        while(htable->table[position].stat != empty &&
            strcmp(key,htable->table[position].name) != 0)
        {
            position = position + 2*++collisionNum - 1;
            if(position >= htable->tablesize)
                position = position - htable->tablesize;
        }
        return position;
    }
    
    int hashinsert(char *key,hashtable *htable)
    {
        int position;
        position = hashfind(key,htable);
        if(htable->table[position].stat != occupied)
        {
            htable->table[position].stat = occupied;
            strcpy(htable->table[position].name,key);
        }
        return position;
    }
    
    void printhash(hashtable *htable)
    {
        for (int i = 0;i<htable->tablesize;i++)
        {
            if(htable->table[i].stat ==  occupied)
                printf("%s	%d
    ",htable->table[i].name,i);
        }
    }
    typedef struct _node
    {
        int index;
        int distance;
        struct _node *next;
    }list,node;
    
    typedef struct _edge
    {
        char *s;
        char *d;
        int dist;
    }edge;
    
    typedef struct _tableentry
    {
        list *adjacentlist;
        int known;
        int p;
        int mindist;
        int degree;
        int hashval;
    }tableentry;
    
    typedef struct _graph
    {
        int nVertexNum;
        hashtable *htable;
        tableentry *AdjTable;
    }graph;
    
    void addadjacentvertex(tableentry *t,int i,int distance,graph *ptG)
    {
        node* tmp = 0;
        tmp = (node *)malloc(sizeof(node));
        tmp->index = i;
        tmp->distance = distance;
        if(t->adjacentlist == 0)
            tmp->next = 0;
        else
            tmp->next = t->adjacentlist;
        t->adjacentlist = tmp;
        ptG->AdjTable[i].degree++;
    }
    
    void printpath(graph *ptG,int i)
    {
        if(ptG->AdjTable[i].p == 0){
            printf("%s",ptG->htable->table[i].name);
            return;
        }
        printpath(ptG,ptG->AdjTable[i].p);
        printf("->%s",ptG->htable->table[i].name);
    }
    
    
    void printgraph(graph *ptG,int type)//type == 1 print adjacent list ;type == 2 print the minimum distance to the vertex that the distance is 0 
    {
        for(int i = 0;i<ptG->htable->tablesize;i++)
            if (ptG->htable->table[i].stat == occupied)
            {
                printf("%s : ",ptG->htable->table[i].name);
                if(type == 2)
                    printf("mindist	%d
    ",ptG->AdjTable[i].mindist);
                else if(type == 1){
                    node *cursor = ptG->AdjTable[i].adjacentlist;
                    for(;cursor != 0; cursor = cursor->next){
                        if(type == 1)
                            printf("%s	",ptG->htable->table[cursor->index].name);    
                    }
                    printf("
    ");
                }
                else if(type == 3)
                {
                    printpath(ptG,i);
                    printf("
    ");
                }
            }
    }
    #define INFINITE 0xffffffff
    
    graph* initgraph2(edge e[],int edgeNum,int vertexNum)
    {
        graph *ptG = (graph *)malloc(sizeof(graph));
        ptG->htable = hashinit(vertexNum);
        ptG->AdjTable = (tableentry *)malloc(sizeof(tableentry)*(ptG->htable->tablesize));
        memset(ptG->AdjTable,0,sizeof(tableentry)*(ptG->htable->tablesize));
        ptG->nVertexNum = vertexNum;
        int Shashposition;
        int Dhashposition;
    
        for(int i = 0;i<edgeNum;i++)
        {
            Shashposition = hashinsert(e[i].s,ptG->htable);
            ptG->AdjTable[Shashposition].hashval = Shashposition;
            ptG->AdjTable[Shashposition].mindist = INFINITE;
            Dhashposition = hashinsert(e[i].d,ptG->htable);
            ptG->AdjTable[Dhashposition].hashval = Dhashposition;
            ptG->AdjTable[Dhashposition].mindist = INFINITE;
            addadjacentvertex(&ptG->AdjTable[Shashposition],Dhashposition,e[i].dist,ptG);
        }
        //printhash(ptG->htable);
        printgraph(ptG,1);
        return ptG;
    }
    
    void unweightedpath(graph *ptG,char *key)
    {
        queue *ptQ = queueinit(ptG->nVertexNum);
        int i = hashfind(key,ptG->htable);
        if(ptG->AdjTable[i].hashval != i)
            return;
        Enqueue(i,ptQ);
        int position;
        node *cursor;
        int currdist = 0;
        ptG->AdjTable[i].mindist = 0;
        ptG->AdjTable[i].known = 1;
        while((position = Dequeue(ptQ)) != 0xffffffff)
        {
            cursor = ptG->AdjTable[position].adjacentlist;
            for(;cursor != 0;cursor=cursor->next)
                if(ptG->AdjTable[cursor->index].known == 0)
                {
                    ptG->AdjTable[cursor->index].mindist = currdist + 1;
                    ptG->AdjTable[cursor->index].known = 1;
                    ptG->AdjTable[cursor->index].p = position;
                    Enqueue(cursor->index,ptQ);
                }
            currdist++;
        }
    }
    
    void weightedpath(graph *ptG,char *key)
    {
        queue *ptQ = queueinit(ptG->nVertexNum);
        int i = hashfind(key,ptG->htable);
        if(ptG->AdjTable[i].hashval != i)
            return;
        Enqueue(i,ptQ);
        int position;
        node *cursor;
        int tmpdist = 0;
        ptG->AdjTable[i].mindist = 0;
        ptG->AdjTable[i].known = 1;
        while((position = Dequeue(ptQ)) != 0xffffffff)
        {
            cursor = ptG->AdjTable[position].adjacentlist;
            for(;cursor != 0;cursor=cursor->next)
            {
                tmpdist = ptG->AdjTable[position].mindist + cursor->distance;
                if(tmpdist < ptG->AdjTable[cursor->index].mindist || ptG->AdjTable[cursor->index].mindist == INFINITE)
                {
                    ptG->AdjTable[cursor->index].mindist = tmpdist;
                    ptG->AdjTable[cursor->index].known = 1;
                    ptG->AdjTable[cursor->index].p = position;
                    Enqueue(cursor->index,ptQ);
                }
            }
        }
    }
    
    
    int main()
    {
        graph *ptG;
        edge e[] ={
            {"b","g",1},
            {"a","b",5},
            {"b","c",2},
            {"b","e",3},
            {"g","e",1},
            {"a","c",3},
            {"c","e",7},
            {"d","a",2},
            {"c","d",7},
            {"e","d",2},
            {"e","f",1},
            {"d","f",6},
    
        };
        ptG = initgraph2(e,sizeof(e)/sizeof(edge),20);
        weightedpath(ptG,"a");
        printgraph(ptG,3);
        //initgraph();
        //topsort();
        while(1);
    }
  • 相关阅读:
    微信支付(APP支付)-服务端开发(一)
    C#去除HTML标签
    监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile
    SQL总结(六)触发器
    sql中索引不会被用到的几种情况
    Sql Server参数化查询之where in和like实现详解
    Sql Server查询性能优化之不可小觑的书签查找
    浅析Sql Server参数化查询
    Sql Server查询性能优化之走出索引的误区
    IScroll在某些win10版本下的奇怪问题
  • 原文地址:https://www.cnblogs.com/leo0000/p/5711576.html
Copyright © 2011-2022 走看看