定义: 图是由有穷的定点集合和有穷的顶点之间的关系集合组成的.

树是一种特殊的图,链表是一种特殊的树

无向边:顶点x和顶点y之间没有方向,(x,y)和(y,x)意义相同表示xy之间有联系

无向图:图中任意两个顶点都是无向边.

有向边:顶点xy之间都是有方向的,<x,y>表示x连接到y,从顶点x可以到顶点y,不可逆. x是尾部,y是头部.  <y,x>

有向图:图中任意两个顶点之间都是有方向的

顶点邻接:两个顶点互相可以抵达.无向图中两个顶点有边则两个顶点互为邻接.有向图中顶点X可以抵达顶点y则顶点x邻接到顶点y

度: 顶点v的度等于和顶点v相关联的边的数目.记为TD(v)

   入度: 以v为头的边的数目.记为ID(v)

   出度:  以v为尾的边的数目.记为OD(v)

权:表示图中顶点间的距离

 

图的存储:

   用一维数组存储顶点:描述相关顶点的数据

   用二维数组存储边:描述顶点间的关系 

  1. 邻接矩阵法:]

                               A = (V , E)是一个有n个顶点的图,则图的邻接矩阵表示为: Edeg[n][n]

         用一个二维数组表示顶点间的关系,二维数组 Edge[i][j] 元素的值表示边的值(权值(距离)).

                         二维数组 Edge[i][j] 的下标表示顶点的编号,有值表示顶点 i 连接到顶点 j的权值. 空值表示没有连接

  

/*
 *    Graph: 图类
 *    成员变量:
 *                
 *  成员函数:
 *                V getVertex(int i)                                    获取位置为i的节点
 *                bool getVertex(int i, V& value)                     判断位置为i的节点和value节点是否相等
 *                bool setVertex(int i, const V& value)                设置节点i的为value
 *                SharedPointer< Array<int> > getAdjacent(int i)        获取节点的i的所有邻接节点
 *                E getEdeg(int i, int j)                                获取节点i和节点j之间的边
 *                bool getEdge(int i, int j, E& value)                判断节点i和节点j之间的边是否和value相等
 *                bool setEdge(int i, int j, const E& value)            设置节点i和节点j之间的边的权重
 *                bool removeEdge(int i, int j)                        去掉节点i和节点j之间的权重
 *                int vCount()                                        计算图中所有的节点
 *                int eCount()                                        计算图中所有的边
 *                int OD(int i)                                        计算节点i的出度
 *                int ID(int i)                                        计算节点i的入度
 *                int TD(int i)                                        计算节点i的度
*/


#ifndef GRAPH_H
#define GRAPH_H

#include "TopClass.h"
#include "SharedPointer.h"
#include "Array.h"

namespace DSL
{
    template <typename V, typename E>
    class Graph : public TopClass
    {
    public:
        virtual V getVertex(int i) = 0;
        virtual bool getVertex(int i, V& value) = 0;
        virtual bool setVertex(int i, const V& value) = 0;
        virtual SharedPointer< Array<int> > getAdjacent(int i) = 0;        
        virtual E getEdeg(int i, int j) = 0;
        virtual bool getEdge(int i, int j, E& value) = 0;
        virtual bool setEdge(int i, int j, const E& value) = 0;
        virtual bool removeEdge(int i, int j) = 0;
        virtual int vCount() = 0;
        virtual int eCount() = 0;
        virtual int OD(int i) =0;
        virtual int ID(int i) = 0;
        virtual int TD(int i) = 0;
    };

}

