图的相关操作【C++数据结构】

图的相关操作~~~~~~

一共六个类,分别实现加权有向图的建立,遍历,宽度遍历,深度遍历

                    加权无向图的最小耗费生成书

存储结构用的是二维数组~~~~

第一个类,加权有向~~~~main方法在其cpp文件中~~~

 

template <class T>
class AdjacencyWDigraph 
{
public:
 AdjacencyWDigraph(int Vertices = 8,T noEdge=0);
 virtual ~AdjacencyWDigraph(){Delete2DArray(a,n+1);}
 bool Exist(int i,int j) const;
 
 int Edges() const {return e;}
 int Vertices() const {return n;}
 
 AdjacencyWDigraph<T>& Add(int i,int j ,const T& w);
    AdjacencyWDigraph<T>& Delete(int i,int j);
 int OutDegree(int i) const;
 int InDegree(int i) const;
   //二维
 void Make2DArray(T ** &x,int rows,int cols);
 void Delete2DArray(T ** &x,int rows);
   //遍历
 void InitializePos(){pos=new int[n+1];}
 void DeactivatePos(){delete [] pos;}
 int Begin(int i);
 int NextVertex(int i);
 //宽度深度
 void BFS(int v,int reach[],int label);
    void DFS(int v,int reach[],int label);
 void dfs(int v,int reach[],int label);

 

 

 T NoEdge;
 int n;
 int e;
 T **a;
 int *pos;

};

 

#include "AdjacencyWDigraph.h"
#include "iostream.h"
#include "BadInput.h"
#include "LinkedQueue.h"
#include "OutOfBounds.h"
#include "AdjacencyWGraph.h"

 
//
// Construction/Destruction
//
//基本操作
template <class T>
AdjacencyWDigraph<T>::AdjacencyWDigraph(int Vertices ,T noEdge)
{
 n = Vertices;
 e = 0;
 NoEdge = noEdge;
 Make2DArray(a,n+1,n+1);
 for(int i =1;i <= n;i++)
  for(int j =1;j <=n;j++)
   a[i][j] = NoEdge;
}

template <class T>
bool AdjacencyWDigraph<T>::Exist(int i,int j) const
{
 if(i<1 || j<1 || i>n || j>n || a[i][j]==NoEdge)
  return false;
 return true;
}

template <class T>
AdjacencyWDigraph<T>& AdjacencyWDigraph<T>::Add(int i,int j ,const T&w)
{
     if(i<1 || j<1 || i>n || j>n ||  i==j || a[i][j]!=NoEdge)
            throw BadInput();
  a[i][j] = w;
  e++;
  cout <<"a["<<i<<"]["<<j<<"]="<<a[i][j]<<endl;
  return *this;
 
}

template <class T>
AdjacencyWDigraph<T>& AdjacencyWDigraph<T>::Delete(int i,int j)
{
 if(i<1 || j<1 || i>n || j>n ||   a[i][j]==NoEdge)
            throw BadInput();
    a[i][j] =NoEdge;
 e--;
 return *this;

}

template <class T>
int AdjacencyWDigraph<T>::OutDegree(int i) const
{
 if(i<1 || i>n) throw BadInput();
 int sum=0;
 for(int j=1;j<=n;j++)
  if(a[i][j] !=NoEdge)
   sum++;
 return sum;
}

template <class T>
int AdjacencyWDigraph<T>::InDegree(int i) const
{
    if(i<1 || i>n) throw BadInput();
 int sum=0;
 for(int j=1;j<=n;j++)
  if(a[j][i] !=NoEdge)
   sum++;
 return sum;
}
//二维数组
template <class T>
void AdjacencyWDigraph<T>::Make2DArray(T ** &x,int rows,int cols)
{
 x=new T * [rows];
 for(int i=0;i<rows;i++)
  x[i]=new int [cols];
}
template <class T>
void AdjacencyWDigraph<T>::Delete2DArray(T ** &x,int rows)
{
 for(int i=0;i<rows;i++)
  delete [] x[i];
 delete [] x;
 x=0;
}
//遍历
template <class T>
int AdjacencyWDigraph<T>::Begin(int i)
{
 if(i<1 || i>n) throw OutOfBounds();
   
 for(int j=1;j<=n;j++)
  if(a[i][j] != NoEdge)
  {
   pos[i]=j;//若未初始化出错
   return j;
  }
 
 pos[i]=n+1;
 return 0;
}
template <class T>
int AdjacencyWDigraph<T>::NextVertex(int i)
{
 if(i<1 || i>n) throw OutOfBounds();
   
 for(int j=pos[i]+1;j<=n;j++)
  if(a[i][j] != NoEdge)
  {
   pos[i]=j;
   return j;
  }
 
 pos[i]=n+1;
 return 0;
 
}
//宽度遍历
template <class T>
void AdjacencyWDigraph<T>::BFS(int v,int reach[],int label)
{
 LinkedQueue<int> Q;
 InitializePos();
 reach[v]=label;
 Q.Add(v);
 while(!Q.IsEmpty())
 {
  int w;
  Q.Delete(w);
  cout<<w;
  int u=Begin(w);
  while(u)
  {
   if(reach[u] !=label)
   {
    Q.Add(u);
    reach[u]=label;
   }
   u=NextVertex(w);     
  } 
 }
 DeactivatePos(); 
}
//深度遍历
template <class T>
void AdjacencyWDigraph<T>::DFS(int v,int reach[],int label)
{
 InitializePos();
 dfs(v,reach,label);//用到递归
 DeactivatePos();
}
template <class T>
void AdjacencyWDigraph<T>::dfs(int v,int reach[],int label)
{
 cout <<v;
 reach[v]=label;
 int u=Begin(v); 

 while(u)
 {
  if(reach[u] !=label)
   dfs(u,reach,label);
  u=NextVertex(v);
  
 }
 cout<<endl;
}

void main()
{
 AdjacencyWDigraph<int> graph(6,0);
 cout<<"建立有向加权图,添加下列节点:"<<endl;
    graph.Add(1,2,3);
 graph.Add(2,3,8);
 graph.Add(1,4,7);
 graph.Add(3,5,2);
 graph.Add(1,6,20);
 graph.Add(4,5,11);
 graph.Add(6,5,1);
 
 graph.InitializePos();

 cout<<"宽度遍历结果 : "<<endl;
    int reach2[6];
 graph.BFS(1,reach2,9);

 cout<<endl;
 cout<<"深度遍历结果:"<<endl;
 int reach1[6];
 graph.DFS(1,reach1,9);//深度成功!!
   
 //遍历
 cout<<"执行遍历操作:"<<endl;
 cout<<"遍历所有从顶点i所到达的下一顶点j:【输入整数i,1<=i<=6】 ";
 int i;
 cin >>i;
 cout <<graph.Begin(i);
    cout <<graph.NextVertex(i);
 cout <<graph.NextVertex(i)<<endl;
   
 //#define INF 999999
    AdjacencyWGraph<int> gra(6,INF);
 cout<<"建立无向加权图,添加下列节点:"<<endl;
    gra.Add(1,2,3);
 gra.Add(2,3,8);
 gra.Add(1,4,7);
 gra.Add(3,5,2);
 gra.Add(1,6,20);
 gra.Add(4,5,11);
 gra.Add(6,5,1);
 cout<<"最小耗费生成数:";
 gra.Prim(6,gra.a);
  
    cout<<"结束"<<endl;


 

}

第二个类,加权无向图,继承加权有向图,实现最小生成树的prim方法,只有头文件

#include "AdjacencyWDigraph.h"
#include "iostream.h"
#include "BadInput.h"
#include "OutOfBounds.h"

template <class T>
class AdjacencyWGraph : public AdjacencyWDigraph<T> 
{
public:
 AdjacencyWGraph(int Vertices = 8,T noEdge=0):AdjacencyWDigraph<T>(Vertices,noEdge){}
 
