zoukankan      html  css  js  c++  java
  • 封装 有向图(邻接表) 遍历,删除,插入,拓扑排序等

    初始化四个弧:

    0 1

    0 2

    3 1

    3 2

      1 #include <iostream>
      2 #include <queue>
      3 #include <stack>
      4 using namespace std;
      5 
      6 const int MAXSIZE = 10;                    //最多的顶点数
      7 
      8 struct ArcNode
      9 {
     10     int adjvex;                            //结点在数组中的序号
     11     ArcNode* next;
     12 };
     13 template<class T>
     14 struct VertexNode
     15 {
     16     T vertex;                            //结点名字
     17     ArcNode *firstedge;
     18     int in;                                //记录顶点的入度
     19 };
     20 
     21 
     22 template<class T>
     23 class ALGraph
     24 {
     25 public:
     26     ALGraph(){}
     27     ALGraph(T a[], int n, int e);        //构造函数,初始哈一个有n个顶点e条边的图
     28     ~ALGraph();                            //析构函数,释放邻接表中各边表结点的存储空间
     29     T GetVex(int i);                    //取图中第i个顶点数据信息
     30     void PutVex(int i, T value);        //将图中第i个顶点的数据域置为value
     31     void InsertVex(T value);            //在图中插入一个顶点,值为value
     32     void DeleteVex(int i);                //删除结点序号为i的结点
     33     void InsertArc(int i, int j);        //在图中插入一条边,其依附的两个顶点标号为i和j
     34     void DeleteArc(int i, int j);        //删除一边,顶点编号i和j
     35     void DFSTraverse(int v);
     36     void BFSTraverse(int v);
     37     void CalAllNodeIns();                //计算所有节点的入度
     38     void TopSort();                        //拓扑排序
     39 private:
     40     VertexNode<T> adjlist[MAXSIZE];        //存放顶点表的数组
     41     int vertexNum, arcNum;                //图的顶点数和边数
     42     int visited[MAXSIZE];                //DFS递归法之用
     43 };
     44 
     45 int main()
     46 {
     47     char a[4] = { 'a','b','c','d' };
     48     ALGraph<char> ag(a,4,4);
     49     ag.TopSort();
     50     system("pause");
     51     return 0;
     52 }
     53 
     54 template<class T>
     55 ALGraph<T>::ALGraph(T a[], int n, int e)
     56 {
     57     int p1, p2;
     58     ArcNode *s;
     59 
     60     vertexNum = n, arcNum = e;
     61     for (int i = 0; i < vertexNum; i++)    //顶点信息存储在二维数组中,下标从0开始
     62     {
     63         adjlist[i].vertex = a[i];
     64         adjlist[i].firstedge = NULL;
     65     }
     66     for (int i = 0; i < arcNum; i++)
     67     {
     68         cin >> p1 >> p2;                //弧尾和弧头结点序号
     69         s = new ArcNode;                
     70         s->adjvex = p2;                    //记录弧尾指向结点的序号
     71         s->next = adjlist[p1].firstedge;//插入关联弧
     72         adjlist[p1].firstedge = s;
     73     }
     74     for (int i = 0; i < MAXSIZE; i++)
     75         visited[i] = 0;
     76 }
     77 
     78 template<class T>
     79 ALGraph<T>::~ALGraph()
     80 {
     81     ArcNode *p, *s;
     82     for (int i = 0; i < vertexNum; i++)
     83     {
     84         s = adjlist[i].firstedge;
     85         while (NULL != s) {
     86             p = s;
     87             s = s->next;
     88             delete p;
     89         }
     90     }
     91     arcNum = vertexNum = 0;
     92 }
     93 
     94 template<class T>
     95 T ALGraph<T>::GetVex(int i)
     96 {
     97     if (i < 0 || i >= vertexNum)
     98     {
     99         throw"顶点不存在";
    100     }
    101     else
    102     {
    103         return adjlist[i].vertex;        //返回第i个顶点的数据信息
    104     }
    105 }
    106 
    107 template<class T>
    108 void ALGraph<T>::PutVex(int i, T value)
    109 {
    110     if (i < 0 || i >= vertexNum)
    111     {
    112         cout << "结点不存在" << endl;
    113         return;
    114     }
    115     else
    116     {
    117         adjlist[i].vertex = value;        //替换第i个顶点的数据信息
    118     }
    119 }
    120 
    121 template<class T>
    122 void ALGraph<T>::InsertVex(T value)
    123 {
    124     int flag = 0;
    125     for (int i = 0; i < vertexNum; i++)
    126     {
    127         if (adjlist[i].vertex == value)
    128         {
    129             cout << "结点已存在" << endl;
    130             flag = 1;
    131             return;
    132         }
    133     }
    134     if (!flag)                            //不在图中,则新增结点
    135     {
    136         adjlist[vertexNum].fisrtedge = NULL;
    137         adjlist[vertexNum++].vertex = value;
    138     }
    139 }
    140 
    141 template<class T>
    142 void ALGraph<T>::DeleteVex(int i)
    143 {
    144     if (i < 0 || i >= vertexNum)
    145     {
    146         cout << "结点不存在" << endl;
    147         return;
    148     }
    149 
    150     ArcNode *s, *d;
    151     s = adjlist[i].firstedge;
    152     while (s != NULL) {
    153         d = s;
    154         s = s->next;
    155         delete d;
    156         arcNum--;
    157     }
    158                                         //横移
    159     if (i != vertexNum - 1)
    160     {
    161         for (int j = i + 1; j < vertexNum; j++)
    162         {
    163             adjlist[j - 1].vertex = adjlist[j].vertex;
    164             adjlist[j - 1].firstedge = adjlist[j].firstedge;
    165         }
    166     }
    167     vertexNum--;
    168 }
    169 
    170 template<class T>
    171 void ALGraph<T>::InsertArc(int i, int j)
    172 {
    173     if (i < 0 || i >= vertexNum)
    174     {
    175         cout << "结点不存在" << endl;
    176         return;
    177     }
    178     ArcNode *s, *p;
    179     s = adjlist[i].firstedge;
    180     p = adjlist[i].firstedge;
    181     if (NULL == s) {
    182         p = new ArcNode;
    183         p->adjvex = j;
    184         p->next = NULL;
    185         arcNum++;
    186         return;
    187     }
    188     while (NULL != s) {
    189         if (j == s->adjvex) {
    190             cout << "弧已存在" << endl;
    191             return;
    192         }
    193         p = s;                        //最后一弧
    194         s = s->next;
    195     }
    196     s = new ArcNode;                //动态分配内存
    197     p->next = s;
    198     s->adjvex = j;
    199     s->next = NULL;
    200     arcNum++;
    201 }
    202 
    203 template<class T>
    204 void ALGraph<T>::DeleteArc(int i, int j)
    205 {
    206     if (i < 0 || i >= vertexNum && j < 0 || j >= vertexNum)
    207     {
    208         cout << "顶点不存在" << endl;
    209         return;
    210     }
    211 
    212     int flag = 0;
    213     ArcNode *s, *r;
    214     s = adjlist[i].firstedge;
    215     r = adjlist[i].firstedge;
    216     while (s != NULL)
    217     {
    218         if (s->adjvex == j) {
    219             flag = 1;
    220             if (s == r) {
    221                 if (NULL == s->next) {
    222                     delete s;
    223                     adjlist[i].firstedge = NULL;
    224                     arcNum--;
    225                     return;
    226                 }
    227                 else
    228                 {
    229                     adjlist[i].firstedge = r->next;
    230                     delete s;
    231                     arcNum--;
    232                     return;
    233                 }
    234             }
    235             else
    236             {
    237                 if (NULL == s->next) {
    238                     delete s;
    239                     r->next = NULL;
    240                     arcNum--;
    241                     return;
    242                 }
    243                 else {
    244                     r->next = s->next;
    245                     delete s;
    246                     arcNum--;
    247                     return;
    248                 }
    249             }
    250         }
    251         r = s;
    252         s = s->next;
    253     }
    254     if (!flag) {
    255         cout << "弧不存在" << endl;
    256     }
    257 }
    258 
    259 template<class T>
    260 void ALGraph<T>::DFSTraverse(int v)
    261 {
    262     cout << adjlist[v].vertex << '	';
    263     visited[v] = 1;
    264     ArcNode *p = adjlist[v].firstedge;
    265     while (p) {
    266         int j = p->adjvex;
    267         if (0 == visited[j]) {
    268             DFSTraverse(j);
    269         }
    270         p = p->next;
    271     }
    272 }
    273 
    274 template<class T>
    275 void ALGraph<T>::BFSTraverse(int v)
    276 {
    277     int visited[MAXSIZE];
    278     for (int i = 0; i < vertexNum; i++)
    279         visited[i] = 0;
    280 
    281     int temp, j;
    282     ArcNode *p;
    283     queue<int> Qu;
    284     cout << adjlist[v].vertex << '	';
    285     visited[v] = 1;
    286     Qu.push(v);
    287     while (!Qu.empty()) {
    288         temp = Qu.front();
    289         Qu.pop();
    290 
    291         p = adjlist[temp].firstedge;
    292         while (NULL != p) {
    293             j = p->adjvex;
    294             if (!visited[j]) {
    295                 cout << adjlist[p->adjvex].vertex << '	';
    296                 Qu.push(j);
    297             }
    298             p = p->next;
    299         }
    300     }
    301 }
    302 
    303 template<class T>
    304 void ALGraph<T>::CalAllNodeIns()
    305 {
    306     int count;
    307     ArcNode *s;
    308     for (int i = 0; i < vertexNum; i++)
    309     {
    310         count = 0;
    311         for (int j = 0; j < vertexNum; j++)
    312         {
    313             s = adjlist[j].firstedge;
    314             while (NULL != s) {
    315                 if (s->adjvex == i)    //统计入度
    316                 {
    317                     count++;
    318                     break;
    319                 }
    320                 s = s->next;
    321             }
    322         }
    323         adjlist[i].in = count;
    324     }
    325 
    326 }
    327 
    328 template<class T>
    329 void ALGraph<T>::TopSort()
    330 {
    331     CalAllNodeIns();
    332 
    333     int k, h, count = 0;
    334     ArcNode *p;
    335     stack<int> Stk;
    336     for (int i = 0; i < vertexNum; i++)
    337         if (!adjlist[i].in)
    338             Stk.push(i);            //将入度为0的结点入栈
    339     while (!Stk.empty())
    340     {
    341         k = Stk.top();
    342         Stk.pop();
    343         cout << adjlist[k].vertex << '	';
    344         count++;
    345         p = adjlist[k].firstedge;    //入度为零的结点的邻接点中
    346         while (NULL != p) {
    347             h = p->adjvex;
    348             if (!(--adjlist[h].in))    //入度为1的结点入栈
    349                 Stk.push(h);
    350             p = p->next;
    351         }
    352     }
    353     if (count < vertexNum)
    354         cout << "+ 图中有回路";
    355 }
  • 相关阅读:
    NPM使用技巧
    重构老项目所悟
    Angular2开发笔记
    nodejs项目mysql使用sequelize支持存储emoji
    [原创]django+ldap+memcache实现单点登录+统一认证
    [原创]django+ldap实现单点登录(装饰器和缓存)
    [原创]django+ldap实现统一认证部分二(python-ldap实践)
    [原创]django+ldap实现统一认证部分一(django-auth-ldap实践)
    ldap部署相关,ldap双机LAM配置管理ldap备份还原
    通过pycharm使用git[图文详解]
  • 原文地址:https://www.cnblogs.com/guoyujiang/p/12049120.html
Copyright © 2011-2022 走看看