乖乖,这个两个代码可长啦,
Graphlink.h,是图的邻接表的类模板,
Graphmtx.h,是图的邻接矩阵的类模板,
都是写了很长时间的,
Graphlink.h代码如下:
#ifndef GRAPHLINK_H
#define GRAPHLINK_H
#include"BaseGraph.h"
#include<iostream.h>
#include<stdlib.h>
#include"LinkedQueue.h"
#include"GenTree.h"
#include"Forest.h"
/////////////////////////////////////////////////
//Edge 边结点结构的定义
/////////////////////////////////////////////////
template<class T,class E>
struct Edge
{
int dest;
//目的结点的结点号
E cost;
//边对应的权值
Edge<T,E>* link;
//下一条边结点的指针
Edge(){};
//默认构造函数
Edge(int num,E weight)//带参数的构造函数
:dest(num),cost(weight),link(NULL){};
bool operator!=(Edge<T,E>& R)const
{
//成员重载运算符
if(R.dest==dest)
//判断两个边结点是否相等
return true;
else
return false;
};
};
///////////////////////////Edge边结点结构定义结束
/////////////////////////////////////////////////
//Vertex结构 图的顶点结点的定义
/////////////////////////////////////////////////
template<class T,class E>
struct Vertex
{
T data;
//结点的数据域
Edge<T,E>* adj;//边链表的首指针
};
///////////////////////////Vertex顶点结构定义结束
/////////////////////////////////////////////////
//Graphlink<T,E>类模板的实现
//以邻接链表方式实现的图的类模板的声明和实现
//该类以Graph<T,E>为虚基类
//T是顶点数据域类型,E是边的权值类型
/////////////////////////////////////////////////
template<class T,class E>
class Graphlink:public Graph<T,E>
{
private:
Vertex<T,E>* NodeTable;
//顶点表数组
int getVertexPos(const T vertex)
//给出指定顶点Vertex的结点号
{
for(int i=0;i<numVertices;i++)
//遍历所有的邻接顶点
if(NodeTable[i]==vertex)
return i;
return -1;
//没有找到
};
bool* visited;
//用于标记第i个结点是否被访问的数组
void DFS(int start);
//递归:深度优先遍历本图,start是起始结点
public:
Graphlink(int sz=DefaultVertices);
//默认构造函数
~Graphlink();
//析构函数
T getValue(int i)
//取结点号为i的结点里的数据
{
if(i>=0 && i<maxVertices)
return NodeTable[i].data;
else
return 0;
};
E getWeight(int v1,int v2);
//取得边(v1,v2)上的权值
bool insertVertex(const T vertex);
//在图中插入一个顶点vertex
bool removeVertex(int v);
//在图中删除指定结点号v的结点
bool insertEdge(int v1,int v2,E cost);
//插入一条边以及对应的权值
bool removeEdge(int v1,int v2);
//删除边(v1,v2)
int getFirstNeighbor(int v);
//取得结点v的第一个邻接结点
int getNextNeighbor(int v,int w);
//取得v的邻接结点中w后的那个邻接结点
void DFSGraphic(int start);
//深度优先遍历当前图所有结点
void BFSGraphic();
//广度优先遍历
void Find_Connected_Component();
//求图的所有的连通分量顶点集
TreeNode<T>* DFSTree(int v);
//递归:得到以v为出发点的深度优先生成树TS
void DisplayDFSTree(int v);
//调用上面的递归函数求图的深度优先生成树
TreeNode<T>* DFSForest(int v);
//则求其所有连通分量的的深度优先生成森林
void Find_DFSForest(int v)
//得到非连通图的深度优先生成森林
{
Forest<char> F;
F.setRoot(DFSForest(0));
cout<<"深度优先生成森林是:"<<endl;
F.Display();
};
int getFirstUnvisit(int p,bool* visited);
//得到当前未访问的第一个邻接结点
int getNextUnvisit(int p,int v,bool* visited);//得到下个未访问的邻接结点
void DepthFirst(int start);
//非递归深度优先遍历当前图
//友元重载输出运算符
friend ostream& operator<<(ostream& os,Graphlink<T,E>& G);
//友元重载输入运算符
friend istream& operator>>(istream& is,Graphlink<T,E>& G);
};
/////////////////////Graphlink<T,E>类模板声明结束
/////////////////////////////////////////////////
//默认构造函数
/////////////////////////////////////////////////
template<class T,class E>
Graphlink<T,E>::Graphlink(int sz)
{
maxVertices=sz;
//图中最大的顶点数
numEdges=0;
//初始边数
numVertices=0;
//初始顶点数
//顶点表数组开辟内存区域
NodeTable=new Vertex<T,E>[sz];
if(NodeTable==NULL)
{
cout<<"内存分配失败!"<<endl;
exit(1);
};
//初始化顶点数组里的内容
for(int i=0;i<maxVertices;i++)
//把每个边链表的手指指针初始化为空
NodeTable[i].adj=NULL;
};
/////////////////////////////////默认构造函数结束
/////////////////////////////////////////////////
//析构函数结束
//释放所有的边链表的内存以及结点数组的内存
/////////////////////////////////////////////////
template<class T,class E>
Graphlink<T,E>::~Graphlink()
{
//首先遍历每条边链表的首结点
for(int i=0;i<numVertices;i++)
{
Edge<T,E>*& ptr=NodeTable[i].adj;//游标指针
Edge<T,E>* pre;
//前个边结点的指针
while(ptr!=NULL)
{
pre=ptr;
//保留当前边结点
ptr=ptr->link;
//指向下个边结点
delete
pre;
//释放结点内存
};
};
};
/////////////////////////////////////析构函数结束
/////////////////////////////////////////////////
//getWeight()公有成员函数
//得到指定边(v1,v2)上的权值
/////////////////////////////////////////////////
template<class T,class E>
E Graphlink<T,E>::getWeight(int v1,int v2)
{
Edge<T,E>* ptr=NodeTable[v1].adj;//得到v1结点的边链表的首指针
while(ptr!=NULL)
//遍历该边链表找结点v2
{
if(ptr->dest==v2)
//如果找到就返回
return ptr->cost;
ptr=ptr->link;
}
return maxWeight;
//即这两点之间不存在边
};
//////////////////////getWeight()公有成员函数结束
/////////////////////////////////////////////////
//insertVertex()公有成员函数
//在图中插入一个顶点
/////////////////////////////////////////////////
template<class T,class E>
bool Graphlink<T,E>::insertVertex(const T vertex)
{
if(numVertices<maxVertices)
//结点表不满则插入新结点
{
NodeTable[numVertices++].data=vertex;
return true;
//插入成功
}
else
return false;
//表满插入失败
};
///////////////////////////insertVertex()函数结束
/////////////////////////////////////////////////
//removeVertex()公有成员函数
//在图中删除指定结点号的结点v,也删除和v关联的边
/////////////////////////////////////////////////
template<class T,class E>
bool Graphlink<T,E>::removeVertex(int v)
{
if(v<0 || v>=numVertices)
//如果给出的结点号不存在
return false;
/*首先删除和结点v相关联的边链表*/
Edge<T,E>* ptr=NodeTable[v].adj;//游标指针
Edge<T,E>* pre;
//指向释放的前一个结点
while(ptr!=NULL)
//释放边链表中所有结点
{
pre=ptr;
ptr=ptr->link;
delete pre;
numEdges--;
//每删去一个边结点,numEdges减1
};
NodeTable[v].adj=NULL;
//该与结点的边链表置空
/*在其他的边链表中也对称删除dest为v的边结点*/
for(int i=0;i<numVertices;i++)
//遍历每一个边链表
{
ptr=NodeTable[i].adj;
//取得每个边链表的首指针
if(ptr==NULL)
//如果边链表是空的
continue;
else if(ptr!=NULL
//如果是在头部删除
&& ptr->dest==v)
{
NodeTable[i].adj=ptr->link;
delete ptr;
}
else
{
while(ptr->link!=NULL)
{
if(ptr->link->dest==v)
{
//如果找到该结点
pre=ptr->link;
ptr->link=ptr->link->link;
delete pre;
break;
};
ptr=ptr->link;
//指针向后推进一格
};
};
};
/*把NodeTable中的最后一个元素填补到v对应的位置*/
NodeTable[v].data=NodeTable[numVertices-1].data;
NodeTable[v].adj=NodeTable[numVertices-1].adj;
NodeTable[numVertices-1].adj=NULL;
/*把所有的原来结点号是numVertices-1的结点
的结点号改为v*/
int p=numVertices-1;
//原来最后一个结点的结点号
for(i=0;i<numVertices-1;i++)
//遍历所有的边链表
{
ptr=NodeTable[i].adj;
//游标指针
while(ptr!=NULL)
//遍历每个边结点
{
if(ptr->dest==p)
//原来目的结点是p的
ptr->dest=v;
//现在改为v
ptr=ptr->link;
};
};
numVertices--;
//结点的个数减1
return true;
//删除成功
};
///////////////////////////removeVertex()函数结束
/////////////////////////////////////////////////
//insertEdge()公有成员函数
//在结点v1和v2之间建立一条边,同时对称建立边链表结点
/////////////////////////////////////////////////
template<class T,class E>
bool Graphlink<T,E>::insertEdge(int v1,int v2,E cost)
{
if(v1<0 || v2<0 || v1>=numVertices || v2>=numVertices)
return false;
/*在v1的边链表中插入v2*/
Edge<T,E>* ptr=NodeTable[v1].adj;
//游标指针
Edge<T,E>* newEdge1=new Edge<T,E>(v2,cost);//新建边链表
if(NodeTable[v1].adj==NULL)
//如果边链表本来是空的
{
NodeTable[v1].adj=newEdge1;
}
else if(v2<NodeTable[v1].adj->dest)
//在头部插入
{
newEdge1->link=NodeTable[v1].adj;
NodeTable[v1].adj=newEdge1;
}
else
{
while(ptr->link!=NULL)
//寻找位置插入
{
if(ptr->dest<v2 && ptr->link->dest>v2)
{
newEdge1->link=ptr->link;
ptr->link=newEdge1;
break;
}
ptr=ptr->link;
};
if(ptr->link==NULL)
//如果在尾部插入
ptr->link=newEdge1;
};
/*在v2的边链表中插入v1*/
ptr=NodeTable[v2].adj;
Edge<T,E>* newEdge2=new Edge<T,E>(v1,cost);//新建边链表
if(NodeTable[v2].adj==NULL)
//如果边链表本来是空的
{
NodeTable[v2].adj=newEdge2;
}
else if(v1<NodeTable[v2].adj->dest)
//在头部插入
{
newEdge2->link=NodeTable[v2].adj;
NodeTable[v2].adj=newEdge2;
}
else
{
while(ptr->link!=NULL)
//寻找位置插入
{
if(ptr->dest<v1 && ptr->link->dest>v1)
{
newEdge2->link=ptr->link;
ptr->link=newEdge2;
break;
}
ptr=ptr->link;
};
if(ptr->link==NULL)
//如果在尾部插入
ptr->link=newEdge2;
};
numEdges++;
//边数加1
return true;
};
/////////////////////insertEdge()公有成员函数结束
/////////////////////////////////////////////////
//removeEdge()公有成员函数
//删除图中指定的一条变
/////////////////////////////////////////////////
template<class T,class E>
bool Graphlink<T,E>::removeEdge(int v1,int v2)
{
if(v1<0 || v1>=maxWeight
//如果v1和v2是合法的
|| v2<0 || v2>=maxWeight)
return false;
//删除失败
Edge<T,E>* ptr;
//游标指针
Edge<T,E>* pre;
//前一个结点
/*在v1的边链表中删除边结点v2*/
ptr=NodeTable[v1].adj;
//v1边链表的首指针
if(NodeTable[v1].adj==NULL)
//比边链表是空的
return false;
//删除失败
else if(NodeTable[v1].adj->dest==v2)
//如果是在头部删
{
//删除结点
pre=NodeTable[v1].adj;
NodeTable[v1].adj=NodeTable[v1].adj->link;
delete pre;
}
else
//如果是在头结点以外结点删除
{
int flag=0;
//是否有结点删除
while(ptr->link!=NULL)
//寻找要删除的v2边结点
{
if(ptr->link->dest==v2)
//删除v2边结点
{
flag=1;
pre=ptr->link;
ptr->link=ptr->link->link;
delete pre;
break;
};
ptr=ptr->link;
//指针向后推进一格
};
if(flag==0)
//如果没有找到边结点v2
{
cout<<"该边不存在!"<<endl;
return false;
//该边不存在删除失败
};
};
/*在v2的边链表中删除边结点v1*/
ptr=NodeTable[v2].adj;
//v1边链表的首指针
if(NodeTable[v2].adj==NULL)
//比边链表是空的
return false;
//删除失败
else if(NodeTable[v2].adj->dest==v1)
//如果是在头部删
{
//删除结点
pre=NodeTable[v2].adj;
NodeTable[v2].adj=NodeTable[v2].adj->link;
delete pre;
}
else
//如果是在头结点以外结点删除
{
int flag=0;
while(ptr->link!=NULL)
//寻找要删除的v2边结点
{
if(ptr->link->dest==v1)
//删除v2边结点
{
flag=1;
pre=ptr->link;
ptr->link=ptr->link->link;
delete pre;
break;
};
ptr=ptr->link;
//指针向后推进一格
};
if(flag==0)
//该边不存在
return false;
//删除失败
};
numEdges--;
//边的个数减1
return true;
};
/////////////////////////////removeEdge()函数结束
/////////////////////////////////////////////////
//getFirstNeighbor()公有成员函数
//得到指定结点v的第一个相邻的结点
/////////////////////////////////////////////////
template<class T,class E>
int Graphlink<T,E>::getFirstNeighbor(int v)
{
if(v>=0 && v<numVertices)
//如果指定的结点存在
{
Edge<T,E>* p=NodeTable[v].adj;//边链表的首结点指针
if(p!=NULL)
return p->dest;
else
return -1;
}
else
return -1;
};
///////////////////////getFirstNeighbor()函数结束
/////////////////////////////////////////////////
//getNextNeighbor()公有成员函数
//得到当前结点v的邻接顶点w下个邻接顶点的顶点号
/////////////////////////////////////////////////
template<class T,class E>
int Graphlink<T,E>::getNextNeighbor(int v,int w)
{
if(v>=0 && v< maxWeight
//如果结点号合法
&& w>=0 && w< maxWeight)
{
Edge<T,E>* ptr=NodeTable[v].adj;//获得和结点v对应的边链表的首指针
while(ptr!=NULL)
//遍历该边链表对应的多有的边结点
{
if(ptr->dest==w)
//如果找到目的结点为w的边结点
break;
//结束查找
ptr=ptr->link;
};
if(ptr!=NULL && ptr->link!=NULL)//如果ptr和ptr的下个结点都不空
return ptr->link->dest;
else
return -1;
//这样的结点不存在,查找失败
}
else
return -1;
};
////////////////////////getNextNeighbor()函数结束
/////////////////////////////////////////////////
//DFS()私有成员函数
//递归:深度优先遍历图所有结点,start是起始结点
/////////////////////////////////////////////////
template<class T,class E>
void Graphlink<T,E>::DFS(int start)
{
cout<<getValue(start)<<" ";
//访问当前的起始结点
visited[start]=true;
//把对应的访问标志置为"已访问"
int p=getFirstNeighbor(start);
//获取start的第一个邻接结点
while(p!=-1)
//递归访问start的所有邻接结点
{
if(visited[p]==false)
//如果neighbor没有被访问过
DFS(p);
//以neighbor为当前结点继续递归访问
p=getNextNeighbor(start,p);
//获取下个邻接结点的结点号
};
};
////////////////////////////DFS()私有成员函数结束
/////////////////////////////////////////////////
//DFSGraphic()公有成员函数
//深度优先遍历图所有结点,通过键盘输入起始结点
/////////////////////////////////////////////////
template<class T,class E>
void Graphlink<T,E>::DFSGraphic(int start)
{
visited=new bool[numVertices];
for(int i=0;i<numVertices;i++)
visited[i]=false;//把每个结点的访问标志置为否
cout<<endl<<"深度优先遍历的结果是:"<<endl;
if(start>=0 && start<numVertices)
DFS(start);
//如果输入的结点号合法就开始遍历
else
exit(1);
delete [] visited;
//释放标记数组的内存空间
};
/////////////////////DFSGraphic()公有成员函数结束
/////////////////////////////////////////////////
//BFSGraphic()公有成员函数
/////////////////////////////////////////////////
template<class T,class E>
void Graphlink<T,E>::BFSGraphic()
{
cout<<"请输入遍历的起始顶点号:";
int start;
//起始的结点号
cin>>start;
visited=new bool[numVertices];
//开辟标记数组的内存空间
for(int i=0;i<numVertices;i++)
visited[i]=false;
//把标记数组置为未访问
LinkedQueue<int> Q;
//用于存放结点号的队列
Q.EnQueue(start);
//首先把起始顶点的标号压入队列
if(start<0 || start>=numVertices)
//如果起始的结点号不合法
exit(1);
int p;
//当前正在访问的顶点的顶点号
int q;
//所有邻接结点的游标指针
while(!Q.IsEmpty())
//按层次遍历图的所有顶点
{
Q.DeQueue(p);
//从队列中取出一个结点
if(visited[p]==false)
//如果不曾被访问
{
cout<<getValue(p)<<" ";
//访问该结点
visited[p]=true;
//已经被访问过
q=getFirstNeighbor(p);
//获取当前访问结点的第一个邻接结点
while(q!=-1)
//把所有的未被访问过的邻接结点全部送入队列
{
if(visited[q]==false)
Q.EnQueue(q);
//如果没有被访问过就压入队列
q=getNextNeighbor(p,q);//获取下个邻接结点号
};
};
};
delete [] visited;
//释放标记数组的内存空间
};
/////////////////////////BFSGraphic()公有函数结束
/////////////////////////////////////////////////
//Find_Connected_Component()公有成员函数
//寻找当前图的所有的连通分量(极大连通子图)
/////////////////////////////////////////////////
template<class T,class E>
void Graphlink<T,E>::Find_Connected_Component()
{
visited=new bool[numVertices];
//开辟标记数组的空间
for(int i=0;i<numVertices;i++)
visited[i]=false;
//标记全部初始化为未被访问
cout<<"所有连通分量顶点的集合如下:";
cout<<endl;
for(i=0;i<numVertices;i++)
{
if(visited[i]==false)
//如果没有被访问,则可以顺次找出
{
DFS(i);
//连通分量
cout<<endl;
}
};
delete [] visited;
};
///////Find_Connected_Component()公有成员函数结束
/////////////////////////////////////////////////
//DFSTree()公有成员函数
//递归:得到当前图的深度优先生成树的算法
//其中该树采用FirstChild-NextSibling存储结束
//v是遍历起始的顶点,subTree是以v为当前顶点的生成子树
/////////////////////////////////////////////////
template<class T,class E>
TreeNode<T>* Graphlink<T,E>::DFSTree(int v)
{
T value=getValue(v);
//通过结点v创建一个树的结点
TreeNode<T>* subTree;
subTree=new TreeNode<T>(value);
//作为当前生成子树的根结
visited[v]=true;
//当前结点v已经访问过
int flag=1;
//判断是否是长子结点
TreeNode<T>* ptr=NULL;
//获取长子树的树根
TreeNode<T>* pre=NULL;
//保留前棵兄弟子树的根结点
for(int p=getFirstNeighbor(v);
//递归遍历v的所有未访问的邻接结点
p!=-1;p=getNextNeighbor(v,p))
{
if(visited[p]==false)
//如果邻接点p还未被访问过
{
ptr=DFSTree(p);
//递归生成一棵子树
if(flag==1)
//如果是长子结点
{
subTree->firstChild=ptr;
flag=0;
//标志表示已经不是长子结点
}
else
pre->nextSibling=ptr;
//接到前面的子树的后面
pre=ptr;
};
};
return subTree;
//返回根结点指针
};
////////////////////////////////DFSTree()函数结束
/////////////////////////////////////////////////
//DisplayDFSTree()公有成员函数
//调用上面的DFSTree()递归函数求当前图的深度优先生成树
/////////////////////////////////////////////////
template<class T,class E>
void Graphlink<T,E>::DisplayDFSTree(int v)
{
visited=new bool[numVertices];
for(int i=0;i<numVertices;i++)
visited[i]=false;
cout<<"先根遍历以"<<getValue(v)<<"为起点的深度优先生成树:";
Tree<T> T;
//定义一棵空树
T.setRoot(DFSTree(v)); //设置根结点
T.pre();
//先根遍历该树
cout<<endl<<"深度优先生成树是:";
T.Display();
cout<<endl;
cout<<"广度优先遍历的结果是:";
T.levelOrder();
delete [] visited;
};
/////////////////////////DisplayDFSTree()函数结束
/////////////////////////////////////////////////
//DFSForest()公有成员函数
//如果图是非连通的,则求其深度优先生成森林
//即每个连通分量的深度优先树构成的森林
/////////////////////////////////////////////////
template<class T,class E>
TreeNode<T>* Graphlink<T,E>::DFSForest(int v)
{
visited=new bool[numVertices];
for(int i=0;i<numVertices;i++)
visited[i]=false;
//标志数组清为未访问
TreeNode<T>* root;
//森林的根
TreeNode<T>* ptr;
//游标指针
TreeNode<T>* pre;
//前一棵生成树树的根结点
int flag=1;
//是否是森林里的第一棵树的标志
for(int p=0;p<numVertices;p++)
//试着以每个结点开始寻找每个连通分量
{
//的深度优先生成树
if(visited[p]==false)
{
ptr=DFSTree(p);
//找出以p为根的连通分量的深度优先生成树
if(flag==1)
//是森林里的第一棵树
{
root=ptr;
//把ptr作为森林的根
flag=0;
}
else
pre->nextSibling=ptr;//把树连接入前面已经形成的森林中
pre=ptr;
//保留前棵树的根结点
};
};
delete [] visited;
return root;
};
//////////////////////////////DFSForest()函数结束
/////////////////////////////////////////////////
//getFirstUnvisit()公有成员函数
//得到p的第一个邻接的结点
/////////////////////////////////////////////////
template<class T,class E>
int Graphlink<T,E>::getFirstUnvisit(int p,bool* visited)
{
Edge<T,E>* ptr=NodeTable[p].adj; //获得p的边链表的头指针
while(ptr!=NULL)
//搜索该边链表
{
int des=ptr->dest;
//获得每条边的目的结点号
if(visited[des]==false)
//如果第一个碰到一个未访问的
return des;
//返回结点号
ptr=ptr->link;
};
return -1;
//没有找到就返回-1
};
////////////////////////getFirstUnvisit()函数结束
/////////////////////////////////////////////////
//getNextUnvisit()公有成员函数
//得到p的w之后的未访问的邻接结点号
/////////////////////////////////////////////////
template<class T,class E>
int Graphlink<T,E>::getNextUnvisit(int p,int v,bool* visited)
{
Edge<T,E>* ptr=NodeTable[p].adj;//获得p的边链表的首指针
int flag=0;
//判断是否已经找到v
while(ptr!=NULL)
//搜索边链表中v的指针
{
int des=ptr->dest;
//获得每条边的目的结点号
if(des==v)
//如果找到
{
flag=1;
//已经找到
break;
}
ptr=ptr->link;
};
if(flag==0)
//边链表中连v都没有
return -1;
ptr=ptr->link;
//指向v后的第一个结点
while(ptr!=NULL)
//从边结点v后的第一个结点开始搜索
{
int des=ptr->dest;
//搜索v后的第一个未被访问的邻接结点
if(visited[des]==false)
return des;
ptr=ptr->link;
};
return -1;
};
/////////////////////////getNextUnvisit()函数结束
/////////////////////////////////////////////////
//DepthFirst()公有成员函数
//采用非递归的方式深度遍历当前图
/////////////////////////////////////////////////
template<class T,class E>
void Graphlink<T,E>::DepthFirst(int start)
{
visited=new bool[numVertices];
//是否被访问过的标记
for(int i=0;i<numVertices;i++)
visited[i]=false;
LinkedStack<int> Stack;
//回溯过程中用到的堆栈
int p=start;
//指向当前的结点
int parent=-1;
//指向当前结点的遍历父结点
int first;
//存放获取长子结点号
int next;
//存放下个兄弟结点的地址
do
{
cout<<getValue(p)<<" ";
//访问当前结点p
visited[p]=true;
//设置已经访问过
first=getFirstNeighbor(p);
//获取当前访问结点p的未访问过的第一个邻接结点号
while(first!=-1 && visited[first]==true)
first=getNextNeighbor(p,first);
//继续看下个邻接结点
if(first!=-1)
//如果不是根结点而且长子结点不空
{
if(p==start)
//如果当前访问的结点是根结点
next=-1;
//则没有下个兄弟结点
else
{
next=getNextNeighbor(parent,p);//寻找p之后第一个未被访问的第一个兄弟结点
while(next!=-1 && visited[next]==true)
next=getNextNeighbor(parent,next);
};
if(next!=-1)
//如果p的下个兄弟结点存在,且不在堆栈中
{
Stack.Push(parent);
//先把父结点压入堆栈
Stack.Push(next);
//再把该下个兄弟结点压入堆栈
};
parent=p;
p=first;
//下个结点
}
else
//如果长子结点是空的
{
if(p==start)
//如果就是根结点
break;
//推出遍历循环
else
{
do
{
Stack.Pop(p);
//从堆栈中弹出一个结点作为下个结点
Stack.Pop(parent);
//从堆栈中同时获得
}
while(visited[p]!=false);
//弹出的结点如果是已经访问过的,就继续弹
};
};
}while(first!=-1 || !Stack.IsEmpty());
//如果堆栈和长子结点都空了,说明遍历结束
};
/////////////////////////DepthFirst()公有函数结束
/////////////////////////////////////////////////
//友元重载<<输出运算符
/////////////////////////////////////////////////
template<class T,class E>
ostream& operator<<(ostream& os,Graphlink<T,E>& G)
{
cout<<"当前图的内容是:"<<endl;
Edge<T,E>* ptr;
for(int i=0;i<G.numVertices;i++)
{
cout<<"第"<<i<<"个顶点"<<T(G.NodeTable[i].data)<<"边结点:";
ptr=G.NodeTable[i].adj;
while(ptr!=NULL)
{
cout<<"("<<ptr->dest<<","<<ptr->cost<<")"<<" ";
ptr=ptr->link;
};
cout<<endl;
};
cout<<"当前图的总结点数是:"<<G.numVertices<<endl;
cout<<"当前图的总边的个数:"<<G.numEdges<<endl;
return os;
};
///////////////////////////////////<<友元重载结束
/////////////////////////////////////////////////
//友元重载>>输入运算符
/////////////////////////////////////////////////
template<class T,class E>
istream& operator>>(istream& is,Graphlink<T,E>& G)
{
cout<<"通过键盘输入输入顶点和边";
cout<<"请输入顶点的个数:";
is>>G.numVertices;
cout<<endl;
for(int i=0;i<G.numVertices;i++)
{
cout<<"请输入第"<<i<<"个结点的数据内容:";
is>>G.NodeTable[i].data;
};
cout<<"请输入边的个数:";
is>>G.numEdges;
cout<<endl;
int v1,v2;
E weight;
for(i=0;i<G.numEdges;i++)
{
cout<<"输入起点:";
is>>v1;
cout<<"输入终点:";
is>>v2;
cout<<"输入权值:";
is>>weight;
G.insertEdge(v1,v2,weight);
cout<<endl;
}
return is;
};
/////////////////////////////>>输入运算符重载结束
#endif