 AdjacencyWGraph<T>& Add(int i,int j ,const T& w)
 {
  AdjacencyWDigraph<T>::Add(i,j,w);
  a[j][i]=w;
  cout <<"a["<<j<<"]["<<i<<"]="<<w<<endl;
  return *this;
 }
    AdjacencyWGraph<T>& Delete(int i,int j)
 {
  AdjacencyWDigraph<T>::Delete(i,j);
  a[j][i]=NoEdge;
  return *this;
 }
 int Degree(int i) const {return OutDegree(i);}
 void First(int i,int& j,T& c)
 {
    if(i<1 || i>n) throw OutOfBounds();
       if(a[i][j] != NoEdge)
  {
   c=a[i][j];
  }
 

 }
 void Next(int i,int& j,T& c)
 {
 
 }

#define INF 999999 //定义无穷大值

void Prim(int n, int **c)
{
   int *lowcost;
   int *closest;
   bool *s;

   lowcost = new int[n];
   closest = new int[n];
   s = new bool[n];

   s[1] = true;
   for(int i=2;i<=n;i++)
   {
      lowcost[i] = c[1][i]; //初始化,lowcost为第一行各权值(与定点一相连的各边权值)
      closest[i]=1; //closest全部为1
      s[i] = false; //布尔值全部为false,即未经过该边
   }

   cout<<"最小生成树为:"<<endl;
  
 
   for(i=1;i<n;i++) //一共n个节点,循环N次~~~~
   {
      int min = INF;
      int j=1;
      for(int k=2;k<=n;k++)
         if((lowcost[k]<min) && (!s[k]))//找出与其相连最小耗费边~~~~
   {
           min=lowcost[k];
           j=k;
   }                     
      cout<<j<<' '<<closest[j]<<endl; //输出

      s[j]=true; //标记此边已经过~~~~
     for(k=2;k<=n;k++)
        if((c[j][k]<lowcost[k]) && (!s[k])) //若顶点为经过~~~筛选出比前行权值小的边
  {
           lowcost[k] = c[j][k]; //传入与下一定点相连权值~~~结果得到了经过两点的所有未经过边的最小权值
           closest[k] = j;
  } 
   }
}

 

 


};

#endif // !defined(AFX_ADJACENCYWGRAPH_H__5770FF91_2A47_4A39_BF85_B49CAFA12602__INCLUDED_)

第三个类,队列,用于实现宽度遍历~~~~~~

#include "Node.h"

template<class T>
class LinkedQueue 
{
public:
 LinkedQueue();
 virtual ~LinkedQueue();
 bool IsEmpty() const{return ((front)?false:true);}
 LinkedQueue<T>& Add(const T& x);
 LinkedQueue<T>& Delete(T& x);

 Node<T> *front;
 Node<T> *rear;

};
template <class T>
LinkedQueue<T>::LinkedQueue()
{
  front=rear=0;
}
template <class T>
LinkedQueue<T>::~LinkedQueue()
{
  Node<T> *next;
  while(front)
  {
   next=front->link;
   delete front;
   front=next;
  }
}
template <class T>
LinkedQueue<T>& LinkedQueue<T>::Add(const T& x)
{
 Node<T> *p=new Node<T>;
 p->data=x;
 p->link=0;
 if(front)
  rear->link=p;
 else front=p;
 rear=p;

 return *this;
}
template <class T>
LinkedQueue<T>& LinkedQueue<T>::Delete(T& x)
{
 if(IsEmpty())
 {
  return *this;
 }
 x=front->data;

 Node<T> *p=front;
 front=front->link;
 delete p;

 return *this;
}

第四五六个,node,队列的节点以及两个异常类~~~~均无cpp文件~~~~


class OutOfBounds 
{
public:
 OutOfBounds();
 virtual ~OutOfBounds();

};

class BadInput 
{
public:
 BadInput();
 virtual ~BadInput();

};

template <class T>
class Node 
{

public:
 Node(){}
 virtual ~Node(){}
 T data;
 Node<T> *link;

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值