一.鄰接矩陣
圖的鄰接矩陣:用兩個數組來表示圖。一個一維數組存儲圖中的頂點信息,一個二維數組用來存儲圖中的邊或弧的信息。
1. 主對角線全爲0,因爲不存在頂點到自身的值
2. 無向圖的邊數組是一個對稱矩陣
3. 求頂點的度,如Vi的度,在鄰接矩陣中第i行(第i列)的元素之和
4. 求頂點的鄰接點,如vi的鄰接點,掃描第i行,arc[i][j]爲1就是鄰接點
1. 主對角線全爲0
2. 有向圖的邊數組矩陣不對稱
3. 頂點Vi的入度,是第vi列的和,出度爲vi行的和
1. 權來代替1
2. 無窮來代替0
代碼實現
- #include<stdio.h>
- #include<string.h>
- #define MAXVEX 100
- #define INFINITY 65535
- typedef char VertexType;//頂點類型
- typedef int EdgeType;//邊類型
- typedef struct{
- VertexType vexs[MAXVEX];//頂點數組
- EdgeType arc[MAXVEX][MAXVEX];//邊數組
- int numVertexes,numEdges;//頂點數和邊數
- }MGraph,*pMGraph;
- void createMGraph(pMGraph pMG){
- int i,j,k,w;
- puts("Enter the numVertexes and numEdges:");
- scanf("%d,%d",&(pMG->numVertexes),&(pMG->numEdges));//輸入頂點數和邊數
- puts("Enter the Vertexes:");
- for(i=0;i<pMG->numVertexes;i++){//依次輸入頂點信息
- puts("Enter the vexs one by one:");
- scanf(&(pMG->vexs[i]));
- }
- for(i=0;i<pMG->numVertexes;i++){//初始化邊數組爲INFINITY
- for(j=0;j<pMG->numVertexes;j++){
- pMG->arc[i][j] = INFINITY;
- }
- }
- for(k=0;k<pMG->numEdges;k++){//依次輸入邊(vi,vj)的i、j和權值
- puts("Enter the edges");
- scanf("%d,%d,%d",&i,&j,&w);
- pMG->arc[i][j] = w;
- pMG->arc[i][j] = pMG->arc[j][i];//無向圖是對稱的,如果是有向圖就省略這一步
- }
- }
二.鄰接表
數組與鏈表相結合的方式稱爲鄰接表。圖中的頂點用一個一維數組存儲,該數組中的數據元素有一個data域存儲頂點信息,一個firstedge存儲指向第一個鄰接點的指針,所有鄰接點以單鏈表存儲,無向圖稱爲vi的邊表,有向圖稱爲以vi的弧尾(出度)的出邊表
1. 求某頂點的度,查找這個頂點的邊表中的結點個數
2. 求某頂點的所有鄰接點,則對邊表進行遍歷即可
1. 求某頂點的入度,查找這個頂點的出邊表即可
2. 但是我們無法很快求出入度,所以可以建立一個逆鄰接表
1. 對於帶權圖,我們可以在邊表結點中添加一個weight的數據域存儲權值即可
代碼實現
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #define MAXVEX 100
- typedef char VertexType;
- typedef int EdgeType;
- typedef struct EdgeNode{//邊表結點
- int adjvex;//鄰接點域,存儲該頂點對應的下標
- EdgeType weight;//權值
- struct EdgeNode *next;//鏈域,指向下一個鄰接點
- }EdgeNode,*pEdgeNode;
- typedef struct VertexNode{//頂點表結點
- VertexType data;//頂點域,存儲頂點信息
- pEdgeNode firstedge;//指向邊表的頭指針
- }VertextNode,*pVertextNode;
- typedef struct {//頂點表
- VertexNode adjList[MAXVEX];//頂點表數組
- int numVertexes,numEdges;//存儲圖中的頂點數和邊數
- }GraphAdjList,*pGraphAdjList;
- void createALGraph(pGraphAdjList pGAL){
- int i,j,k;
- pEdgeNode e;
- puts("Enter the numVertexes and numEdges:");
- scanf("%d,%d",&(pGAL->numVertexes),&(pGAL->numEdges));
- for(i=0;i<pGAL->numVertexes;i++){//輸入頂點表信息
- scanf(&(pGAL->adjList[i].data));//
- pGAL->adjList[i].firstedge = NULL;
- }
- for(k=0;k<pGAL->numEdges;k++){
- puts("Enter (Vi,Vj):");//輸入邊表信息
- scanf("%d,%d",&i,&j);
- e = (pEdgeNode)malloc(sizeof(EdgeNode));// 採用頭插法
- e->adjvex = j;
- e->next = pGAL->adjList[i].firstedge;
- pGAL->adjList[i].firstedge = e;
- e = (pEdgeNode)malloc(sizeof(EdgeNode));//無向表,所以一條邊對應兩個頂點,要同時添加兩個
- e->adjvex = i;
- e->next = pGAL->adjList[j].firstedge;
- pGAL->adjList[j].
三.十字鏈表(針對有向圖)
將有向圖的鄰接表和逆鄰接表結合起來
頂點表的結點結構變爲
Data |
Firstin |
Firstout |
firstin表示入邊表頭指針,指向該結點的入邊表中第一個結點
firstout表示出邊表頭指針,指向該結點的出邊表第一個結點
邊表結點的結構變爲
Tailvex |
Headvex |
Headlink |
Taillink |
tailvex表示弧起點在頂點表中的下標
headvex表示弧終點在頂點表中的下標
headlink表示入邊表指針域,指向終點相同的下一條邊
taillink表示出邊表指針域,指向起點相同的下一條邊
1. 先完成出邊表
2. 在完成入邊表
3. 代碼仍然使用頭插法
四.鄰接多重表(針對無向圖)
邊表結點結構爲
Ivex |
Ilink |
Jvex |
Jlink |
ivex和jvex是依附於一條邊的兩個頂點在頂點表中的下標。ilink指向依附於ivex的下一條邊。jlink執行依附於jvex的下一條邊
五.邊集數組
兩個一維數組構成,一個存儲頂點信息,另一個存儲邊的信息,這個邊數組每個元素由起點下標、終點下標、權值組成。