整形图的深度遍历和广度遍历

比较简单的实现,图采用邻接矩阵的存储方式,且没有加上复制构造函数和重载运算符。

#include <iostream>
#include<stdexcept>
#include<stdio.h>
using namespace std;
struct Node
{
    int data;
    Node *next;
    Node(){next=NULL;}
    Node(int item,Node *link=NULL)
    {
        data=item;
        next=link;
    }
};
class LinkQueue
{
protected:
    Node *front,*rear;
    int count;
public:
    LinkQueue(){rear=front=new Node();count=0;}
    virtual ~LinkQueue();
    int length()const{return count;}
    bool Empty()const{return count==0;}
    void Clear();
    void Traverse()const;
    bool OutQueue(int &e);
    bool GetHead(int &e)const;
    bool InQueue(const int &e);
    LinkQueue(const LinkQueue &copy);
    LinkQueue&operator=(const LinkQueue &copy);
};
LinkQueue::~LinkQueue()
{
    Clear();
}
void LinkQueue::Clear()
{
    int tmp;
    while(!Empty())
        OutQueue(tmp);
}
void LinkQueue::Traverse()const
{
    for(Node *tmp=front->next;tmp!=NULL;tmp=tmp->next)
        cout<<tmp->data<<' ';
}
bool LinkQueue::OutQueue(int &e)
{
    if(!Empty())
    {
        Node *tmp=front->next;
        e=tmp->data;
        front->next=tmp->next;
        if(rear==tmp)
            rear=front;
        delete tmp;
        count--;
        return true;
    }
    else
        return false;
}
bool LinkQueue::GetHead(int &e)const
{
    if(!Empty())
    {
        Node *tmp=front->next;
        e=tmp->data;
        return true;
    }
    else
        return false;
}
bool LinkQueue::InQueue(const int &e)
{
    Node *tmp=new Node(e);
    rear->next=tmp;
    rear=tmp;
    count++;
    return true;
}
LinkQueue::LinkQueue(const LinkQueue&copy)
{
    rear=front=new Node();
    count=0;
    for(Node *tmp=copy.front->next;tmp!=NULL;tmp=tmp->next)
        InQueue(tmp->data);
}
LinkQueue&LinkQueue::operator=(const LinkQueue&copy)
{
    if(&copy!=this)
    {
        Clear();
        for(Node *tmp=copy.front->next;tmp!=NULL;tmp=tmp->next)
            InQueue(tmp->data);
    }
    return *this;
}
class AdjMatrixDirGraph
{
protected:
    int vexNum,edgeNum;                             //顶点数和边数
    int **Matrix;                                   //领接矩阵
    int *elems;                                     //顶点元素
    mutable bool *tag;                              //指向标志数组的指针
    void DestroyHelp();                             //销毁有向图
    void DFS(int v)const;                           //从顶点v开始深度优先遍历
    void BFS(int v)const;                           //从顶点v开始广度优先遍历
public:
    AdjMatrixDirGraph(int es[],int vertexNum=10);   //构造数据元素为es,顶点个数为vertexNum,边数为0的有向图
    AdjMatrixDirGraph(int vertexNum=10);            //构造顶点个数为vertexNum变数为0的有向图
    ~AdjMatrixDirGraph();                           //析构函数
    void DFSTraverse()const;                        //对图进行深度优先遍历
    void BFSTraverse()const;                        //对图进行广度优先遍历
    bool GetElem(int v,int &e)const;                //求顶点的元素
    bool SetElem(int v,const int &e);               //设置顶点的元素
    int GetVexNum()const{return vexNum;}            //返回顶点个数
    int GetEdgeNum()const{return edgeNum;}          //返回边的条数
    int FirstAdjVex(int v)const;                    //返回顶点v的第一个邻接顶点
    int NextAdjVex(int v1,int  v2)const;            //返回顶点v1的相对于v2的下一个邻接点
    void InsertEdge(int v1,int v2);                 //插入顶点为v1和v2的边
    void DeleteEdge(int v1,int v2);                  //删除顶点为v1和v2的边
    bool GetTag(int v)const;                        //返回顶点v的标志
    void SetTag(int v,bool val)const;               //设置v1的标志为val
    void Display()const;                            //显示关系矩阵
};
void AdjMatrixDirGraph::DestroyHelp()
{
    delete[] elems;
    delete[] tag;
    for(int i=0;i<vexNum;i++)
        delete []Matrix[i];
    delete []Matrix;
}
void AdjMatrixDirGraph::DFS(int v)const
{
    SetTag(v,true);
    int e;
    GetElem(v,e);
    cout<<e<<' ';
    for(int w=FirstAdjVex(v);w>=0;w=NextAdjVex(v,w))
        if(!GetTag(w))
            DFS(w);
}
void AdjMatrixDirGraph::DFSTraverse()const
{
    int v;
    for(v=0;v<GetVexNum();v++)
        SetTag(v,false);
    cout<<"深度遍历:";
    for(v=0;v<GetVexNum();v++)
        if(!GetTag(v))
            DFS(v);
}
void AdjMatrixDirGraph::BFS(int v)const
{
    SetTag(v,true);
    int e;
    GetElem(v,e);
    cout<<e<<' ';
    LinkQueue q;
    q.InQueue(v);
    while(!q.Empty())
    {
        int u,w;
        q.OutQueue(u);
        for(w=FirstAdjVex(u);w>=0;w=NextAdjVex(u,w))
        {
            if(!GetTag(w))
            {
                SetTag(w,true);
                GetElem(w,e);
                cout<<e<<' ';
                q.InQueue(w);
            }
        }
    }
}
void AdjMatrixDirGraph::BFSTraverse()const
{
    int v;
    for(v=0;v<vexNum;v++)
        SetTag(v,false);
    cout<<"广度遍历:";
    for(v=0;v<vexNum;v++)
        if(!GetTag(v))
            BFS(v);
}
AdjMatrixDirGraph::AdjMatrixDirGraph(int es[],int vetexNum)
{
    if(vetexNum<=0)
        throw runtime_error("顶点数不能小于等于0");
    vexNum=vetexNum,edgeNum=0;
    Matrix=new int*[vexNum];
    elems=new int[vexNum];
    tag=new bool[vexNum];
    for(int i=0;i<vexNum;i++)
        Matrix[i]=new int[vexNum];
    for (int u = 0; u < vexNum; u++)
        for (int v = 0; v < vexNum; v++)
            Matrix[u][v] = 0;
    for(int i=0;i<vexNum;i++)
        elems[i]=es[i];
    for(int i=0;i<vexNum;i++)
        tag[i]=false;
}
AdjMatrixDirGraph::AdjMatrixDirGraph(int vetexNum)
{
    if(vetexNum<0)
        throw runtime_error("顶点数不能小于等于0");
    vexNum=vetexNum,edgeNum=0;
    Matrix=new int*[vexNum];
    elems=new int[vexNum];
    tag=new bool[vexNum];
    for(int i=0;i<vexNum;i++)
        Matrix[i]=new int[vexNum];
    for (int u = 0; u < vexNum; u++)
        for (int v = 0; v < vexNum; v++)
            Matrix[u][v] = 0;
    for(int i=0;i<vexNum;i++)
        tag[i]=false;
}
AdjMatrixDirGraph::~AdjMatrixDirGraph()
{
    DestroyHelp();
}
bool AdjMatrixDirGraph::GetElem(int v,int &e)const
{
    if(v<0||v>=vexNum)
        return false;
    else
    {
        e=elems[v];
        return true;
    }
}
bool AdjMatrixDirGraph::SetElem(int v,const int &e)
{
    if(v<0||v>=vexNum)
        return false;
    else
    {
        elems[v]=e;
        return true;
    }
}
int AdjMatrixDirGraph::FirstAdjVex(int v)const
{
    int i=0;
    while(Matrix[v][i]==0&&i<vexNum)
        i++;
    if(Matrix[v][i]==1)
        return i;
    return -1;
}
int AdjMatrixDirGraph::NextAdjVex(int v1,int v2)const
{
    while(Matrix[v1][++v2]==0&&v2<vexNum)
    if(Matrix[v1][v2]==1)
        return v2;
    return -1;
}
void AdjMatrixDirGraph::InsertEdge(int v1,int v2)
{
    if(v1<0||v1>=vexNum) throw runtime_error("v1不合法");
    if(v2<0||v2>=vexNum) throw runtime_error("v2不合法!");
    if(v1==v2) throw runtime_error("v1不能等于v2!");
    if(Matrix[v1][v2]==0&&Matrix[v2][v1]==0)
        edgeNum++;
    Matrix[v1][v2]=1;
    Matrix[v2][v1]=1;
}
void AdjMatrixDirGraph::DeleteEdge(int v1,int v2)
{
    if(v1<0||v1>=vexNum) throw runtime_error("v1不合法!");
    if(v2<0||v2>=vexNum) throw runtime_error("v2不合法!");
    if(v1==v2) throw runtime_error("v1不能等于v2!");
    if(Matrix[v1][v2]==1&&Matrix[v2][v1]==1)
        edgeNum--;
    Matrix[v1][v2]=0;
    Matrix[v2][v1]=0;
}
bool AdjMatrixDirGraph::GetTag(int v)const
{
    if(v<0||v>=vexNum)
        throw runtime_error("v不合法");
    else
        return tag[v];
}
void AdjMatrixDirGraph::SetTag(int v,bool val)const
{
    if(v<0||v>=vexNum)
        throw runtime_error("v不合法");
    else
        tag[v]=val;
}
void AdjMatrixDirGraph::Display()const
{
    for(int i=0;i<vexNum;i++)
    {
        for(int j=0;j<vexNum;j++)
            cout<<Matrix[i][j]<<' ';
        cout<<endl;
    }
}
int main()
{
    int vetexNum,edgeNum,v1,v2;
    cout<<"请输入顶点个数:";
    cin>>vetexNum;
    int es[vetexNum];
    for(int i=0;i<vetexNum;i++)
    {
        cout<<"请输入顶点编号为"<<i<<"的顶点的值:";
        cin>>es[i];
    }
    AdjMatrixDirGraph g(es,vetexNum);
    cout<<"请输入边的条数:";
    cin>>edgeNum;
    for(int i=0;i<edgeNum;i++)
    {
        cout<<"请输入所要插入的第"<<i+1<<"条边的两个端点(以空格隔开):";
        scanf("%d %d",&v1,&v2);
        g.InsertEdge(v1,v2);
    }
    g.Display();
    g.DFSTraverse();
    g.BFSTraverse();
    return 0;
}
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/cool_flag/article/details/78952597
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