前言:圖是樹的擴充,本博文主要講述圖的儲存。
圖的儲存包括:圖的鄰接矩陣,圖的鄰接鏈表,以及十字鏈表。
1,圖的鄰接矩陣,無非開闢一個一維數組和一個二維數組。一維數組用於存放圖的頂點資訊,二維數組用於存放圖的串連資訊,之前做過一個感測網的項目。記得是用一個二維數組存放路由之間的資訊的,因為路由的資訊是無向的,所以當時只用了一半。這個很簡單,直接跳過;
2,圖的鄰接鏈表,數組和鏈表的組合。如下:
圖 1
圖分有向和無向的,分別如:圖2 和 圖 3。
圖 2
圖 3
圖2 與圖1對應。我們知道,要儲存圖2,如果按圖1的方式的儲存,在資料結構上必須具備兩種,靜態數組和鏈表。
數組的下標表示的就是節點的順序,裡面儲存的是對應的資料和一個指向鏈表的指標。
定義的資料結構:
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];
建立圖表:
//建立圖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; }}}
測試:
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"; }return 0;}結果:按圖2 的方式輸入字元。只不過輸入的字元不是V0,V1......
3圖的十字鏈表:有向圖的出度和入度,都只能定位出或是入的節點,要想同時定位出入的節點,很簡單,把二者結合起來就可以。不再做介紹。