#endif
Graph.h

 

  1 /*
  2  *    MartixGraph: 邻接矩阵
  3  *
  4  *    模板参数:
  5                N: 顶点的数目 
  6  *               V: 顶点的数据元素类型        
  7  *              E: 边的数据元素类型
  8  *
  9  *    成员变量:
 10  *              V*  m_vertexes[N];    数组保存顶点数据元素,指针数组高效            
 11  *              V*  m_edges[N][N];    数组值为边的权值,第一个N可看作顶点位置
 12  *              int m_ecount;            边总数
 13  *  成员函数:
 14  *                V getVertex(int i)                                    获取位置为i的节点
 15  *                bool getVertex(int i, V& value)                     判断位置为i的节点和value节点是否相等
 16  *                bool setVertex(int i, const V& value)                设置节点i的为value
 17  *                SharedPointer< Array<int> > getAdjacent(int i)        获取节点的i的所有邻接节点
 18  *                E getEdeg(int i, int j)                                获取节点i和节点j之间的边
 19  *                bool getEdge(int i, int j, E& value)                判断节点i和节点j之间的边是否和value相等
 20  *                bool setEdge(int i, int j, const E& value)            设置节点i和节点j之间的边的权重
 21  *                bool removeEdge(int i, int j)                        去掉节点i和节点j之间的权重
 22  *                int vCount()                                        计算图中所有的节点
 23  *                int eCount()                                        计算图中所有的边
 24  *                int OD(int i)                                        计算节点i的出度
 25  *                int ID(int i)                                        计算节点i的入度
 26  *                int TD(int i)                                        计算节点i的度
 27 */
 28 
 29 #ifndef MARTIXGRAPH_H
 30 #define MARTIXGRAPH_H
 31 
 32 #include "Graph.h"
 33 #include "Exception.h"
 34 #include "DynamicArray.h"
 35 
 36 namespace DSL 
 37 {
 38     template <int N, typename V, typename E>
 39     class MartixGraph : public Graph<V, E>
 40     {
 41     protected:
 42         V*  m_vertexes[N];
 43         E*  m_edges[N][N];
 44         int m_ecount;
 45     public:
 46         MartixGraph()
 47         {
 48             for(int i = 0; i < vCount(); i++)
 49             {
 50                 m_vertexes[i] = NULL;
 51                 for(int j = 0; j < vCount(); j++)    
 52                     m_edges[i][j] = NULL;
 53             }
 54             m_ecount = 0;
 55         }
 56 
 57         
 58         V getVertex(int i)
 59         {
 60             V value;
 61             if(!getVertex(i, value))
 62                 THROW_EXCEPTION(InvalidParameterException, "error: invalid params i");
 63             return value;
 64         }
 65         
 66         bool getVertex(int i, V& value) 
 67         {
 68             if((0 <= i) && (i < vCount()))
 69             {
 70                 if(m_vertexes[i] != NULL)
 71                 {
 72                     value = *(m_vertexes[i]);
 73                 }
 74                 else
 75                 {
 76                     THROW_EXCEPTION(InvalidOperationException, "error: No element in this vertex!");
 77                 }
 78                 return ture;
 79             }
 80             return false;
 81         }
 82 
 83         bool setVertex(int i, const V& value)
 84         {
 85             if((0 <= i) && (i < vCount()))
 86             {
 87                 V* temp = m_vertexes[i];
 88                 if(temp == NULL)
 89                     temp = new V();
 90                 if(temp == NULL)
 91                 {
 92                     THROW_EXCEPTION(NotEnoughMemoryException, "error: no enough memory to malloc new vertex!");
 93                 }
 94                 else
 95                 {
 96                     *temp = value;
 97                     m_vertexes[i] = temp;
 98                 }
 99                 return ture;
100             }
101             return false;            
102         }
103         
104         SharedPointer< Array<int> > getAdjacent(int i)
105         {
106             DynamicArray<int>* vertex_array = NULL;    
107             if((0 <= i) && (i < vCount()))
108             {
109                 int count = 0;
110                 for(int j = 0; j < vCount(); j++)
111                 {
112                     if(m_edges[i][j] != NULL)
113                         count++;
114                 }
115                 vertex_array = new DynamicArray<int>(count);
116                 if(vertex_array == NULL)
117                 {
118                     THROW_EXCEPTION(NotEnoughMemoryException, "error: no enough memory to malloc new vertex!");
119                 }
120                 else
121                 {
122                     for(int j = 0, m = 0; j < vCount(); j++)
123                     {
124                         if(m_edges[i][j] != NULL)
125                             vertex_array->set(m++, j);
126                     }
127                 }
128             }
129             else
130             {
131                 THROW_EXCEPTION(InvalidParameterException, "error: invalid params");
132             }
133             return vertex_array;
134         }
135         
136         E getEdeg(int i, int j)    
137         {
138             E value;
139             if(!getEdge(i, j, value))
140                 THROW_EXCEPTION(InvalidParameterException, "error: invalid params");
141             return value;
142         }
143         
144         bool getEdge(int i, int j, E& value)
145         {
146             if((0 <= i) && (i < vCount()) && (0 <= j) && (j < vCount()))
147             {
148                 if(m_edges[i][j] != NULL)
149                     value = *(m_edges[i][j]);
150                 else
151                     THROW_EXCEPTION(InvalidOperationException, "error: No element in this vertex!");
152                 return ture;
153             }
154             else
155             {
156                 return false;
157             }
158         }
159 
160         bool setEdge(int i, int j, const E& value)
161         {
162             if((0 <= i) && (i < vCount()) && (0 <= j) && (j < vCount()))
163             {
164                 E* temp = m_edges[i][j];
165                 if(temp == NULL)
166                 {
167                     temp = new E();
168                     if(temp)
169                     {
170                         *temp = value;
171                         m_edges[i][j] = temp;
172                         m_ecount++;
173                     }
174                     else
175                     {
176                         THROW_EXCEPTION(NotEnoughMemoryException, "error: no enough memory to malloc edge");
177                     }
178                 }
179                 else
180                 {
181                     *temp = value;
182                 }
183                 return ture;
184             }
185             else
186             {
187                 return false;
188             }
189         }
190         
191         bool removeEdge(int i, int j)
192         {
193             if((0 <= i) && (i < vCount()) && (0 <= j) && (j < vCount()))
194             {
195                 E* toDel = m_edges[i][j];
196                 m_edges[i][j] = NULL;
197                 if(toDel != NULL)
198                 {
199                     m_ecount--;
200                     delete toDel;
201                 }
202                 return ture;
203             }
204             else
205             {
206                 return false;
207             }
208         }
209 
210         int vCount()
211         {
212             return N;
213         }
214         
215         int eCount()                                    
216         {
217             return m_ecount;
218         }
219         
220         int OD(int i)
221         {
222             int count = 0;
223             if((0 <= i) && (i < vCount()))                    
224             {
225                 for(int j = 0; j < vCount(); j++)
226                 {
227                     if(m_edges[i][j] != NULL)
228                         count++;
229                 }
230             }
231             else
232             {
233                 THROW_EXCEPTION(InvalidParameterException, "error: inalid parameter");
234             }
235             return count;
236         }
237         
238         int ID(int i)                                    
239         {
240             int count = 0;
241             if((0 < i) && (i < vCount()))                    
242             {
243                 for(int j = 0; j < vCount(); j++)
244                 {
245                     if(m_edges[j][i] != NULL)
246                         count++;
247                 }
248             }
249             else
250             {
251                 THROW_EXCEPTION(InvalidParameterException, "error: inalid parameter");
252             }
253             return count;
254         }
255 
256         int TD(int i)                                    
257         {
258             return (ID(i) + OD(i));
259         }
260 
261         ~MartixGraph()
262         {
263             for(int i = 0; i < eCount(); i++)
264             {
265                 for(int j = 0; j < eCount(); j++)    
266                     delete m_edges[i][j];
267                 delete m_vertexes[i];
268             }
269             m_ecount = 0;
270         }
271     };
272 }
273 
274 #endif
MartixGraph.h

 

 

 

  2.邻接链表法

      所有顶点按照编号存储于同一链表中

      每一个顶点对应的节点又是一个链表的头节点,链表的每个节点存储指向其他节点边的信息,一条边的信息包含:起点,终点,权重

    

