图的邻接多重表和搜索(C++版本)

最近在学数据结构,学到图这一章,网上的C++版本的代码乱得不行,所以自己写了一个完整C++版本的放这里。

用邻接多重表表示一个无向图,并给出DFS和BFS搜索代码。邻接多重表好处就是贼直观,几条边就几个边表的元素。

代码如下:

边表节点定义(其实就是边的定义)

typedef struct EdgeNode          //邻接多重表
{
    int iVertex;
    EdgeNode* iLink;
    int jVertex;
    EdgeNode* jLink;

};

 顶点表节点的定义

template <typename Type>
struct VextexNode             //邻接多重表的顶点表
{
    Type Data;
    EdgeNode* TailLink;
    Mark Flag;
};

最后是图的模板类

#ifndef MULADJACENCYLIST_H
#define MULADJACENCYLIST_H
#include "SideNode.h"
#include "VexNode.h"
#include <iostream>
#include <vector>
#include <list>
#include <set>
using namespace std;

template <typename Type, int N>
class MulAdjacencyList
{
public:
    MulAdjacencyList();
    ~MulAdjacencyList();
    void AddEdge();
    int DeleteEdge(int x, int y);
    void DFS(int x, const Type& Value);
    void BFS(int x, const Type& Value);  
private:
    int InitEdgeNum();    //构造函数中先输入图的边数
    int NextIndex(int CurIndex);     //查找最近的一个邻接点,CurIndex为点的下标而不是值
    void BFSHelper(set <int> SourceList, const Type& Value); //BFS真正的递归函数
    void AllNextIndex(int i);     //和i相连的所有邻接点,i为点的下标而不是值
    VextexNode <Type> VertexArray[N];   //顶点表
    EdgeNode* LastPtr(int x);  
    int EdgeNums;  //当前的边数
    vector <int> Temp;   //用来存放搜索结果的容器
    set <int> TempList; //用来存放AllNextIndex结果的容器
};

template <typename Type, int N>
void MulAdjacencyList<Type, N>::AddEdge()  //添加一条x到y的无向边
{
    cout << "Enter the edge wanna insert!" << endl;
    int i, j;
    if (cin >> i >> j)
    {
        EdgeNode* TarPtr = new EdgeNode;
        TarPtr->iVertex = i;
        TarPtr->jVertex = j;
        TarPtr->iLink = VertexArray[i].TailLink;
        TarPtr->jLink = VertexArray[j].TailLink;
        VertexArray[i].TailLink = TarPtr;
        VertexArray[j].TailLink = TarPtr;
        EdgeNums++;
    }
    else
        cin.clear();
}

template <typename Type, int N>
int MulAdjacencyList<Type, N>::InitEdgeNum()
{
    cout << "Enter the quantity of edges!"<< endl;
    cin >> EdgeNums;
    return EdgeNums;
}

template <typename Type, int N>
EdgeNode* MulAdjacencyList<Type, N>::LastPtr(int x)   //找到和x相关的最后一条边
{
    EdgeNode* Temp = VertexArray[x].TailLink;
    EdgeNode* LastTemp = Temp;
    while (Temp != NULL)
    {
        if (Temp->iVertex == x)
        {
            LastTemp = Temp;
            Temp = Temp->iLink;
        }
        else if (Temp->jVertex == x)
        {
            LastTemp = Temp;
            Temp = Temp->jLink;
        }
    }
    return LastTemp;
}

template <typename Type, int N>
MulAdjacencyList <Type, N>::MulAdjacencyList()
{
    cout << "enter the vertex for the graph!" << endl;
    for (int i = 0; i != N; ++i)
    {
        cin >> VertexArray[i].Data;
        VertexArray[i].TailLink = NULL;
        VertexArray[i].Flag = No;
    }
    int Temp = InitEdgeNum();    
    for (int i = 0; i != Temp; ++ i)
        AddEdge();
}

template <typename Type, int N>
int MulAdjacencyList<Type, N>::DeleteEdge(int x, int y)   //删除x到y的一条无向边  
{    
    if (x == y)return 0;
    EdgeNode* Q = VertexArray[x].TailLink; //Q的下一条边就是要删除的边
    EdgeNode* P = VertexArray[x].TailLink;   //先从x出发找到要删除的边,调整完x的边的次序,得到指针,最后再删除
    if (P && P->jVertex == y)    //假如第一条边就是待删除的边, P是前向判断,避免P为NULL的情况下还执行P->jVertex
        VertexArray[x].TailLink = P->iLink;
    else if (P && P->iVertex == y)
        VertexArray[x].TailLink = P->jLink;
    else             //假如第一条边不是要删除的边,则向下查找
    {
        while (P)
        {
            if (P->iVertex == x && P->jVertex != y)//不是要删除的边
            {
                Q = P;
                P = P->iLink;
            }
            else if (P->jVertex == x && P->iVertex != y)
            {
                Q = P;
                P = P->jLink;
            }
            else         //找到了邻接点y
                break;
        }
        if (P == NULL)
        {
            return 0;             //这里可以加入一句警告“Not Found”
        }
        else if (P->iVertex == x && P->jVertex == y)  //找到了边(x,y),调整x的边的次序
        {
            if (Q->iVertex == x)
                Q->iLink = P->iLink;
            else
                Q->jLink = P->iLink;
        }
        else if (P->iVertex == y && P->jVertex == x)
        {
            if (Q->iVertex == x)
                Q->iLink = P->jLink;
            else
                Q->jLink = P->jLink;
        }
    }

    P = VertexArray[y].TailLink;   //从y出发开始查找,调整y的边的次序
    if (P && P->iVertex == x)
        VertexArray[y].TailLink = P->jLink;
    else if (P && P->jVertex == x)
        VertexArray[y].TailLink = P->iLink;
    else
    {
        while (P != NULL)
        {
            if (P->iVertex == y && P->jVertex != x)
            {
                Q = P;
                P = P->iLink;
            }
            else if (P->jVertex == y && P->iVertex != x)
            {
                Q = P;
                P = P->jLink;
            }
            else
                break;
        }
        if (P == NULL) //由于上面打了一次警告,这里就不打警告了
            return 0;
        else if (P->iVertex == y && P->jVertex == x)
        {
            if (Q->iVertex == y)
                Q->iLink = P->iLink;
            else
                Q->jLink = P->iLink;
        }
        else if ((P->jVertex == y && P->iVertex == x))
        {
            if (Q->iVertex == y)
                Q->iLink = P->jLink;
            else
                Q->jLink = P->jLink;
        }
    }
    cout << x << endl << y << endl<<"yici"<<endl;
    if (P != NULL) delete P;            //调整完线序了,删掉边
    --EdgeNums;
    return 1;
}

template <typename Type, int N>
MulAdjacencyList <Type, N>::~MulAdjacencyList()
{
    for (int i = 0; i != N; ++i)
    {
        for (int j = 0; j != N; ++j)
            DeleteEdge(i,j);
    }
}

template <typename Type, int N>
void MulAdjacencyList <Type, N>::AllNextIndex(int i)   //找到和i相关联的所有的点
{
    EdgeNode* Ptr = VertexArray[i].TailLink;
    while (Ptr != NULL)
    {
        if (Ptr->iVertex == i)
        {
            if (VertexArray[Ptr->jVertex].Flag != Yes)TempList.insert(Ptr->jVertex);
            Ptr = Ptr->iLink;
        }
        else
        {
            if (VertexArray[Ptr->iVertex].Flag != Yes)TempList.insert(Ptr->iVertex);
            Ptr = Ptr->jLink;
        }
    }
}

template <typename Type, int N>
int MulAdjacencyList <Type, N>::NextIndex(int CurIndex)
{
    EdgeNode* Ptr = VertexArray[CurIndex].TailLink;
    while (Ptr != NULL)
    {
        if (Ptr->iVertex == CurIndex)
        {
            if (VertexArray[Ptr->jVertex].Flag == No){
                return Ptr->jVertex;
            }
            else
                Ptr = Ptr->iLink;
        }
        else if (Ptr ->jVertex == CurIndex)
        {
            if (VertexArray[Ptr->iVertex].Flag == No){
                return Ptr->iVertex;
            }
            else
                Ptr = Ptr->jLink;
        }
    }
    if (Ptr == NULL) { return N; }
}

template <typename Type, int N>
void MulAdjacencyList <Type, N>::DFS(int x, const Type& Value)  //x为起始的下标,Value为查找的值
{
    if (VertexArray[x].Data == Value)
    {
        Temp.push_back(x);
    }
    VertexArray[x].Flag = Yes;
    int TempIndex = NextIndex(x);
    while (TempIndex != N)
    {
        DFS(TempIndex, Value);
        TempIndex = NextIndex(x);
    }
    for (vector <int>::const_iterator i = A.Temp.begin(); i != A.Temp.end(); ++i)  //打印找到的元素
        cout << *i << endl;
}

template <typename Type, int N>
void MulAdjacencyList <Type, N>::BFSHelper(set <int> SourceList,const Type& Value)
{
    if (!SourceList.empty())
    {
        for (set <int>::const_iterator i = SourceList.begin(); i != SourceList.end(); ++i)
        {
            VertexArray[*i].Flag = Yes;
            if (VertexArray[*i].Data == Value)
                Temp.push_back(*i);
        }
        for (set <int>::const_iterator i = SourceList.begin(); i != SourceList.end(); ++i)
        {
            AllNextIndex(*i);
        }
        SourceList = TempList;
        TempList.clear();
        BFSHelper(SourceList, Value);
    }
}

template <typename Type, int N>
void MulAdjacencyList <Type, N>::BFS(int x, const Type& Value)
{
    set <int> Set;
    Set.insert(x);
    BFSHelper(Set, Value);
}
#endif

 大类的代码有点乱,先挖个坑以后有空再来填上,希望对各位和自己有帮助。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对任意给定的(顶点数不小于20,边数不少于30,的类型可以是有向、无向、有向网、无向网),能够输入的顶点和边(或弧)的信息,并存储到相应存储结构(邻接矩阵、邻接表、十字链表、邻接多重表,任选其中两种类型),对自己所创建的完成以下操作: 对无向求每个顶点的度,或对有向求每个顶点的入度和出度(5分) 完成插入顶点和边(或弧)的功能(5分) 完成删除顶点和边(或弧)的功能(5分) 两种存储结构的转换(5分),如果其中一种存储结构为十字链表或邻接多重表则增加5分。 输出的深度优先遍历序列或广度优先遍历序列(5分) 求的深度优先或广度优先的生成树(或生成森林)(存储结构为孩子-兄弟链表),并对生成树进行遍历(15分) 判断的连通性,输出连通分量的个数(5分) 判断中是否存在环,无向5分,有向10分 给出顶点u和v,判断u到v是否存在路径(5分) 10、求顶点u到v的一条简单路径(10分) 11、求顶点u到v的所有简单路径(15分) 12、求顶点u到v的最短路径(10分) 13、求顶点u到其余各顶点的最短路径(15分) 14、求任两个顶点之间的最短路径(15分) 15、求最小生成树(15分) 16、对于有一个源点和一个汇点的有向网,求关键路径(20分) 编程环境可以是C、VC++、JAVA,每位同学从上述题目中选择100分的题目,注意,必须选择第1-6题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值