码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2016-03-15 23:38:52      阅读:708      评论:0      收藏:0      [点我收藏+]

标签:

最近在学数据结构,学到图这一章,网上的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

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

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

标签:

原文地址:http://www.cnblogs.com/scutjiajia/p/5281623.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!