数据结构--无向图--初级版

其实图的存储结构很简单,常见的就是邻接表和邻接矩阵。

个人觉得,比较复杂的是求最短路径之类的算法。

下面先发一个基础版的,实现了深度和广度优先遍历。

但这里的遍历方法和大多数教科书上有了一点区别,就是没有用递归,而是用栈代替了。因为递归是讲所谓的“现场”保存到调用栈中,而调用栈好像很小,很容易溢出。

但这个版本也存在一些效率问题,我会在注释里写出

里面使用的liststock其实就是封装了一个前面介绍的链表类。很简单

 

  1 #pragma once;
  2 #include <iostream>
  3 #include "mylist.h"
  4 #include "liststack.h"
  5 
  6 /************************************************************************/
  7 /* 用邻接表结构实现图                                                                                                      */
  8 /************************************************************************/
  9 
 10 template<typename T>
 11 struct vertex
 12 {
 13     T data;
 14     int nWeight;
 15     mylist<int> borders;
 16 };
 17 
 18 const int MAX_VERTEX_COUNT = 6;
 19 
 20 template<typename T>
 21 class mygraph
 22 {
 23 public:
 24     mygraph()
 25     {
 26         m_size = MAX_VERTEX_COUNT;
 27 
 28     }
 29 
 30     void setVertexData(int nVertex, const T& data, int nWeight)
 31     {
 32         if(nVertex >= m_size)
 33         {
 34             throw("超出顶点数量");
 35         }
 36         m_vertexlist[nVertex].data = data;
 37         m_vertexlist[nVertex].nWeight = nWeight;
 38     }
 39 
 40     void addBorder(int nVertex, int nRelation)
 41     {
 42         if(nVertex >= m_size || nRelation >= m_size)
 43         {
 44             throw("超出顶点数量");
 45         }
 46         _addBorder(nVertex, nRelation);
 47         _addBorder(nRelation, nVertex);
 48         //无向图,需要同时设置两个顶点的关系
 49     }
 50 
 51     //广度优先遍历
 52     void BFS(int nFirstVertex)
 53     {
 54         bool visitRecord[MAX_VERTEX_COUNT];
 55         liststack<int> searchStack;
 56 
 57 
 58         
 59         searchStack.push(nFirstVertex);
 60         while(!searchStack.empty())
 61         {
 62             int nCurrentVertex = searchStack.pop();
 63 
 64             visitRecord[nCurrentVertex] = true;
 65             
 66             mylist<int>::Iterator iBegin = m_vertexlist[nCurrentVertex].borders.begin();
 67             while(iBegin != m_vertexlist[nCurrentVertex].borders.end())
 68             {
 69                 if(!visitRecord[*iBegin])
 70                 {
 71                     visitRecord[*iBegin] = true;
 72                     //
 73                     searchStack.push(*iBegin);
 74                     cout<< nCurrentVertex << "--" <<  *iBegin << endl;
 75                     
 76                 }
 77                 iBegin ++;
 78             }
 79         
 80         }
 81 
 82         
 83     }
 84 
 85     //深度优先遍历
 86     void DFS(int nFirstVertex)
 87     {
 88         bool visitRecord[MAX_VERTEX_COUNT];
 89         liststack<int> searchStack;
 90 
 91         int i;
 92         for(i = 0; i < m_size; i ++)
 93         {
 94             visitRecord[i] = false;
 95         }
 96         
 97     
 98         
 99         while(!searchStack.empty())
100         {
101             int nCurrentVertex = searchStack.top();
102 
103             visitRecord[nCurrentVertex] = true;
104         
105             mylist<int>::Iterator iBegin = m_vertexlist[nCurrentVertex].borders.begin();
106 
107             //这里就存在一个效率问题,每次都从邻接表的头开始遍历。
108             //但之所以没有保存链表中的迭代器对象,是担心在多线程操作中,
109             //可能一个线程遍历,另一个线程在给图增加定点。
110             //虽然这个实现版本中定点数是固定的,但绝对很容易就改成可动态增长的。
111             //一旦数组动态增长,那么链表中的指针就会变为无效。
112             //大家都知道,复制指针是很危险的,除非用灵巧指针代替。
113             //今后的版本中会修改这个问题
114             while(iBegin != m_vertexlist[nCurrentVertex].borders.end())
115             {
116                 if(!visitRecord[*iBegin])
117                 {
118                     visitRecord[*iBegin] = true;
119                     searchStack.push(*iBegin);
120                     cout << nCurrentVertex << "-" << *iBegin << endl;
121                     break;
122                 }
123                 iBegin ++;
124             }
125             if(iBegin == m_vertexlist[nCurrentVertex].borders.end())
126             {
127                 
128                 searchStack.pop();
129             }
130         }
131     }
132 
133 private:
134     void _addBorder(int nVertex, int nRelation)
135     {
136 
137         if(!(m_vertexlist[nVertex].borders.find(nRelation) == m_vertexlist[nVertex].borders.end()))
138         {
139             return ;
140         }
141 
142         m_vertexlist[nVertex].borders.insert(nRelation);
143     }
144     size_t m_size;
145     vertex<T> m_vertexlist[MAX_VERTEX_COUNT];
146 
147 };
posted @ 2008-10-06 22:55  刺儿头  阅读(453)  评论(0编辑  收藏  举报