本來打算在資料結構的 練習9 繼續寫此篇的,以保持連貫性,後來發現,沒法寫,因為BFS的優先隊列,沒接觸過,只能回頭學了,翻開《演算法導論》,發現優先隊列有堆實現,而堆又不會,牽一髮而動全身啊,沒辦法,只能學了,直接看MIT的《演算法導論》視頻吧,看看最基本的排序演算法,反正早晚要複習到。
7月9號接著寫。上一篇博文《資料結構-練習 9 圖的儲存》介紹了圖的儲存方式之一,鄰接鏈表。在這裡將介紹圖的遍曆,包括深度優先和廣度優先。
上代碼:
/*coder information: e_mail:shenganbeiyang@163.com QQ:501968942@qq.COM*/#include<iostream>#include<queue>using namespace std;struct edgeNode;/*define the struct*///定義資料結構 struct DataNode{ char savedData; //int weight;the weight of node edgeNode* next; DataNode() { savedData='\0'; next=NULL; }}; struct edgeNode{ int sequence;//存放數組的下標,表示資料之間的關係 edgeNode* next;};//節點數目const int NUM=7;DataNode GraphList[NUM];int visited[NUM];queue<int> que_DN;//建立圖void createGraph(DataNode * graphl){ cout<<"請輸入7個資料節點:"<<endl; char inputChar; int nodeOne; int nodeTwo; for(int i=0;i<NUM;++i) { cin>>inputChar; graphl[i].savedData=inputChar; } //建立 邊 cout<<"請輸入要連結的兩個節點:"<<endl; while(1) { cin>>nodeOne; cin>>nodeTwo; if(nodeOne==-1&&nodeTwo==-1) return; //調整節點的位置哦 edgeNode *newEdgeN1=new edgeNode(); newEdgeN1->sequence=nodeTwo; newEdgeN1->next=graphl[nodeOne].next; graphl[nodeOne].next=newEdgeN1; edgeNode* newEdgeN2=new edgeNode(); newEdgeN2->sequence=nodeOne; newEdgeN2->next=graphl[nodeTwo].next; graphl[nodeTwo].next=newEdgeN2; } }//釋放記憶體void deleteMem(DataNode * graphl){ edgeNode *p=NULL; edgeNode *TEMP=NULL; for(int i=0;i<NUM;++i) { p=GraphList[i].next; while(p) { TEMP=p; p=p->next; delete TEMP; }}}//DFS深度優先遍曆void DFStraverse(DataNode * graphl,int v){ visited[v]=1; cout<<"深度遍曆節點:"<<graphl[v].savedData<<endl; edgeNode* p=graphl[v].next; while(p) { if(!visited[p->sequence]) { DFStraverse(graphl,p->sequence);//remember:遞迴結束之前不會運行後面的語句。 } p=p->next; }}void DFS(DataNode * graphl){ int i; for(i=0;i<NUM;++i) { visited[NUM]=0; } for(i=0;i<NUM;++i) { if(!visited[i]) { DFStraverse(graphl,i); } }}//BFS廣度優先搜尋void BFStraverse(DataNode * graphl ){ //visited[v]=1; cout<<"廣度優先遍曆點:"; edgeNode* EN; //不能遞迴實現,可用隊列來實現 int j; for(int i=0;i<NUM;++i) { visited[NUM]=0; } for(int i=0;i<NUM;++i) { if(!visited[i]) { que_DN.push(i); visited[i]=1; cout<<graphl[i].savedData<<","; while(!que_DN.empty()) { int v=que_DN.front(); que_DN.pop(); EN=graphl[v].next; while(EN) { j=EN->sequence; if(!visited[j]) { que_DN.push(j); visited[j]=1; cout<<graphl[j].savedData<<","; } EN=EN->next; } } } }}void BFS(DataNode * graphl){ int i; for(i=0;i<NUM;++i) { visited[i]=0; } BFStraverse(graphl );}int main(){ createGraph(GraphList);cout<<"輸出鏈表序列:"<<endl;for(int i=0;i<NUM;++i){ edgeNode *p=GraphList[i].next; cout<<i<<":"<<GraphList[i].savedData<<" "; while(p) { cout<< p->sequence<<","; p=p->next; } cout<<"\n"; }DFS(GraphList);BFS(GraphList);deleteMem(GraphList);return 0;}
BFS 的目的是為了,備份之前節點。
測試: