您的位置:首页 > 理论基础 > 数据结构算法

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

2009-07-09 15:28 232 查看
图的相关操作~~~~~~

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

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

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

第一个类,加权有向~~~~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
;
closest = new int
;
s = new bool
;

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;

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: