广搜-point-to-point最短距离(大文件)-邻接表

#include <iostream>
#include <cstdio>
#include <stack>
#include <vector>
#include <queue>
#include <ctime>
#include <cstdlib>




using namespace std;




///图的邻接表
struct AdjList
{
    int vertex;
    int weight;
    AdjList *LowNext;///指向下一个头节点
    AdjList *rNext;///指向节点的邻居
};


struct queue_node
{
    int node;
    int precursor;
};


///endresult.txt
const int edges  = 10001;///图中顶点数
int  edge[edges][edges];///邻接矩阵
int MIN_Value = 0x7fffffff;
bool isGray[edges];///标记节点是否被访问过


std::stack<int> path;


std::queue<int> graph_queue;
std::queue<int> edge_weight;
std::vector<queue_node> path_report;


AdjList *AdjHead = NULL;


void CreateAdjList(int node1,int node2,int weight)
{


    //cout<<"创建图的邻接表"<<endl;
    AdjList *pNode ;
    if(AdjHead == NULL)
    {
        ///cout<<"创建头节点"<<endl;
        AdjHead = new AdjList();
        pNode = new AdjList();
        AdjHead->vertex = node1;
        AdjHead->LowNext = NULL;
        AdjHead->rNext = pNode;


        pNode->vertex = node2;
        pNode->weight = weight;
        pNode->rNext = NULL;
        pNode->LowNext = NULL;
       /// return AdjHead;
    }


    pNode = AdjHead;
    AdjList *preNode = pNode;
    AdjList *qNode ;
    while(pNode)
    {
        ///cout<<"创建中间节点"<<endl;
        if(pNode->vertex == node1)
        {
           qNode = new AdjList();
           qNode->vertex = node2;
           qNode->weight = weight;
           qNode->rNext = pNode->rNext;
           pNode->rNext = qNode;


           qNode->LowNext = NULL;
           break;
        }
        preNode = pNode;
        pNode = pNode->LowNext;


    }
    AdjList *TempNode;
    if(pNode == NULL)
    {
        qNode = new AdjList();
        qNode->vertex = node1;
        qNode->weight = 0;


        TempNode = new AdjList();
        TempNode->vertex = node2;
        TempNode->weight = weight;


        ///把qnode(向下)链接上
        pNode = AdjHead;
        qNode->LowNext = pNode->LowNext;
        pNode->LowNext = qNode;


        ///把TempNode链接到qNode右面 后面
        qNode->rNext = TempNode;
        TempNode->rNext = NULL;
        TempNode->LowNext = NULL;
    }
   /// return AdjHead;
}


///读图文件 -》放入邻接链表
void readFileEdge()
{
    int node1,node2,weight;
    char filename[20] ;
    cout<<"please input graph file name :";
    cin>>filename;
    FILE *read_resultFile = fopen(filename,"r");


    if(read_resultFile == NULL)
    {
        cout<<"open endresult.txt fail"<<endl;
        return ;
    }
    cout<<"正在读文件,初始化图邻接矩阵"<<endl;
    while(!feof(read_resultFile))
    {
        fscanf(read_resultFile,"%d  %d  %d",&node1,&node2,&weight);
        //edge[node1][node2] = weight;
        if(!feof(read_resultFile))
        {
            CreateAdjList(node1,node2,weight);
            CreateAdjList(node2,node1,weight);
            ///cout<<"***********"<<endl;
        }


    }


    fclose(read_resultFile);


}
///判断节点i是否被访问过
void visit()
{
    for(int i=1;i<edges;i++)
        isGray[i] = false;
}




///利用队列金广度优先搜索
int bfs(int source,int target)
{
    if(source == target)return 0;
    int distance;


    ///利用path_report 记录路径和前驱;
    struct queue_node que ;
    que.node = source;
    que.precursor = 0;
    path_report.push_back(que);




    graph_queue.push(source);
    edge_weight.push(0);
    int queue_head ;
    AdjList *pNode = AdjHead;
    while(!graph_queue.empty())
    {
        queue_head = graph_queue.front();
        isGray[queue_head] = true;
        distance = edge_weight.front();


        graph_queue.pop();
        edge_weight.pop();
        pNode = AdjHead;
        while(pNode)
        {


            if(pNode->vertex == queue_head)
            {
                ///pNode->weight += queue_head->weight;
                break;
            }


            pNode = pNode->LowNext;
        }
        AdjList *qNode = pNode;
        if(pNode)
            qNode = pNode->rNext;
        while(qNode)
        {


            ///qNode->weight += pNode->weight;
            if(qNode->vertex == target)///找到目的节点
            {
                que.node = qNode->vertex;
                que.precursor = pNode->vertex;
                path_report.push_back(que);
                if(distance + qNode->weight < MIN_Value)///如果当前最短距离最小,赋给最小值
                {
                    MIN_Value = distance +  qNode->weight;
//                    while(!path.empty())
//                        path.pop();
//                    vector<struct queue_node>::iterator ite ;
//                    int temp = target;
//                    for(ite = path_report.end();ite>=path_report.begin();ite--)
//                    {
//                        if(ite->node == temp)
//                        {
//                            path.push(ite->node);
//                            cout<<"path : "<<ite->node<<"->";
//                            temp = ite->precursor;
//                        }
//
//                    }cout<<endl;
                }




            }


            else if(isGray[qNode->vertex] == false)
            {
                ///插入到路径记录中
                ///que = new queue_node();
                que.node = qNode->vertex;
                que.precursor = pNode->vertex;
                path_report.push_back(que);


                graph_queue.push(qNode->vertex);
                edge_weight.push(distance + qNode->weight);
//                 cout<<"graph_queue.front ="<<queue_head<<"----";
//                cout<<"edge_queue.front ="<<distance<<endl;
            }




            qNode = qNode->rNext;
        }


    }
    return MIN_Value;
}


void print_stack()
{
    cout<<"shortest path is : ";
    while(!path.empty())
    {
        cout<<path.top()<<"->";
        path.pop();
    }
}


void print_vector()
{
    vector<struct queue_node>::iterator ite;
    for(ite = path_report.begin();ite!=path_report.end();ite++)
    {
        cout<<"current node :"<<ite->node<<"    pre node :"<<ite->precursor<<endl;
    }
}


int main()
{
    ///AdjList *source,*target,*pNode;
    srand((unsigned) time(NULL));
    int s = rand()%(edges - 1) + 1;
    int t = rand()%(edges - 1) + 1;
    int distance;
    isGray[s] = true;
    readFileEdge();
    AdjList *pNode = AdjHead;
    AdjList *qNode = AdjHead;
   // cout<<"head->weight "<<AdjHead->vertex<<endl;
//    while(pNode)
//    {
//        qNode = pNode;
//        while(qNode)
//        {
//            cout<<qNode->vertex<<"->";
//            qNode = qNode->rNext;
//        }
//        cout<<endl;
//        pNode = pNode->LowNext;
//    }
   /// cout<<MIN_Value<<endl;
    distance = bfs(s,t);
    cout<<s<<"->"<<t<<" shotest path length :"<<distance<<endl;
//    print_stack();
//    print_vector();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值