C++--图算法之DFS,BFS,Dijstra

来源:互联网 发布:淘宝联盟导购id 编辑:程序博客网 时间:2024/04/29 14:15

list1.h

#pragma once#include <iostream>#define MAXSIZE 20using namespace std;typedef struct Sidetable                //边表节点结构体 {    int DataPosition;    int Weight;    Sidetable* Next;}Side_Table;typedef struct vertop              //顶点表结构体{    char Data;    Sidetable* Size_Headptr;}vertop;class list1{public:    list1();    ~list1();private:    int Visited[MAXSIZE];    int Nums;    vertop DataArray[MAXSIZE];public:    void Setdata();    int Re_nums(){ return Nums; }    void Visitedclear();    void Set_side();    int Re_position(char );    void DFS1(int);    void BFS();    void Tojz();    void DJjz2(int v0,int v1);    int JZ[MAXSIZE][MAXSIZE];};

point.h

#pragma once#include <iostream>#define MAXSIZE 20using namespace std;typedef struct Sidetable                //边表节点结构体 {    int DataPosition;    int Weight;    Sidetable* Next;}Side_Table;typedef struct vertop              //顶点表结构体{    char Data;    Sidetable* Size_Headptr;}vertop;class list1{public:    list1();    ~list1();private:    int Visited[MAXSIZE];    int Nums;    vertop DataArray[MAXSIZE];public:    void Setdata();    int Re_nums(){ return Nums; }    void Visitedclear();    void Set_side();    int Re_position(char );    void DFS1(int);    void BFS();    void Tojz();    void DJjz2(int v0,int v1);    int JZ[MAXSIZE][MAXSIZE];};

list1.cpp

#include "Point.h"Point::Point(){    num = 0;    name = num;}Point::~Point(){}

list1.cpp