/*
 *    ListGraph: 邻接链表
 *
 *    模板参数:
 *               V: 顶点的数据元素类型        
 *              E: 边的数据元素类型
 *
 *    成员变量:
 *              struct Edges{
 *                      int e_start;            边的起始点
 *                    int e_end;              边的终点
 *                      E data;}                边的权值
 *
 *              struct Vertex{
 *                    V* data;                顶点的数据元素
 *                    LinkList<Edges> edges;} 保存所有邻接到这个顶点边的信息
 *               LinkList<Vertex*> m_list        邻接链表
 *              int m_ecount;                    边总数
 *  成员函数:
 *                int addVertex()                                     在链表尾部插入新的顶点,返回顶点编号
 *                int addVertex(const& value)                            增加新的顶点并添加顶点元素
 *                bool removeVertex()                                    删除链表尾部的顶点,删除相关边
 *                V getVertex(int i)                                    获取位置为i的节点
 *                bool getVertex(int i, V& value)                     判断位置为i的节点和value节点是否相等
 *                bool setVertex(int i, const V& value)                设置节点i的为value
 *                SharedPointer< Array<int> > getAdjacent(int i)        获取节点的i的所有邻接节点
 *                E getEdge(int i, int j)                                获取节点i和节点j之间的边
 *                bool getEdge(int i, int j, E& value)                判断节点i和节点j之间的边是否和value相等
 *                bool setEdge(int i, int j, const E& value)            设置节点i和节点j之间的边的权重
 *                bool removeEdge(int i, int j)                        去掉节点i和节点j之间的权重
 *                int vCount()                                        计算图中所有的节点
 *                int eCount()                                        计算图中所有的边
 *                int OD(int i)                                        计算节点i的出度
 *                int ID(int i)                                        计算节点i的入度
 *                int TD(int i)                                        计算节点i的度
*/

