1. 程式人生 > >整形圖的深度遍歷和廣度遍歷

整形圖的深度遍歷和廣度遍歷

比較簡單的實現,圖採用鄰接矩陣的儲存方式,且沒有加上覆制建構函式和過載運算子。

#include <iostream>
#include<stdexcept>
#include<stdio.h>
using namespace std;
struct Node
{
    int data;
    Node *next;
    Node(){next=NULL;}
    Node(int item,Node *link=NULL)
    {
        data=item;
        next=link;
    }
};
class
LinkQueue { protected: Node *front,*rear; int count; public: LinkQueue(){rear=front=new Node();count=0;} virtual ~LinkQueue(); int length()const{return count;} bool Empty()const{return count==0;} void Clear(); void Traverse()const; bool OutQueue(int &e); bool
GetHead(int &e)const; bool InQueue(const int &e); LinkQueue(const LinkQueue &copy); LinkQueue&operator=(const LinkQueue &copy); }; LinkQueue::~LinkQueue() { Clear(); } void LinkQueue::Clear() { int tmp; while(!Empty()) OutQueue(tmp); } void LinkQueue::Traverse()const
{ for(Node *tmp=front->next;tmp!=NULL;tmp=tmp->next) cout<<tmp->data<<' '; } bool LinkQueue::OutQueue(int &e) { if(!Empty()) { Node *tmp=front->next; e=tmp->data; front->next=tmp->next; if(rear==tmp) rear=front; delete tmp; count--; return true; } else return false; } bool LinkQueue::GetHead(int &e)const { if(!Empty()) { Node *tmp=front->next; e=tmp->data; return true; } else return false; } bool LinkQueue::InQueue(const int &e) { Node *tmp=new Node(e); rear->next=tmp; rear=tmp; count++; return true; } LinkQueue::LinkQueue(const LinkQueue&copy) { rear=front=new Node(); count=0; for(Node *tmp=copy.front->next;tmp!=NULL;tmp=tmp->next) InQueue(tmp->data); } LinkQueue&LinkQueue::operator=(const LinkQueue&copy) { if(&copy!=this) { Clear(); for(Node *tmp=copy.front->next;tmp!=NULL;tmp=tmp->next) InQueue(tmp->data); } return *this; } class AdjMatrixDirGraph { protected: int vexNum,edgeNum; //頂點數和邊數 int **Matrix; //領接矩陣 int *elems; //頂點元素 mutable bool *tag; //指向標誌陣列的指標 void DestroyHelp(); //銷燬有向圖 void DFS(int v)const; //從頂點v開始深度優先遍歷 void BFS(int v)const; //從頂點v開始廣度優先遍歷 public: AdjMatrixDirGraph(int es[],int vertexNum=10); //構造資料元素為es,頂點個數為vertexNum,邊數為0的有向圖 AdjMatrixDirGraph(int vertexNum=10); //構造頂點個數為vertexNum變數為0的有向圖 ~AdjMatrixDirGraph(); //解構函式 void DFSTraverse()const; //對圖進行深度優先遍歷 void BFSTraverse()const; //對圖進行廣度優先遍歷 bool GetElem(int v,int &e)const; //求頂點的元素 bool SetElem(int v,const int &e); //設定頂點的元素 int GetVexNum()const{return vexNum;} //返回頂點個數 int GetEdgeNum()const{return edgeNum;} //返回邊的條數 int FirstAdjVex(int v)const; //返回頂點v的第一個鄰接頂點 int NextAdjVex(int v1,int v2)const; //返回頂點v1的相對於v2的下一個鄰接點 void InsertEdge(int v1,int v2); //插入頂點為v1和v2的邊 void DeleteEdge(int v1,int v2); //刪除頂點為v1和v2的邊 bool GetTag(int v)const; //返回頂點v的標誌 void SetTag(int v,bool val)const; //設定v1的標誌為val void Display()const; //顯示關係矩陣 }; void AdjMatrixDirGraph::DestroyHelp() { delete[] elems; delete[] tag; for(int i=0;i<vexNum;i++) delete []Matrix[i]; delete []Matrix; } void AdjMatrixDirGraph::DFS(int v)const { SetTag(v,true); int e; GetElem(v,e); cout<<e<<' '; for(int w=FirstAdjVex(v);w>=0;w=NextAdjVex(v,w)) if(!GetTag(w)) DFS(w); } void AdjMatrixDirGraph::DFSTraverse()const { int v; for(v=0;v<GetVexNum();v++) SetTag(v,false); cout<<"深度遍歷:"; for(v=0;v<GetVexNum();v++) if(!GetTag(v)) DFS(v); } void AdjMatrixDirGraph::BFS(int v)const { SetTag(v,true); int e; GetElem(v,e); cout<<e<<' '; LinkQueue q; q.InQueue(v); while(!q.Empty()) { int u,w; q.OutQueue(u); for(w=FirstAdjVex(u);w>=0;w=NextAdjVex(u,w)) { if(!GetTag(w)) { SetTag(w,true); GetElem(w,e); cout<<e<<' '; q.InQueue(w); } } } } void AdjMatrixDirGraph::BFSTraverse()const { int v; for(v=0;v<vexNum;v++) SetTag(v,false); cout<<"廣度遍歷:"; for(v=0;v<vexNum;v++) if(!GetTag(v)) BFS(v); } AdjMatrixDirGraph::AdjMatrixDirGraph(int es[],int vetexNum) { if(vetexNum<=0) throw runtime_error("頂點數不能小於等於0"); vexNum=vetexNum,edgeNum=0; Matrix=new int*[vexNum]; elems=new int[vexNum]; tag=new bool[vexNum]; for(int i=0;i<vexNum;i++) Matrix[i]=new int[vexNum]; for (int u = 0; u < vexNum; u++) for (int v = 0; v < vexNum; v++) Matrix[u][v] = 0; for(int i=0;i<vexNum;i++) elems[i]=es[i]; for(int i=0;i<vexNum;i++) tag[i]=false; } AdjMatrixDirGraph::AdjMatrixDirGraph(int vetexNum) { if(vetexNum<0) throw runtime_error("頂點數不能小於等於0"); vexNum=vetexNum,edgeNum=0; Matrix=new int*[vexNum]; elems=new int[vexNum]; tag=new bool[vexNum]; for(int i=0;i<vexNum;i++) Matrix[i]=new int[vexNum]; for (int u = 0; u < vexNum; u++) for (int v = 0; v < vexNum; v++) Matrix[u][v] = 0; for(int i=0;i<vexNum;i++) tag[i]=false; } AdjMatrixDirGraph::~AdjMatrixDirGraph() { DestroyHelp(); } bool AdjMatrixDirGraph::GetElem(int v,int &e)const { if(v<0||v>=vexNum) return false; else { e=elems[v]; return true; } } bool AdjMatrixDirGraph::SetElem(int v,const int &e) { if(v<0||v>=vexNum) return false; else { elems[v]=e; return true; } } int AdjMatrixDirGraph::FirstAdjVex(int v)const { int i=0; while(Matrix[v][i]==0&&i<vexNum) i++; if(Matrix[v][i]==1) return i; return -1; } int AdjMatrixDirGraph::NextAdjVex(int v1,int v2)const { while(Matrix[v1][++v2]==0&&v2<vexNum) if(Matrix[v1][v2]==1) return v2; return -1; } void AdjMatrixDirGraph::InsertEdge(int v1,int v2) { if(v1<0||v1>=vexNum) throw runtime_error("v1不合法"); if(v2<0||v2>=vexNum) throw runtime_error("v2不合法!"); if(v1==v2) throw runtime_error("v1不能等於v2!"); if(Matrix[v1][v2]==0&&Matrix[v2][v1]==0) edgeNum++; Matrix[v1][v2]=1; Matrix[v2][v1]=1; } void AdjMatrixDirGraph::DeleteEdge(int v1,int v2) { if(v1<0||v1>=vexNum) throw runtime_error("v1不合法!"); if(v2<0||v2>=vexNum) throw runtime_error("v2不合法!"); if(v1==v2) throw runtime_error("v1不能等於v2!"); if(Matrix[v1][v2]==1&&Matrix[v2][v1]==1) edgeNum--; Matrix[v1][v2]=0; Matrix[v2][v1]=0; } bool AdjMatrixDirGraph::GetTag(int v)const { if(v<0||v>=vexNum) throw runtime_error("v不合法"); else return tag[v]; } void AdjMatrixDirGraph::SetTag(int v,bool val)const { if(v<0||v>=vexNum) throw runtime_error("v不合法"); else tag[v]=val; } void AdjMatrixDirGraph::Display()const { for(int i=0;i<vexNum;i++) { for(int j=0;j<vexNum;j++) cout<<Matrix[i][j]<<' '; cout<<endl; } } int main() { int vetexNum,edgeNum,v1,v2; cout<<"請輸入頂點個數:"; cin>>vetexNum; int es[vetexNum]; for(int i=0;i<vetexNum;i++) { cout<<"請輸入頂點編號為"<<i<<"的頂點的值:"; cin>>es[i]; } AdjMatrixDirGraph g(es,vetexNum); cout<<"請輸入邊的條數:"; cin>>edgeNum; for(int i=0;i<edgeNum;i++) { cout<<"請輸入所要插入的第"<<i+1<<"條邊的兩個端點(以空格隔開):"; scanf("%d %d",&v1,&v2); g.InsertEdge(v1,v2); } g.Display(); g.DFSTraverse(); g.BFSTraverse(); return 0; }