#include "list1.h"#include <iomanip>list1::list1(){    Nums = 0;    for (int i = 0; i <= MAXSIZE; i++)    {        DataArray[i].Data = '\0';              //初始化顶点表数据域        DataArray[i].Size_Headptr = NULL;      //初始化顶点表指针域        Visited[i] = 0;    }}list1::~list1(){    Side_Table* p;    for (int i = 1; i <= Nums; i++)    {        p = DataArray[i].Size_Headptr;        while (p)        {            DataArray[i].Size_Headptr = p->Next;            delete p;            p = DataArray[i].Size_Headptr;        }    }}void list1::Visitedclear(){    for (int i = 0; i < MAXSIZE; i++)    {        Visited[i] = 0;    }}void list1::Setdata(){    int i = 1;    while (cin >> DataArray[i].Data, DataArray[i].Data != 'q')    {        i++;        Nums++;    }}int list1::Re_position(char ch){    int i = 1;    while (i <= Nums)    {        if (DataArray[i].Data == ch)        {            break;        }        i++;    }    return i;}void list1::DFS1(int i){    Side_Table* p;    cout << DataArray[i].Data << " ";    Visited[i] = 1;    p = DataArray[i].Size_Headptr;    while (p != NULL)    {        if (Visited[p->DataPosition] == 0)        {            DFS1(p->DataPosition);        }        p = p->Next;    }}void list1::Set_side(){    int pos1, pos2, weight;                    char ch1, ch2;    Side_Table* p;    while (cin >> ch1 >> ch2 >> weight, ch1 != 'q' && ch2 != 'q')    {        pos1 = Re_position(ch1);                      pos2 = Re_position(ch2);        p = new Side_Table();        p->DataPosition = pos2;        p->Weight = weight;        p->Next = DataArray[pos1].Size_Headptr;        DataArray[pos1].Size_Headptr = p;        p = new Side_Table();                           p->DataPosition = pos1;           p->Weight = weight;        p->Next = DataArray[pos2].Size_Headptr;        DataArray[pos2].Size_Headptr = p;    }}void list1::BFS(){    Visitedclear();    int i, queue[MAXSIZE], front = 0, rear = 0;    Side_Table* p;    cout << DataArray[1].Data << " ";                 //从1开始遍历    Visited[1] = 1;    rear = rear + 1;    queue[rear] = 1;    //入队    while (front != rear)    {        front = front + 1;        i = queue[front];                             p = DataArray[i].Size_Headptr;        while (p != NULL)        {            if (Visited[p->DataPosition] == 0)                        {                cout << DataArray[p->DataPosition].Data << " ";                    Visited[p->DataPosition] = 1;                            rear = rear + 1;                queue[rear] = p->DataPosition;                       }            p = p->Next;        }    }}void list1::Tojz(){    for (int i = 0; i < Nums; i++)    for (int j = 0; j < Nums; j++)    {        if (i == j) JZ[i][j] = 0;        else JZ[i][j] = 999;    }    //cout << Nums << endl;     Side_Table* p;    for (int i = 1; i <= Nums; i++)    {        p = DataArray[i].Size_Headptr;        for (int j = 0; j < Nums; j++)        {            if (p != NULL)            {                       JZ[i-1][p->DataPosition-1] = p->Weight;                p = p->Next;            }        }    }    for (int i = 0; i < Nums; i++)    {        for (int j = 0; j < Nums; j++)        {            cout << setw(3) << JZ[i][j];            cout << " ";        }        cout << endl;    }}void list1::DJjz2(int v0, int v1  ){    //for (int i = 0; i < Nums; i++)    //{    //  for (int j = 0; j < Nums; j++)    //  {    //      cout << setw(3) << JZ[i][j];    //      cout << " ";    //  }    //  cout << endl;    //}    //int num1 = Nums;    //int dist[20];    //bool S[20];                                  // 判断是否已存入该点到S集合中    //int tmp[20];    //int pre = v0;    //for (int i = 0; i < Nums; ++i)    //{    //  dist[i] = JZ[v0][i];    //  S[i] = false;                                    //}    //dist[v0] = 0;    //S[v0] = true;    //tmp[0] = v0;    //int count = 1;    //for (int i = 1; i < Nums; i++)    //{    //  int mindist = 999;    //  int u = v0;                             //  for (int j = 0; j < Nums; ++j)    //  if ((!S[j]) && dist[j]<mindist)    //  {    //      u = j;                                 //      mindist = dist[j];    //  }    //  S[u] = true;    //  tmp[count] = u;    //  count++;    //  if ( (dist[pre] + JZ[pre][u] > dist[u]))    //  {    //      count--;    //      count--;    //      tmp[count] = u;    //      count++;    //  }    //  if (dist[u] + JZ[u][v1] < dist[v1])         //  {    //      dist[v1] = dist[u] + JZ[u][v1];             //  }    //  pre = u;    //}    //count--;    //tmp[count] = v1;    //cout << "路径:" << endl;    //for (int k = 0; k < count + 1; k++)    //{    //  cout << DataArray[tmp[k]+1].Data << " ";    //}    //cout << endl;    //cout << "最短距离为:" << dist[v1] << endl;    int dist[20];    bool S[20];    int tmp[20];    int pre = v0;    for (int i = 0; i < Nums; ++i)    {        dist[i] = JZ[v0][i];        S[i] = false;    }    dist[v0] = 0;    S[v0] = true;    tmp[0] = v0;    int count = 1;    for (int i = 1; i < Nums; i++)    {        int mindist = 999;        int u = v0;        for (int j = 0; j < Nums; ++j)        if ((!S[j]) && dist[j]<mindist)        {            u = j;            mindist = dist[j];        }        S[u] = true;        tmp[count] = u;        count++;        if (i != 0 && (dist[pre] + JZ[pre][u] > dist[u]))        {            count--;            count--;            tmp[count] = u;            count++;        }        if (dist[u] + JZ[u][v1] < dist[v1])        {            dist[v1] = dist[u] + JZ[u][v1];        }        pre = u;    }    count--;    tmp[count] = v1;    cout << "路径:" << endl;    for (int k = 0; k < count + 1; k++)    {        cout << DataArray[tmp[k]+1].Data << " ";    }    cout << endl;    cout << "最短距离为:" << dist[v1] << endl;    cout << endl;}

main.cpp

#include <iostream>#include <cstring>#include <string>#include <list>#include <stack>#include <stdio.h>#include <string.h>#include <iomanip>#include <queue>#include "Point.h"#include "list1.h"using namespace std;void menu(){    cout << "1.建立邻接矩阵" << endl;    cout << "2.建立邻接表" << endl;    cout << "3.DFS测试" << endl;    cout << "4.BFS测试" << endl;    cout << "5.Dijstra求最短路径" << endl;    cout << "0.结束" << endl;}int side[20][20];int Visited[20];int Visited1[20];Point point[20];void DFSjz(int i, int Vertices){    cout << point[i].name << " ";    Visited[i] = 1;    for (int j = 0; j < Vertices; j++)    {        if (side[i][j] != 999 && Visited[j] == 0)        {            DFSjz(j,  Vertices);        }    }}void DJjz1(int v0,int v1,int num1){    int dist[20];    bool S[20];                                      int tmp[20];    int pre=v0;    for (int i = 0; i < num1; ++i)    {        dist[i] = side[v0][i];        S[i] = false;                                   }    dist[v0] = 0;    S[v0] = true;    tmp[0] = v0;    int count = 1;    for (int i = 1; i < num1; i++)    {        int mindist = 999;        int u = v0;                                 for (int j = 0; j < num1; ++j)        if ((!S[j]) && dist[j]<mindist)        {            u = j;                                        mindist = dist[j];        }        S[u] = true;        tmp[count] = u;        count++;        if (i != 0 && (dist[pre] + side[pre][u] > dist[u]))        {            count--;            count--;            tmp[count] = u;            count++;        }        if (dist[u] + side[u][v1] < dist[v1])                 {                dist[v1] = dist[u] + side[u][v1];                       }        pre = u;    }    count--;    tmp[count] = v1;    cout << "路径:" << endl;    for (int k = 0; k < count+1; k++)    {        cout << point[tmp[k]].name << " ";    }    cout << endl;    cout << "最短距离为:" << dist[v1] << endl;    cout << endl;}//struct Queue{                             //用数组模拟队列 //  int queue[20];//  int start;//  int end;//}MyQueue;//void BFSjz( int num){//  int j;//  MyQueue.queue[MyQueue.end++] = 0;//  Visited1[0] = 1;//  while (MyQueue.end != MyQueue.start){//      for (j = 0; j<num; j++){//          if (side[MyQueue.start][j] && !Visited1[j]){//              Visited1[j] = 1;//              MyQueue.queue[MyQueue.end++] = j;//          }//      }//      cout << point[MyQueue.queue[MyQueue.start++]].name << " ";//  }//}queue<int>q;void bfsjz(int i,int num){    int k, j;    cout << point[i].name << " ";    Visited1[i] = 1;//标记顶点i被访问       q.push(i);    while (!q.empty())    {        k = q.front();        q.pop();        //cout<<q.size();          for (j = 1; j <num; j++)        {            if (side[k][j] != 0 && Visited1[j] == 0)            {                cout << point[j].name << " ";                Visited1[j] = 1;                q.push(j);            }        }    }}void BFS(int num){    int i;    //初始化visited数组,表示一开始所有顶点都未被访问过        for (i = 0; i < num; i++)        Visited1[i] = 0;    //广度优先搜索        for (i = 0; i < num; i++)    {        if (Visited1[i] == 0)//如果这个顶点为被访问过,则从i顶点出发进行广度优先遍历               bfsjz( i,num);    }}int main(){    list1 list;    int num;    bool fa = true;    while (fa)    {        menu();        string n;        cin>>n;        if (n[0] == '0')        {            num = 0;            n = "程序结束";            cout << n << endl;            break;        }        switch (n[0])        {        case '1':        {                for (int i = 0; i < 20; i++)                {                    Visited[i] = 0;                }                for (int i = 0; i < 20; i++)                {                    Visited1[i] = -1;                }                cout << "输入点的个数N:" << endl;                while (1)                {                    cin >> num;                    if (num <= 0)                        cout << "输入错误,请输入一个正整数(<20)" << endl;                    else                        break;                }                int m;                cout << "输入边数M:" << endl;                while (1)                {                    cin >> m;                    if (m <= 0)                        cout << "输入错误,请输入一个正整数(<20)" << endl;                    else                        break;                }                for (int i = 0; i < num; i++)                {                        point[i].num = i;                           }                cout << "输入所有端点名;" << endl;                for (int i = 0; i < num; i++)                {                        cin >> point[i].name;                }                for (int i = 0; i<20;i++)                for (int j = 0; j<20; j++)                {                    if (i == j) side[i][j] = 0;                    else                        side[i][j] = 999;                }                cout << "请输入所有的边(2点的位置及两点之间权值,如121),若输入000则输入结束" << endl;                int p1, p2,p3;                while (m--)                {                    cin >> p1 >> p2>>p3;                    if (p1 == 0 && p2 == 0&&p3==0)                        break;                    else                    {                        side[p1-1][p2-1] = p3;                        side[p2 - 1][p1 - 1] = p3;                    }                }                cout << "建立完成,所成矩阵如下" << endl<<"  ";                for (int i = 0; i < num; i++)                {                    cout << point[i].name << " ";                }                cout << endl;                for (int i = 0; i < num; i++)                {                    cout << point[i].name << " ";                    for (int j = 0; j < num; j++)                    {                        cout << setw(3) << side[i][j];                        cout<< " ";                    }                    cout << endl;                }        }            break;        case '2':        {                    cout << "请输入顶点数据(如A B C,以'q'结束输入):";                    list.Setdata();                    cout << "请输入顶点关系及权值(如a b 3,以qq0结束输入):" << endl;                    list.Set_side();                    list.Tojz();        }            break;        case '3':        {            int tmp;            cout << "输入1测试矩阵,输入2测试表" << endl;            while (1)            {                cin >> tmp;                if (tmp == 1)                {                       cout <<"遍历如下(从第一个点开始):"<< endl;                    DFSjz(1, num);                    cout << endl;                    break;                }                else if (tmp == 2)                {                    cout << "遍历如下(从第一个点开始):" << endl;                    list.DFS1(1); // 从第一个开始遍历                      cout << endl;                    break;                }                else                {                    cout << "输入错误,请重新输入" << endl;                }            }        }            break;        case '4':        {                    int tmp;                    cout << "输入1测试矩阵,输入2测试表" << endl;                    while (1)                    {                        cin >> tmp;                        if (tmp == 1)                        {                            cout << "遍历如下(从第一个点开始):" << endl;                            BFS(num);                            cout << endl;                            break;                        }                        else if (tmp == 2)                        {                            cout    << "遍历如下:" << endl;                            list.BFS();                            cout << endl;                            break;                        }                        else                        {                            cout << "输入错误,请重新输入" << endl;                        }                    }        }            break;        case '5':        {                int tmp;                cout << "输入1测试矩阵,输入2测试表" << endl;                while (1)                {                    cin >> tmp;                    if (tmp == 1)                    {                        for (int i = 0; i < num; i++)                        {                            cout << point[i].name << " ";                        }                        cout << endl;                        for (int i = 0; i < num; i++)                        {                            cout << point[i].num << " ";                        }                        cout << endl;                        cout << "输入两点位置(如0 1)" << endl;                        int p1, p2;                        cin >> p1 >> p2;                        DJjz1(p1,p2, num);                        break;                    }                    else if (tmp == 2)                    {                        list.Tojz();                        cout << "输入两点位置(如0 1)" << endl;                        int p1, p2;                        cin >> p1 >> p2;                        list.DJjz2(p1, p2);                        break;                    }                    else                    {                        cout << "输入错误,请重新输入" << endl;                    }                }        }            break;            break;        default:        {                   cout << "输入错误,请重新输入" << endl;        }            break;        }    }    system("pause");    return 0;}
0 0