图的十字链表表示的c++实现
来源:互联网 发布:boot repair ubuntu 17 编辑:程序博客网 时间:2024/05/16 07:38
#include <iostream>using namespace std;class VexNode;class ArcNode;typedef int VEXID;#define MAXVEXNUM 1000// 编程错误:函数的顺序写错,入s->v写成v->s// 一定要有无参的构造函数且要初始化所有成员,不然disasterclass VexNode{friend class AdjList;friend class ArcNode;friend class JunkSmsFilter;public:VexNode();VexNode(VEXID);private: VEXID vexname;int inDegree;int outDegree;ArcNode* firstInArc; //邻接表只是存一个arc,而十字链表存两个ArcNode* firstOutArc; //邻接表只是存一个arc,而十字链表存两个//firstInArc为横向链表的头指针,firstInArc为纵向链表的头指针};VexNode::VexNode(){ vexname=0; inDegree=0; outDegree=0; firstInArc=NULL; firstOutArc=NULL; firstInArc=NULL; firstOutArc=NULL;}VexNode::VexNode(VEXID id){ vexname=id; inDegree=0; outDegree=0; firstInArc=NULL; firstOutArc=NULL;}class ArcNode{friend class AdjList;friend class JunkSmsFilter;public:ArcNode();ArcNode(VEXID mdest,VEXID msrc);private:VEXID dest; // 标示弧指向的那个顶点,比邻接表多出一个顶点 VEXID src; // 标示弧指向的那个顶点,比邻接表多出一个顶点int weight; // 有多少个边ArcNode* nextArc_comSrc;//十字链表的横向链接出度边ArcNode* nextArc_comDes;//十字链表的纵向链接出度边};ArcNode::ArcNode(){ nextArc_comSrc=NULL; nextArc_comDes=NULL;}ArcNode::ArcNode(VEXID msrc,VEXID mdest){ dest=mdest; src=msrc; weight=1; nextArc_comSrc=NULL; nextArc_comDes=NULL;}class AdjList{public:AdjList();int getVexIndegree(VEXID);int getVexOutdegree(VEXID);int getSingleDLinkDestNum(VEXID);bool addDLink(VEXID,VEXID);bool existDArc(int sendId,int revId);void appendDWeight(int i,int j,int weight);void DFS(VEXID);void DFSTraverse(VEXID); void BFS(VEXID);void BFSTraverse(VEXID);bool existOutArc(int p); bool existInArc(int p);int locateVexById(VEXID sendId);int getDArcWeight(int,int);protected:int vexnum;bool visited[MAXVEXNUM];VexNode vexList[MAXVEXNUM];};int AdjList::getDArcWeight(int s,int v){ ArcNode* ptemp=vexList[s].firstOutArc;ArcNode* pparent=ptemp;while(ptemp!=NULL){if((ptemp->dest)==v) {return ptemp->weight;}pparent=ptemp;ptemp=ptemp->nextArc_comSrc;}}AdjList::AdjList(){}void AdjList::DFS(VEXID svex)//只能遍历一颗生成树,无法遍历生成森林{int ivex=locateVexById(svex);ArcNode* arcIter=vexList[ivex].firstOutArc;cout<<"starting from-vex- to"<<svex<<"-";//递归出口的另一种形式是把递归放在分支内部 while(arcIter!=NULL){cout<<"-vex"<<arcIter->dest<<"-";// 在递归前输出,这点很重要DFS(arcIter->dest);//递归放在while内部则while执行下一轮前递归,故为深度优先arcIter=arcIter->nextArc_comDes;//递归后才执行广度操作 }}void AdjList::DFSTraverse(VEXID svex)// 遍历生成森林{ for(int i=1;i<MAXVEXNUM;i++) visited[i]=false;for(int i=1;i<MAXVEXNUM;i++) {if(visited[i]==false){DFS(vexList[i].vexname);}}}void AdjList::BFS(VEXID){}void AdjList::BFSTraverse(VEXID){}bool AdjList::existDArc(int isrc,int ides){cout<<"inside existDarc:"<<endl;ArcNode* ptemp=vexList[isrc].firstOutArc; cout<<"get arc pointer ok:"<<endl;while(ptemp!=NULL){cout<<"inside existDarc: while"<<endl;if((ptemp->dest)==ides) {cout<<"inside existDarc: exit Darc"<<endl;return true;}ptemp=ptemp->nextArc_comSrc;} cout<<"inside existDarc:no Darc"<<endl;return false;}bool AdjList::existOutArc(int isrc){if(vexList[isrc].firstOutArc==NULL) return false; return true;}bool AdjList::existInArc(int idest){ if(vexList[idest].firstInArc==NULL) return false; return true;}int AdjList::locateVexById(VEXID sendId){return sendId;}void AdjList::appendDWeight(int i, int j, int paraweight){ ArcNode* ptemp=vexList[i].firstOutArc;ArcNode* pparent=ptemp;while(ptemp!=NULL){if((ptemp->dest)==j) {ptemp->weight+=paraweight;return;}pparent=ptemp;ptemp=ptemp->nextArc_comSrc;}if(ptemp==NULL) throw "append Weight null error!";}int AdjList::getSingleDLinkDestNum(int id){//从id出去的边指向的顶点没有回边 int num=0;ArcNode* ptemp=vexList[id].firstOutArc;ArcNode* pparent=ptemp;while(ptemp!=NULL){pparent=ptemp;if(getDArcWeight(ptemp->dest,id)==0) { cout<<"发现没有回边的点"<<endl;num++;}ptemp=ptemp->nextArc_comDes;} return num;}bool AdjList::addDLink(VEXID sendId,VEXID revId){cout<<"going to add link now inside addDlink"<<endl;int i=locateVexById(sendId);int j=locateVexById(revId); if(!existDArc(sendId,revId)) //如果不存在有向边{cout<<"going to creat new arc"<<endl;ArcNode* pNewArc=new ArcNode(sendId,revId); cout<<"creat new arc ok"<<endl;cout<<endl<<"no directed graph from "<<i<<" to "<<j<<" Now"<<endl;if(!existOutArc(i)) //增加i的出边链表{cout<<"增加i的出边链表"<<endl;vexList[i].firstOutArc=pNewArc;}else // i已经有出边了{ArcNode* ptemp=vexList[i].firstOutArc;ArcNode* pparent=ptemp;while(ptemp!=NULL){pparent=ptemp;ptemp=ptemp->nextArc_comSrc;}pparent->nextArc_comSrc=pNewArc;} if(!existInArc(j)) //增加i的入边链表{vexList[j].firstInArc=pNewArc;}else{ArcNode* ptemp=vexList[i].firstInArc;ArcNode* pparent=ptemp;while(ptemp!=NULL){pparent=ptemp;ptemp=ptemp->nextArc_comDes;}pparent->nextArc_comDes=pNewArc;} }//else{cout<<endl<<"ARC"<<i<<" to "<<j<<" Now IS"<<endl;appendDWeight(i,j,1);}return true;}