深度优先遍历实例(C++)

问题描述:
用图的邻接矩阵的方法存储一个图(图的节点是整数),然后对图进行深度优先遍历,输出图的深度优先遍历的序列,并输出其中最大的节点的值。
+-+
#include 
using namespace std;
int value=-30000;//用于查找所有节点中值最小的节点值
enum StatusCode {SUCCESS, FAIL, UNDER_FLOW, OVER_FLOW,RANGE_ERROR, DUPLICATE_ERROR,
    NOT_PRESENT, ENTRY_INSERTED, ENTRY_FOUND, VISITED, UNVISITED
};
int DEFAULT_SIZE=100;

// 无向图的邻接矩阵类模板
template 
class AdjMatrixUndirGraph
{
protected:
    // 邻接矩阵的数据成员:
    int vexNum, edgeNum;                        // 顶点个数和边数
    int **Matrix;                                // 邻接矩阵
    ElemType *elems;                            // 顶点数据
    StatusCode *tag;                    // 指向标志数组的指针
    
    // 辅助函数模板:
    void DestroyHelp();                            // 销毁无向图,释放无向图占用的空间
    void DFS(int v);
public:
    //
    // 抽象数据类型方法声明及重载编译系统默认方法声明:
    AdjMatrixUndirGraph(ElemType es[], int vertexNum = DEFAULT_SIZE);
    // 构造数据元素es[],顶点个数为vertexNum,边数为0的无向图
    AdjMatrixUndirGraph(int vertexNum = DEFAULT_SIZE);
    // 构造顶点个数为vertexNum,边数为0的无向图
    ~AdjMatrixUndirGraph();                        // 析构函数模板
    //
    StatusCode GetElem(int v, ElemType &e) const;// 求顶点的元素,得到顶点元素的值
    StatusCode SetElem(int v, const ElemType &e);// 设置顶点的元素值
    //
    int GetVexNum() const;                        // 返回顶点个数
    int GetEdgeNum() const;                        // 返回边数
    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的边
    //
    StatusCode GetTag(int v) const;                // 返回顶点v的标志
    void SetTag(int v, StatusCode val) const;    // 设置顶点v的标志为val
    //
    void DFSTraverse();//深度优先遍历
    //
    AdjMatrixUndirGraph(const AdjMatrixUndirGraph ©);    // 复制构造函数模板
    AdjMatrixUndirGraph &operator =(const AdjMatrixUndirGraph ©);
    // 重载赋值运算符
};
//
template 
void Display(const AdjMatrixUndirGraph &g, bool showVexElem); // 显示邻接矩阵无向图
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// 无向图的邻接矩阵类模板的实现部分
template 
AdjMatrixUndirGraph::AdjMatrixUndirGraph(ElemType es[], int vertexNum)
// 操作结果:构造数据元素es[],顶点个数为vertexNum,边数为0的无向图
{
    if (vertexNum < 0)
        return;//抛出异常
    
    vexNum = vertexNum;                            // 顶点数为vertexNum
    edgeNum = 0;                                // 边数为0
    
    elems = new ElemType[vexNum];                // 生成顶点数据标数组
    
    int u, v;                                    // 临时变量
    for (v = 0; v < vexNum; v++)
    {
        // 初始化标志数组
        elems[v] = es[v];
    }
    
    tag = new StatusCode[vexNum];                // 生成标志数组
    for (v = 0; v < vexNum; v++)
    {
        // 初始化标志数组
        tag[v] = UNVISITED;//均记录为未被访问
    }
    
    Matrix = (int **)new int *[vexNum];// 生成邻接矩阵???
    for (v = 0; v < vexNum; v++)
    {
        // 生成邻接矩阵的行,vexNum代表的是顶点个数
        Matrix[v] = new int[vexNum];
    }
    
    for (u = 0; u < vexNum; u++)
    {
        for (v = 0; v < vexNum; v++)
        {
            // 为邻接矩阵元素赋值
            Matrix[u][v] = 0;
        }
    }
}

template 
AdjMatrixUndirGraph::AdjMatrixUndirGraph(int vertexNum)
// 操作结果:构造顶点个数为vertexNum,边数为0的无向图
{
    if (vertexNum < 0)    return;// 抛出异常
    
    vexNum = vertexNum;                            // 顶点数为vertexNum
    edgeNum = 0;                                // 边数为0
    
    elems = new ElemType[vexNum];                // 生成顶点数据标数组
    
    int u, v;                                    // 临时变量
    tag = new StatusCode[vexNum];                // 生成标志数组
    for (v = 0; v < vexNum; v++)
    {
        // 初始化标志数组
        tag[v] = UNVISITED;
    }
    
    Matrix = (int **)new int *[vexNum];// 生成邻接矩阵
    for (v = 0; v < vexNum; v++)
    {
        // 生成邻接矩阵的行
        Matrix[v] = new int[vexNum];
    }
    
    for (u = 0; u < vexNum; u++)
    {
        for (v = 0; v < vexNum; v++)
        {
            // 为邻接矩阵元素赋值
            Matrix[u][v] = 0;
        }
    }
}

template 
void AdjMatrixUndirGraph::DestroyHelp()
// 操作结果:销毁无向图,释放无向图占用的空间
{
    delete []elems;                            // 释放顶点数据
    delete []tag;                                // 释放标志
    
    for (int iPos = 0; iPos < vexNum; iPos++)
    {
        // 释放邻接矩阵的行
        delete [] Matrix[iPos];
    }
    delete []Matrix;                            // 释放邻接矩阵
}

template 
AdjMatrixUndirGraph::~AdjMatrixUndirGraph()
// 操作结果:释放对象所占用空间
{
    DestroyHelp();
}

template 
StatusCode AdjMatrixUndirGraph::GetElem(int v, ElemType &e) const
// 操作结果:求顶点v的元素, v的取值范围为0 ≤ v < vexNum, v合法时返回
//    SUCCESS, 否则返回RANGE_ERROR
{
    if (v < 0 || v >= vexNum)
    {
        // v范围错
        return NOT_PRESENT;    // 元素不存在
    }
    else
    {
        // v合法
        e = elems[v];        // 将顶点v的元素值赋给e
        return ENTRY_FOUND;    // 元素存在
    }
}

template 
StatusCode AdjMatrixUndirGraph::SetElem(int v, const ElemType &e)
// 操作结果:设置顶点的元素值v的取值范围为0 ≤ v < vexNum, v合法时返回
//    SUCCESS, 否则返回RANGE_ERROR
{
    if (v < 0 || v >= vexNum)
    {
        // v范围错
        return RANGE_ERROR;    // 位置错
    }
    else
    {
        // v合法
        elems[v] = e;        // 顶点元素
        return SUCCESS;        // 成功
    }
}

template 
int AdjMatrixUndirGraph::GetVexNum() const
// 操作结果:返回顶点个数
{
    return vexNum;
}

template 
int AdjMatrixUndirGraph::GetEdgeNum() const
// 操作结果:返回边数个数
{
    return edgeNum;
}

template 
int AdjMatrixUndirGraph::FirstAdjVex(int v) const
// 操作结果:返回顶点v的第1个邻接点
{
    if (v < 0 || v >= vexNum) return -1;//范围出错,返回-1
    
    for (int cur = 0; cur < vexNum; cur++)
    {
        // 查找邻接点
        if (Matrix[v][cur] != 0) return cur;
    }
    
    return -1;                                    // 返回-1表示无邻接点
}

template 
int AdjMatrixUndirGraph::NextAdjVex(int v1, int v2) const
// 操作结果:返回顶点v1的相对于v2(v2为v1邻接点)的下1个邻接点
{
    if (v1 < 0 || v1 >= vexNum) return -1;
    if (v2 < 0 || v2 >= vexNum) return -1;
    if (v1 == v2) return -1;
    
    for (int cur = v2 + 1; cur < vexNum; cur++)
    {
        // 查找邻接点
        if (Matrix[v1][cur] != 0) return cur;
    }
    
    return -1;                                    // 返回-1表示无邻接点
}

template 
void AdjMatrixUndirGraph::InsertEdge(int v1, int v2)
// 操作结果:插入顶点为v1和v2,权为w的边
{
    if (v1 < 0 || v1 >= vexNum) return;
    if (v2 < 0 || v2 >= vexNum) return;
    if (v1 == v2) return;
    if (Matrix[v1][v2] == 0 && Matrix[v2][v1] == 0)
    {
        // 原无向图无边(v1, v2),插入后边数自增1
        edgeNum++;
    }
    Matrix[v1][v2] = 1;                // 修改对应的邻接矩阵元素值
    Matrix[v2][v1] = 1;                // 修改对应的邻接矩阵元素值
}

template 
void AdjMatrixUndirGraph::DeleteEdge(int v1, int v2)
// 操作结果:删除顶点为v1和v2的边
{
    if (v1 < 0 || v1 >= vexNum) return;
    if (v2 < 0 || v2 >= vexNum) return;
    if (v1 == v2) return;
    
    if (Matrix[v1][v2] != 0 && Matrix[v2][v1] != 0)
    {
        // 原无向图存在边(v1, v2),删除后边数自减1
        edgeNum--;
    }
    Matrix[v1][v2] = 0;                // 修改对应的邻接矩阵元素值
    Matrix[v2][v1] = 0;                // 修改对应的邻接矩阵元素值
}

template 
StatusCode AdjMatrixUndirGraph::GetTag(int v) const
// 操作结果:返回顶点v的标志
{
    if (v < 0 || v >= vexNum) return FAIL;
    
    return tag[v];
}

template 
void AdjMatrixUndirGraph::SetTag(int v, StatusCode val) const
// 操作结果:设置顶点v的标志为val
{
    if (v < 0 || v >= vexNum) return;
    
    tag[v] = val;
}
//--。
template 
AdjMatrixUndirGraph::AdjMatrixUndirGraph(const AdjMatrixUndirGraph ©)
// 操作结果:由无向图的邻接矩阵copy构造新无向图的邻接矩阵copy——复制构造函数模板
{
    int iPos, jPos;                                // 临时变量
    vexNum = copy.vexNum;                        // 复制顶点数
    edgeNum = copy.edgeNum;                        // 复制边数
    
    elems = new ElemType[vexNum];            // 生成顶点数据数组
    for (iPos = 0; iPos < vexNum; iPos++)
    {
        // 复制顶点数据数组
        elems[iPos] = copy.elems[iPos];
    }
    
    tag = new StatusCode[vexNum];                // 生成标志数组
    for (iPos = 0; iPos < vexNum; iPos++)
    {
        // 复制标志数组
        tag[iPos] = copy.tag[iPos];
    }
    
    Matrix = (int **)new int *[vexNum];    // 生成邻接矩阵
    for (iPos = 0; iPos < vexNum; iPos++)
    {
        // 生成邻接矩阵的行
        Matrix[iPos] = new int[vexNum];
    }
    
    for (iPos = 0; iPos < vexNum; iPos++)
    {
        for (jPos = 0; jPos < vexNum; jPos++)
        {
            // 复制邻接矩阵元素赋值
            Matrix[iPos][jPos] = copy.Matrix[iPos][jPos];
        }
    }
}

template 
AdjMatrixUndirGraph &AdjMatrixUndirGraph::operator =(const AdjMatrixUndirGraph ©)
// 操作结果:将无向图的邻接矩阵copy赋值给当前无向图的邻接矩阵——重载赋值运算符
{
    if (© != this)
    {
        DestroyHelp();                        // 释放当前无向图占用空间
        int iPos, jPos;                        // 临时变量
        vexNum = copy.vexNum;                // 复制顶点数
        edgeNum = copy.edgeNum;                // 复制边数
        
        elems = new ElemType[vexNum];        // 生成顶点数据数组
        for (iPos = 0; iPos < vexNum; iPos++)
        {
            // 复制顶点数据数组
            elems[iPos] = copy.elems[iPos];
        }
        
        tag = new StatusCode[vexNum];    // 生成标志数组
        for (iPos = 0; iPos < vexNum; iPos++)
        {
            // 复制标志数组
            tag[iPos] = copy.tag[iPos];
        }
        
        Matrix = (int **)new int*[vexNum];    // 生成邻接矩阵
        for (iPos = 0; iPos < vexNum; iPos++)
        {
            // 生成邻接矩阵的行
            Matrix[iPos] = new int[vexNum];
        }
        
        for (iPos = 0; iPos < vexNum; iPos++)
        {
            for (jPos = 0; jPos < vexNum; jPos++)
            {
                // 复制邻接矩阵元素赋值
                Matrix[iPos][jPos] = copy.Matrix[iPos][jPos];
            }
        }
    }
    return *this;
}
//深度优先遍历算法——Step2
template 
void AdjMatrixUndirGraph::DFS(int v)
{
    SetTag(v, VISITED);//设置为访问
    ElemType e = elems[v];
    cout<
void AdjMatrixUndirGraph::DFSTraverse()
{
    int v;
    //将所有节点的tag值设置为未被访问-unvisisted
    for (v = 0; v < GetVexNum(); v++)
    {
        SetTag(v, UNVISITED);
    }
    //对每个未被访问的节点进行深度优先遍历
    for (v = 0; v < GetVexNum(); v++)
    {
        if (GetTag(v) == UNVISITED)
            DFS(v);
    }
    cout<
void Display(const AdjMatrixUndirGraph &g)
// 操作结果: 显示邻接矩阵有向图
{
    int **Matrix;                                    // 邻接矩阵
    Matrix = (int **)new int *[g.GetVexNum()];        // 生成邻接矩阵!!!
    int iPos;                                        // 临时变量
    
    for (iPos = 0; iPos < g.GetVexNum(); iPos++)
    {
        // 生成邻接矩阵的行
        Matrix[iPos] = new int[g.GetVexNum()];
    }
    
    for (iPos = 0; iPos < g.GetVexNum(); iPos++)
    {
        for (int jPos = 0; jPos < g.GetVexNum(); jPos++)
        {
            // 为邻接矩阵元素赋值
            Matrix[iPos][jPos] = 0;
        }
    }
    
    for (int v = 0; v < g.GetVexNum(); v++)
    {
        // 查找有向图中v的邻接点
        for (int u = g.FirstAdjVex(v); u != -1; u = g.NextAdjVex(v, u))
        {
            // u为v的邻接点
            Matrix[v][u] = 1;
        }
    }
    
    for (iPos = 0; iPos < g.GetVexNum(); iPos++)
    {
        // 显示行
        
        ElemType e;                    // 数据元素
        g.GetElem(iPos, e);            // 取出元素值
        cout << e;                    // 显示元素值
        
        for (int jPos = 0; jPos < g.GetVexNum(); jPos++)
        {
            // 显示元素
            cout << "\t" << Matrix[iPos][jPos];
        }
        cout << endl;                    // 换行
    }
    
    for (iPos = 0; iPos < g.GetVexNum(); iPos++)
    {
        // 释放邻接矩阵的行
        delete []Matrix[iPos];
    }
    delete []Matrix;                    // 释放邻接矩阵
}
//
int main()
{
    
    int vexs[] = {13,25,87,189,1,5,24};
    int m[7][7] = {
        {0, 0, 1, 1, 1, 0, 1},
        {0, 0, 0, 0, 0, 0, 1},
        {1, 0, 0, 1, 1, 0, 1},
        {1, 0, 1, 0, 0, 1, 0},
        {1, 0, 1, 0, 0, 0, 0},
        {0, 0, 0, 1, 0, 0, 1},
        {1, 1, 1, 0, 0, 1, 0},
    };
    int n = 7;
    
    AdjMatrixUndirGraph g(vexs, n);
    
    int u;                                    // 临时变量
    for (u = 0; u < n; u++)
    {    // 生成邻接矩阵的行
        for (int v = 0; v < n; v++)
        {    // 生成邻接矩阵元素的值
            if (m[u][v] == 1) g.InsertEdge(u, v);
        }
    }
    
    cout<<"无向图:"<
结果:
深度优先遍历实例(C++)_第1张图片

代码仅供参考
2018.01.02第一次投稿

你可能感兴趣的:(C++数据结构)