zoukankan      html  css  js  c++  java
  • 邻接表(C++)

    adj_list_network_edge.h

     1 // 邻接表网边数据类模板
     2 template <class WeightType>
     3 class AdjListNetworkEdge
     4 {
     5 public:
     6 // 数据成员:
     7     int adjVex;                                // 邻接点
     8     WeightType weight;                        // 权值
     9 
    10 // 构造函数模板:
    11     AdjListNetworkEdge();                        // 无参数的构造函数模板
    12     AdjListNetworkEdge(int v, WeightType w);    // 构造邻接点为v,权为w的邻接边
    13 };
    14 
    15 // 邻接表网边数据类模板的实现部分
    16 template <class WeightType>
    17 AdjListNetworkEdge<WeightType>::AdjListNetworkEdge()
    18 // 操作结果:构造一个空邻接表边结点边——无参构造函数模板
    19 {
    20     adjVex = -1;
    21 }
    22 
    23 template <class WeightType>
    24 AdjListNetworkEdge<WeightType>::AdjListNetworkEdge(int v, WeightType w)
    25 // 操作结果:构造邻接点为v,权为w的邻接边
    26 {
    27     adjVex = v;                                // 邻接点
    28     weight = w;                                //
    29 }

    adj_list_graph_vex_node

     1 // 邻接表网顶点结点类模板
     2 template <class ElemType, class WeightType>
     3 class AdjListNetWorkVexNode
     4 {
     5 public:
     6 // 数据成员:
     7     ElemType data;                            // 数据元素值
     8     LinkList<AdjListNetworkEdge<WeightType> > *adjLink;
     9         // 指向邻接链表的指针
    10 
    11 // 构造函数模板:
    12     AdjListNetWorkVexNode();                // 无参数的构造函数模板
    13     AdjListNetWorkVexNode(ElemType item, 
    14         LinkList<AdjListNetworkEdge<WeightType> > *adj = NULL);
    15         // 构造顶点数据为item,指向邻接链表的指针为adj的结构
    16 };
    17 
    18 // 邻接表网顶点结点类模板的实现部分
    19 template <class ElemType, class WeightType>
    20 AdjListNetWorkVexNode<ElemType, WeightType>::AdjListNetWorkVexNode()
    21 // 操作结果:构造一个空顶点结点——无参构造函数模板
    22 {
    23     adjLink = NULL;                            // 指向邻接链表的指针为空
    24 }
    25 
    26 template <class ElemType, class WeightType>
    27 AdjListNetWorkVexNode<ElemType, WeightType>::AdjListNetWorkVexNode(ElemType item, 
    28     LinkList<AdjListNetworkEdge<WeightType> > *adj)
    29 // 操作结果:构造数据为item,边为eg的顶点
    30 {
    31     data = item;                            // 顶点数据
    32     adjLink = adj;                            // 指向邻接链表的指针
    33 }

    adj_list_undir_graph.h

      1 #include "adj_list_graph_vex_node.h"            // 邻接表无向图顶点结点类模板
      2 
      3 // 无向图的邻接表类模板
      4 template <class ElemType>
      5 class AdjListUndirGraph
      6 {
      7 protected:
      8 // 邻接表的数据成员:
      9     int vexNum, edgeNum;                        // 顶点个数和边数
     10     AdjListGraphVexNode<ElemType> *vexTable;    // 顶点表
     11     mutable StatusCode *tag;                    // 指向标志数组的指针                
     12 
     13 // 辅助函数模板:
     14     void DestroyHelp();                            // 销毁无向图,释放无向图点用的空间
     15     int IndexHelp(const LinkList<int> *la, int v) const;
     16         //定位顶点v在邻接链表中的位置
     17 
     18 public:
     19 // 抽象数据类型方法声明及重载编译系统默认方法声明:
     20     AdjListUndirGraph(ElemType es[], int vertexNum = DEFAULT_SIZE);
     21         // 构造顶点数据为es[],顶点个数为vertexNum,infinit表示无穷大,边数为0的无向图
     22     AdjListUndirGraph(int vertexNum = DEFAULT_SIZE);
     23         // 构造顶点个数为vertexNum,infinit表示无穷大,边数为0的无向图
     24     ~AdjListUndirGraph();                        // 析构函数模板
     25     StatusCode GetElem(int v, ElemType &e) const;// 求顶点的元素    
     26     StatusCode SetElem(int v, const ElemType &e);// 设置顶点的元素值
     27     ElemType GetInfility() const;                // 返回无穷大             
     28     int GetVexNum() const;                        // 返回顶点个数             
     29     int GetEdgeNum() const;                        // 返回边数个数             
     30     int FirstAdjVex(int v) const;                // 返回顶点v的第一个邻接点             
     31     int NextAdjVex(int v1, int v2) const;        // 返回顶点v1的相对于v2的下一个邻接点             
     32     void InsertEdge(int v1, int v2);            // 插入顶点为v1和v2的边             
     33     void DeleteEdge(int v1, int v2);            // 删除顶点为v1和v2的边             
     34     StatusCode GetTag(int v) const;                // 返回顶点v的标志         
     35     void SetTag(int v, StatusCode val) const;    // 设置顶点v的标志为val         
     36     AdjListUndirGraph(const AdjListUndirGraph<ElemType> &copy);    // 复制构造函数模板
     37     AdjListUndirGraph<ElemType> &operator =(const AdjListUndirGraph<ElemType> &copy); // 重载赋值运算符
     38 };
     39 
     40 template <class ElemType>
     41 void Display(const AdjListUndirGraph<ElemType> &g, bool showVexElem);    // 显示邻接矩阵无向图
     42 
     43 // 无向图的邻接表类模板的实现部分
     44 template <class ElemType>
     45 AdjListUndirGraph<ElemType>::AdjListUndirGraph(ElemType es[], int vertexNum)
     46 // 操作结果:构造顶点数为numVex,顶点数据为es[],顶点个数为vertexNum,边数为0的无向图
     47 {
     48     if (vertexNum < 0)    throw Error("顶点个数不能为负!");// 抛出异常
     49 
     50     vexNum = vertexNum;                            // 顶点数为vertexNum
     51     edgeNum = 0;                                // 边数为0
     52 
     53     tag = new StatusCode[vexNum];                // 生成标志数组
     54     int curPos;                                    // 临时变量 
     55     for (curPos = 0; curPos < vexNum; curPos++)
     56     {    // 初始化标志数组
     57         tag[curPos] = UNVISITED;
     58     }
     59 
     60     vexTable = new AdjListGraphVexNode<ElemType>[vexNum];// 生成邻接表
     61     for (curPos = 0; curPos < vexNum; curPos++)
     62     {    // 初始化顶点数据
     63         vexTable[curPos].data = es[curPos];
     64     }
     65 }
     66 
     67 template <class ElemType>
     68 AdjListUndirGraph<ElemType>::AdjListUndirGraph(int vertexNum)
     69 // 操作结果:构造顶点数为numVex,顶点个数为vertexNum,边数为0的无向图
     70 {
     71     if (vertexNum < 0)    throw Error("顶点个数不能为负!");// 抛出异常
     72 
     73     vexNum = vertexNum;                            // 顶点数为vertexNum
     74     edgeNum = 0;                                // 边数为0
     75 
     76     tag = new StatusCode[vexNum];                // 生成标志数组
     77     int curPos;                                    // 临时变量 
     78     for (curPos = 0; curPos < vexNum; curPos++)
     79     {    // 初始化标志数组
     80         tag[curPos] = UNVISITED;
     81     }
     82 
     83     vexTable = new AdjListGraphVexNode<ElemType>[vexNum];// 生成邻接表
     84 }
     85 
     86 template <class ElemType>
     87 void AdjListUndirGraph<ElemType>::DestroyHelp()
     88 // 操作结果:销毁无向图,释放无向图点用的空间
     89 {
     90     delete []tag;                                // 释放标志
     91     for (int iPos = 0; iPos < vexNum; iPos++)
     92     {    // 释放链表
     93         if (vexTable[iPos].adjLink != NULL)
     94             delete vexTable[iPos].adjLink;
     95     }
     96     delete []vexTable;                            // 释放邻接表
     97 }
     98 
     99 template <class ElemType>
    100 AdjListUndirGraph<ElemType>::~AdjListUndirGraph()
    101 // 操作结果:释放邻接表无向图所占用空间
    102 {
    103     DestroyHelp();
    104 }
    105 
    106 template <class ElemType>
    107 StatusCode AdjListUndirGraph<ElemType>::GetElem(int v, ElemType &e) const
    108 // 操作结果:求顶点v的元素, v的取值范围为0 ≤ v < vexNum, v合法时返回
    109 //    SUCCESS, 否则返回RANGE_ERROR
    110 {
    111     if (v < 0 || v >= vexNum)
    112     {    // v范围错
    113         return NOT_PRESENT;            // 元素不存在
    114     }
    115     else
    116     {    // v合法
    117         e = vexTable[v].data;        // 将顶点v的元素值赋给e
    118         return ENTRY_FOUND;            // 元素存在
    119     }
    120 }    
    121 
    122 template <class ElemType>
    123 StatusCode AdjListUndirGraph<ElemType>::SetElem(int v, const ElemType &e)
    124 // 操作结果:设置顶点的元素值v的取值范围为0 ≤ v < vexNum, v合法时返回
    125 //    SUCCESS, 否则返回RANGE_ERROR
    126 {
    127     if (v < 0 || v >= vexNum)
    128     {    // v范围错
    129         return RANGE_ERROR;            // 位置错
    130     }
    131     else
    132     {    // v合法
    133         vexTable[v].data = e;        // 顶点元素
    134         return SUCCESS;                // 成功
    135     }
    136 }
    137 
    138 template <class ElemType>
    139 int AdjListUndirGraph<ElemType>::GetVexNum() const
    140 // 操作结果:返回顶点个数             
    141 {
    142     return vexNum;
    143 }
    144 
    145 template <class ElemType>
    146 int AdjListUndirGraph<ElemType>::GetEdgeNum() const
    147 // 操作结果:返回边数个数
    148 {
    149     return edgeNum;
    150 }         
    151 
    152 template <class ElemType>
    153 int AdjListUndirGraph<ElemType>::FirstAdjVex(int v) const
    154 // 操作结果:返回顶点v的第一个邻接点             
    155 {
    156     if (v < 0 || v >= vexNum) throw Error("v不合法!");// 抛出异常
    157 
    158     if (vexTable[v].adjLink == NULL)
    159     {    // 空邻接链表,无邻接点
    160         return -1; 
    161     }
    162     else
    163     {    // 非空邻接链表,存在邻接点
    164         int adjVex;
    165         vexTable[v].adjLink->GetElem(1, adjVex);
    166         return adjVex;
    167     }
    168 }
    169 
    170 template <class ElemType>
    171 int AdjListUndirGraph<ElemType>::IndexHelp(const LinkList<int> *la, int v) const
    172 // 操作结果:定位顶点v在邻接链表中的位置
    173 {
    174     int curPos, adjVex;
    175     curPos = la->GetCurPosition();
    176 
    177     la->GetElem(curPos, adjVex);                    // 取得邻接点信息
    178     if (adjVex == v) return curPos;                    // v为线性链表的当前位置处 
    179     
    180     curPos = 1;
    181     for (curPos = 1; curPos <= la->Length(); curPos++)
    182     {    // 循环定定
    183         la->GetElem(curPos, adjVex);                // 取得边信息
    184         if (adjVex == v) break;                        // 定位成功
    185     }
    186     
    187     return curPos;                                    // curPos = la.Length() + 1 表定失败
    188 }
    189 
    190 template <class ElemType>
    191 int AdjListUndirGraph<ElemType>::NextAdjVex(int v1, int v2) const
    192 // 操作结果:返回顶点v1的相对于v2的下一个邻接点             
    193 {
    194     if (v1 < 0 || v1 >= vexNum) throw Error("v1不合法!");    // 抛出异常
    195     if (v2 < 0 || v2 >= vexNum) throw Error("v2不合法!");    // 抛出异常
    196     if (v1 == v2) throw Error("v1不能等于v2!");                // 抛出异常
    197     
    198     if (vexTable[v1].adjLink == NULL) return -1;            // 邻接链表vexTable[v1].adjList为空,返回-1
    199 
    200     int curPos = IndexHelp(vexTable[v1].adjLink, v2);        // 取出v2在邻接链表中的位置
    201     if (curPos < vexTable[v1].adjLink->Length())
    202     {    // 存在下1个邻接点
    203         int adjVex;
    204         vexTable[v1].adjLink->GetElem(curPos + 1, adjVex);    // 取出后继
    205         return adjVex;
    206     }
    207     else
    208     {    // 不存在下一个邻接点
    209         return -1;
    210     }
    211 }
    212 
    213 template <class ElemType>
    214 void AdjListUndirGraph<ElemType>::InsertEdge(int v1, int v2)
    215 // 操作结果:插入顶点为v1和v2的边             
    216 {
    217     if (v1 < 0 || v1 >= vexNum) throw Error("v1不合法!");    // 抛出异常
    218     if (v2 < 0 || v2 >= vexNum) throw Error("v2不合法!");    // 抛出异常
    219     if (v1 == v2) throw Error("v1不能等于v2!");                // 抛出异常
    220 
    221     // 插入<v1, v2>
    222     if (vexTable[v1].adjLink == NULL)
    223     {    // 空链表
    224         vexTable[v1].adjLink = new LinkList<int>;
    225     }
    226     
    227     int curPos = IndexHelp(vexTable[v1].adjLink, v2);            // 取出v2在邻接链表中的位置
    228     if (curPos > vexTable[v1].adjLink->Length())
    229     {    // 不存在边<v1, v2>
    230         vexTable[v1].adjLink->Insert(curPos, v2);                // 插入边
    231         edgeNum++;                                            // 边数自增1
    232     }
    233     
    234     // 插入<v2, v1>
    235     if (vexTable[v2].adjLink == NULL)
    236     {    // 空链表
    237         vexTable[v2].adjLink = new LinkList<int>;
    238     }
    239 
    240     curPos = IndexHelp(vexTable[v2].adjLink, v1);                // 取出v1在邻接链表中的位置
    241     if (curPos > vexTable[v2].adjLink->Length())
    242     {    // 不存在边<v1, v2>
    243         vexTable[v2].adjLink->Insert(curPos, v1);                // 插入边
    244     }
    245 }
    246 
    247 template <class ElemType>
    248 void AdjListUndirGraph<ElemType>::DeleteEdge(int v1, int v2)
    249 // 操作结果:删除顶点为v1和v2的边             
    250 {
    251     if (v1 < 0 || v1 >= vexNum) throw Error("v1不合法!");    // 抛出异常
    252     if (v2 < 0 || v2 >= vexNum) throw Error("v2不合法!");    // 抛出异常
    253     if (v1 == v2) throw Error("v1不能等于v2!");                // 抛出异常
    254 
    255     int curPos = IndexHelp(vexTable[v1].adjLink, v2);    // 取出v2在邻接链表中的位置
    256     if (curPos <= vexTable[v1].adjLink->Length())
    257     {    // 存在边<v1, v2>
    258         vexTable[v1].adjLink->Delete(curPos, v2);        // 删除<v1, v2>
    259          edgeNum--;                                    // 边数自减1
    260     }
    261 
    262     curPos = IndexHelp(vexTable[v2].adjLink, v1);        // 取出v1在邻接链表中的位置
    263     if (curPos <= vexTable[v2].adjLink->Length())
    264     {    // 存在边<v2, v1>
    265         vexTable[v2].adjLink->Delete(curPos, v1);        // 删除<v2, v1>
    266     }
    267 }
    268 
    269 template <class ElemType>
    270 StatusCode AdjListUndirGraph<ElemType>::GetTag(int v) const
    271 // 操作结果:返回顶点v的标志         
    272 {
    273     if (v < 0 || v >= vexNum) throw Error("v不合法!");        // 抛出异常
    274 
    275     return tag[v];
    276 }
    277 
    278 template <class ElemType>
    279 void AdjListUndirGraph<ElemType>::SetTag(int v, StatusCode val) const
    280 // 操作结果:设置顶点v的标志为val         
    281 {
    282     if (v < 0 || v >= vexNum) throw Error("v不合法!");        // 抛出异常
    283 
    284     tag[v] = val;
    285 }
    286 
    287 template <class ElemType>
    288 AdjListUndirGraph<ElemType>::AdjListUndirGraph(const AdjListUndirGraph<ElemType> &copy)
    289 // 操作结果:由无向图的邻接矩阵copy构造新无向图的邻接矩阵copy——复制构造函数模板
    290 {
    291     int curPos;                                    // 临时变量
    292     vexNum = copy.vexNum;                        // 复制顶点数
    293     edgeNum = copy.edgeNum;                        // 复制边数
    294 
    295     tag = new StatusCode[vexNum];                // 生成标志数组
    296     for (curPos = 0; curPos < vexNum; curPos++)
    297     {    // 复制标志数组
    298         tag[curPos] = copy.tag[curPos];
    299     }
    300 
    301     vexTable = new AdjListGraphVexNode<ElemType>[vexNum];// 生成邻接表
    302     for (curPos = 0; curPos < vexNum; curPos++)
    303     {    // 复制邻接链表
    304         vexTable[curPos].data = copy.vexTable[curPos].data;    // 复制顶点数据
    305         vexTable[curPos].adjLink = new LinkList<int>(*copy.vexTable[curPos].adjLink);    
    306     }
    307 }
    308 
    309 template <class ElemType>
    310 AdjListUndirGraph<ElemType> &AdjListUndirGraph<ElemType>::operator =(const AdjListUndirGraph<ElemType> &copy)
    311 // 操作结果:将无向图的邻接矩阵copy赋值给当前无向图的邻接矩阵——重载赋值运算符
    312 {
    313     if (&copy != this)
    314     {
    315         DestroyHelp();                                // 释放当前无向图占用空间
    316 
    317         int curPos;                                    // 临时变量
    318         vexNum = copy.vexNum;                        // 复制顶点数
    319         edgeNum = copy.edgeNum;                        // 复制边数
    320 
    321         tag = new StatusCode[vexNum];                // 生成标志数组
    322         for (curPos = 0; curPos < vexNum; curPos++)
    323         {    // 复制标志数组
    324             tag[curPos] = copy.tag[curPos];
    325         }
    326 
    327         vexTable = new AdjListGraphVexNode<ElemType>[vexNum];// 生成邻接表
    328         for (curPos = 0; curPos < vexNum; curPos++)
    329         {    // 复制邻接链表
    330             vexTable[curPos].data = copy.vexTable[curPos].data;    // 复制顶点数据
    331             vexTable[curPos].adjLink = new LinkList<int>(*copy.vexTable[curPos].adjLink);    
    332         }
    333     }
    334     return *this;
    335 }
    336 
    337 template <class ElemType>
    338 void Display(const AdjListUndirGraph<ElemType> &g, bool showVexElem = true)
    339 // 操作结果: 显示邻接矩阵无向图
    340 {
    341     for (int v = 0; v < g.GetVexNum(); v++)
    342     {    // 显示第v个邻接链表
    343         cout << endl << v << "  ";                            // 显示顶点号
    344         if (showVexElem)
    345         {    // 显示顶点元素
    346             ElemType e;                                        // 数据元素
    347             g.GetElem(v, e);                                // 取出元素值
    348             cout << e << "  ";                                // 显示顶点元素
    349         }
    350 
    351         for (int u = g.FirstAdjVex(v); u != -1; u = g.NextAdjVex(v, u))
    352         {    // 显示第v个邻接链表的一个结点(表示一个邻接点)
    353             cout << "-->" << u; 
    354         }
    355         cout << endl; 
    356     }
    357 }
  • 相关阅读:
    git 操作
    vim使用指北 ---- Multiple Windows in Vim
    Unity 异步网络方案 IOCP Socket + ThreadSafe Queue
    unity 四元数, 两行等价的代码
    golang的项目结构 相关知识
    stencil in unity3d
    一段tcl代码
    16_游戏编程模式ServiceLocator 服务定位
    15_游戏编程模式EventQueue
    14_ Component 游戏开发组件模式
  • 原文地址:https://www.cnblogs.com/ljwTiey/p/4297477.html
Copyright © 2011-2022 走看看