#ifndef LISTGRAPH_H
#define LISTGRAPH_H

#include "Graph.h"
#include "LinkList.h"
#include "Exception.h"
#include "DynamicArray.h"

namespace DSL 
{
    template<typename E>
    struct Edge : public TopClass
    {
        int e_sta;
        int e_end;
        E data;

        Edge(int i = -1, int j = -1)
        {
            e_sta = i;
            e_end = j;
        }

        Edge(int i, int j, const E& value)
        {
            e_sta = i;
            e_end = j;
            data = value;
        }

        bool operator == (const Edge<E>& obj)
        {
            return     ((e_sta == obj.e_sta) && (e_end == obj.e_end));
        }

        bool operator != (const Edge<E>& obj)
        {
            return     !(obj == *this);
        }

    };

    template <typename V, typename E>
    class ListGraph : public TopClass
    {
    protected:
        struct Vertex : public TopClass
        {
            V* data;
            LinkList<Edge<E>> edge;
            
            Vertex()
            {
                data = NULL;
            }
        };
    
        LinkList<Vertex*> m_list;

    public:
        ListGraph(unsigned int pos = 0)
        {
            for(int i = 0; i < pos; i++)
                addVertex();
        }

        int addVertex()
        {
            int pos = -1;
            Vertex* temp_v = new Vertex();
            if(temp_v != NULL)
            {
                m_list.insert(temp_v);
                pos = m_list.length() - 1;
            }
            else
            {
                THROW_EXCEPTION(NotEnoughMemoryException, "error: no enough memory to create Vertex");
            }
            return pos;
        }
        
        int addVertex(const V& value)
        {
            int pos = addVertex();
            if(pos >= 0)
            {
                setVertex(pos, value);
            }
            else
            {
                THROW_EXCEPTION(IdexOutOfBoundException, "error: index out of bound");
            }
        }

        
        bool removeVertex()                    
        {
            int index = m_list.length() - 1;
            if(index >= 0)
            {
                Vertex* v = m_list.get(index);
                if(m_list.remove(index))
                {
                    for(int i = (m_list.move(0), 0); !m_list.end(); i++,  m_list.next())
                    {
                        int pos = m_list.current()->edge.find(Edge<E>(i, index)); // 删除与这个顶点相关的边
                        if(pos >= 0)
                            m_list.current()->edge.remove(pos);
                    }
                }
                delete v->data;
                delete v;
                return ture;
            }
            else
            {
                THROW_EXCEPTION(InvalidOperationException, "error: no vertex in this graph");
            }
        }
        
        V getVertex(int i)    
        {
            V ret;
            if(!getVertex(i, ret))
                THROW_EXCEPTION(IdexOutOfBoundException, "error: index out of bound");
            return ret;
        }
        
        bool getVertex(int i, V& value)
        {
            bool ret = ((0 <= i) && (i < vCount()));
            if(ret)
            {
                Vertex* temp_v = m_list.get(i);
                if(temp_v->data != NULL)
                {
                    value = *(temp_v->data);
                }
                else
                {
                    THROW_EXCEPTION(InvalidOperationException, "error: no value assigned to this vertex");
                }
            }
            return ret;

        }
        
        bool setVertex(int i, const V& value)            
        {
            bool ret = ((0 <= i) && (i < vCount()));
            if(ret)
            {
                Vertex* temp_v = m_list.get(i);
                V* temp_d = temp_v->data;
                if(temp_d == NULL)
                {
                    temp_d = new V();
                    if(temp_d)
                    {
                        *temp_d = value;
                        temp_v->data = temp_d;
                        ret = ture;
                    }
                    else
                    {
                        THROW_EXCEPTION(NotEnoughMemoryException, "error: no enough memory to create data");
                    }
                }
            }
            else
            {
                THROW_EXCEPTION(IdexOutOfBoundException, "error: index out of bound");
            }
            return ret;
        }

        SharedPointer< Array<int> > getAdjacent(int i)
        {
            DynamicArray<int>* ad_array = NULL;
            if((0 <= i) && (i < vCount()))
            {
                Vertex* temp_v = m_list.get(i);
                ad_array = new DynamicArray<int>(temp_v->edge.length());
                if(ad_array != NULL)
                {
                    for(int i = (temp_v->edge.move(0), 0); !temp_v->edge.end(); i++, temp_v->edge.next())
                    {
                        ad_array->set(i, temp_v->edge.current().e_end);
                    }
                }
                else
                {
                    THROW_EXCEPTION(NotEnoughMemoryException, "error: no enough memory to create data");
                }
            }
            else
            {
                THROW_EXCEPTION(IdexOutOfBoundException, "error: index out of bound");
            }
            return ad_array;
        }

        
        E getEdge(int i, int j)
        {
            E ret;
            if(!getEdge(i, j, ret)) 
                THROW_EXCEPTION(InvalidParameterException, "error: Invalid Parameter");
            
            return ret;
        }

        bool getEdge(int i, int j, E& value)
        {
            bool ret = ((0 <= i) && (i < vCount()) && (0 <= j) && (j < vCount()));
            if(ret)
            {
                Vertex* temp_v = m_list.get(i);
                int pos = temp_v->edge.find(Edge<E>(i, j));
                if(pos >= 0)
                {
                    value = temp_v->edge.get(pos).data;
                }
                else
                {
                    THROW_EXCEPTION(IdexOutOfBoundException, "error: index out of bound");
                }
            }
            else
            {
                THROW_EXCEPTION(IdexOutOfBoundException, "index out of bound");
            }
            return ret;
        }
        
        bool setEdge(int i, int j, const E& value)
        {
            bool ret = ((0 <= i) && (i < vCount()) && (0 <= j) && (j < vCount()));
            if(ret)
            {
                Vertex* temp_v = m_list.get(i);
                int pos = temp_v->edge.find(Edge<E>(i, j));
                if(pos >= 0)
                {
                    ret = temp_v->edge.set(pos, Edge<E>(i, j, value));
                }
                else
                {
                    ret = temp_v->edge.insert(0, Edge<E>(i, j, value));
                }
            }
            else
            {
                THROW_EXCEPTION(IdexOutOfBoundException, "index out of bound");
            }
            return ret;
        }
        
        bool removeEdge(int i, int j)                    
        {
            bool ret = ((0 <= i) && (i < vCount()) && (0 <= j) && (j < vCount()));
            if(ret)
            {
                Vertex* temp_v = m_list.get(i);
                int pos = temp_v->edge.find(Edge<E>(i, j));
                if(pos >= 0)
                {
                    ret = temp_v->edge.remove(pos);
                }
                else
                {
                    THROW_EXCEPTION(IdexOutOfBoundException, "index out of bound");
                }
            }
            else
            {
                THROW_EXCEPTION(IdexOutOfBoundException, "index out of bound");
            }
            return ret;
        }

        int vCount()
        {
            return m_list.length();
        }

        int eCount()                                    
        {
            int count = 0;
            for(m_list.move(0); !m_list.end(); m_list.next())
                count += m_list.current()->edge.length();
            return count;
        }

        int ID(int i)                                    
        {
            int count = 0;
            if((0 <= i) && (i < vCount()))
            {
                for(m_list.move(0); !m_list.end(); m_list.next())
                {
                    for(m_list.current()->edge.move(0); !m_list.current()->edge.end(); m_list.current()->edge.next())
                    {
                        if(m_list.current()->edge.current().e_end == i)
                        {
                            count++;
                            break;
                        }
                    }
                }
            }
            else
            {
                THROW_EXCEPTION(IdexOutOfBoundException, "index out of bound");
            }
            return count;
        }

        int OD(int i)                                    
        {
            int count = 0;
            if((0 <= i) && (i < vCount()))
            {
                count = m_list.get(i)->edge.length();
            }
            else
            {
                THROW_EXCEPTION(IdexOutOfBoundException, "index out of bound");
            }
            return count;
        }

        int TD(int i)                                    
        {
            return (ID(i) + OD(i));
        }

        ~ListGraph()
        {
            while(m_list.length() > 0)
            {
                Vertex* toDel = m_list.get(0);
                m_list.remove(0);
                delete toDel->data;
                delete toDel;
            }
        }
    };
}

#endif
View Code

 

 图的遍历

  1. BFS(广度优先算法)

     类似于树的层次遍历,先遍历同一层次的横向节点,

     使用两个队列temp_queue,ret_queue,一个数组marked[]标记节点是否访问过

     a. 先将起始顶点V压入队列temp_queue中

     b. 再将队列temp_queue的头顶点V弹出,判断是否访问过(访问过转b,没有访问过转c)

     c. 标记顶点V为访问过,将V的邻接节点压入队列temp_queue

     d. 判断队列temp_queue是否为空,空则返回ret_queue(非空转b)

     

 1 SharedPointer<Array<int>> BFS(int i)
 2         {
 3             DynamicArray<int>* output_array = NULL;
 4 
 5             if((0 <= i) && (i < vCount()))
 6             {
 7                 DynamicArray<bool> marked(vCount());
 8                 LinkListQueue<int> tmp_queue;
 9                 LinkListQueue<int> ret_queue;
10 
11                 for(int j = 0; j < vCount(); j++)
12                     marked[j] = false;
13 
14                 tmp_queue.add(i);
15                 while(0 < tmp_queue.length())
16                 {
17                     int v = tmp_queue.front();
18                     tmp_queue.remove();
19                     if(!marked[i])
20                     {
21                         SharedPointer<Array<int>> ad = getAdjacent(v);
22                         for(int j = 0; j < ad->length(); j++)
23                             tmp_queue.add((*ad)[j]);
24                     }
25                     ret_queue.add(v);
26                     marked[i] = ture;
27                 }
28 
29                 output_array = new DynamicArray<int>(ret_queue.length());
30                 if(output_array)
31                 {
32                     for(int j = 0; j < output_array->length(); j++, ret_queue.remove())
33                         output_array->set(j, ret_queue.front());
34                 }
35                 else
36                 {
37                     THROW_EXCEPTION(NotEnoughMemoryException, "error: no enough to create array");
38                 }
39             }
40             else
41             {
42                 THROW_EXCEPTION(IdexOutOfBoundException, "error: index out of bound");
43             }
44             return output_array;            
45         }
46         
View Code

 

   

   2. DFS(深度优先算法)

     类似于树的前序遍历,先遍历纵向的节点,当前节点没有可以访问的邻接节点则回退

    使用一个栈temp_stack,一个队列ret_queue,一个数组marked[]标记节点是否被访问过

       a. 将起始顶点V_top压入栈中

    b. 弹出起始顶点v_top,判断是否被访问过/标记过(被访问过则丢掉当前节点再转b,没有转c)

    c. 标记顶点v_top,将v_top顶点压入ret_queue中,并将顶点v_top的邻接顶点压入栈中

    d. 栈为空则返回(非空转b)

 

 1         SharedPointer< Array<int> > DFS(int i)
 2         {
 3             DynamicArray<int>* output_array = NULL;
 4             if((0 <= i) && (i < vCount()))
 5             {
 6                 LinkListStack<int> temp_stack;
 7                 LinkListQueue<int> ret_queue;
 8                 DynamicArray<bool> marked(vCount());
 9         
10                 for(int j = 0; j < vCount(); j++)
11                     marked.set(j, false);
12         
13                 temp_stack.push(i);
14                 while(0 < temp_stack.size())
15                 {
16                     int v = temp_stack.top();
17                     temp_stack.pop();
18                     if(marked[i] != ture)
19                     {
20                         SharedPointer< Array<int> > temp_ad = getAdjacent(v);
21                         for(int j = temp_ad->length() - 1; 0 <= j; j--)
22                             temp_stack.push((*temp_ad)[j]);
23                     }
24                     ret_queue.add(v);
25                     marked[i] = ture;
26                 }
27 
28                 output_array = new DynamicArray<int>(ret_queue.length());
29                 if(output_array)
30                 {
31                     for(int j = 0; j < output_array->length(); j++, ret_queue.remove())
32                         output_array->set(j, ret_queue.front());
33                 }
34                 else
35                 {
36                     THROW_EXCEPTION(NotEnoughMemoryException, "error: no enough to create array");
37                 }
38                 return output_array;
39             }
40             else
41             {
42                 THROW_EXCEPTION(IdexOutOfBoundException, "error: index out of bound");
43             }
44         }
View Code

 

 

  3. DFS (递归实现)

    将遍历的图G分为两个部分,第一部分是起始顶点V0,第二部分其他顶点组成的子图G'。

    DFS(G) = visited(V0) + DFS(G')  //G'为空则返回

    DFS(graph, vex) 以顶点vex为起始顶点深度优先遍历graph

      a. 访问vex节点,如果vex的邻接顶点为空,即返回

      b. 先访问起始顶点vex,再判断vex的邻接顶点不为空,获取临界顶点为新的起始顶点,继续递归。

 1         SharedPointer< Array<int> > DFS_R(int i)
 2         {
 3             DynamicArray<int>* output_array = NULL;
 4             if((0 <= i) && (i < vCount()))
 5             {
 6                 LinkListQueue<int> ret_queue;
 7                 DynamicArray<bool> marked(vCount());
 8                 for(int j = 0; j < vCount(); j++)
 9                     marked.set(j, false);
10         
11                 DFS_R_core(*this, i, marked, ret_queue);
12 
13                 output_array = new DynamicArray<int>(ret_queue.length());
14                 if(output_array)
15                 {
16                     for(int j = 0; j < output_array->length(); j++, ret_queue.remove())
17                         output_array->set(j, ret_queue.front());
18                 }
19             }
20             else
21             {
22                 THROW_EXCEPTION(IdexOutOfBoundException, "error: index out of bound");
23             }
24             return output_array;
25         }
26 
27         void DFS_R_core(Graph<V, E>& g, int i, Array<bool>& marked, LinkListQueue<int>& ret_queue)
28         {
29             ret_queue.add(i);
30             marked[i] = ture; 
31             SharedPointer< Array<int> > ad = g.getAdjacent(i);
32             for(int j = 0; j < ad->length(); j++)
33             {
34                 if(!marked[(*ad)[j]])
35                     DFS_R_core(g, (*ad)[j], marked, ret_queue);
36             }
37         }
38     };
View Code

 

  4. Prim(最小生成树)

    如何使得再图中选择n-1条边使得n个顶点之间两两可达,并使得n-1条边权值最小

    a. 仅使用图中的n-1条边连接图中的n个顶点

    b. 不能使用产生回路的边    

    c. 各边的权值总和达到最小

    d.只针对无向图

    算法组成: 

      Array<bool> marked 标记顶点所属集合{T / F}.数组下标表示顶点坐标,数组值表示顶点的位置.

      Array<E> cost 记录T集合到F集合中所有不同顶点之间边的集合并选择最小那条边并标记边的末尾顶点到marked数组(如果T顶点集合到F顶点集合之间F的同一顶点连接有多条,选取权值最小的连接).

             数组值表示边的权值,数组下标和adjVex数组下标一一对应并表示图的边

      Array<int> adjVex 记录cost数组中权值对应的顶点.数组下标表示边的终止顶点,数组值表示边的起始顶点.

      Queue<Edge> ret 记录最小生成树中的边

    算法步骤:

      a. 选择某一项顶点v0作为起始顶点,使得T = {v0};F = {v1,v2,,,vn}; E = {  };

      b. 每次选择一条边,这条边是边集合(U, V)中权值最小的边,且U属于T,V属于F

      c. 修改T,F,E:T = T + {V}, F = F - {V}, E = E +  {(U, V)}

      d. 当F != NULL时且T到F是有连接的,即是(U,V)存在,则转b.否则结束

 

posted @ 2020-06-11 08:09  张不源  Views(235)  Comments(0Edit  收藏  举报