邻接表是图的一种最主要存储结构,用来描述图上的每一个点。对图的每个顶点建立一个容器(n个顶点建立n个容器),第i个容器中的结点包含顶点Vi的所有邻接顶点。实际上邻接矩阵就是一种未离散化每个点的边集的邻接表。
AdjacencyListPtr graphToAdjacentList(GraphPtr pPtr){
int i,j,tempNum;
AdjacentNodePtr p,q;
tempNum = pPtr->numNodes;
AdjacencyListPtr resultPtr = (AdjacencyListPtr)malloc(sizeof(AdjacencyList));
resultPtr->numNodes = tempNum;
resultPtr->headers = (AdjacencyNode*)malloc(tempNum * sizeof(AdjacencyNode));
for(i = 0;i < tempNum;i++){
p = &(resultPtr->headers[i]);
p->column = -1;
p->next = NULL;
for(j = 0;j < tempNum;j++){
if(pPtr->connections[i][j] > 0){
q = (AdjacentNodePtr)malloc(sizeof(AdjacencyNode));
q->column = j;
q->next = NULL;
p->next = q;
p = q;
}
}
}
return resultPtr;
}
邻接表的广度优先遍历
void widthFirstTranverse(AdjacencyListPtr pListPtr,int pStart){
printf("width first rn");
int i,j,tempNode;
AdjacentNodePtr p;
i = 0;
visitedPtr = (int*)malloc(pListPtr->numNodes * sizeof(int));
for(i = 0;i < pListPtr->numNodes;i++){
visitedPtr[i] = 0;
}
QueuePtr tempQueuePtr = iniQueue();
printf("%d ",pStart);
visitedPtr[pStart] = 1;
enqueue(tempQueuePtr,pStart);
while(!isQueueEmpty(tempQueuePtr)){
tempNode = dequeue(tempQueuePtr);
for(p = &(pListPtr->headers[tempNode]);p != NULL;p = p->next){
j = p->column;
if(visitedPtr[j]){
continue;
}
printf("%d ",j);
visitedPtr[j] = 1;
enqueue(tempQueuePtr,j);
}
}
}
完整代码
#include运行结果#include #define QUEUE_SIZE 10 int* visitedPtr; typedef struct Graph{ int** connections; int numNodes; } *GraphPtr; GraphPtr iniGraph(int paraSize, int** paraData) { int i, j; GraphPtr resultPtr = (GraphPtr)malloc(sizeof(struct Graph)); resultPtr -> numNodes = paraSize; resultPtr -> connections = (int**)malloc(paraSize * sizeof(int*)); for (i = 0; i < paraSize; i ++) { resultPtr -> connections[i] = (int*)malloc(paraSize * sizeof(int)); for (j = 0; j < paraSize; j ++) { resultPtr -> connections[i][j] = paraData[i][j]; } } return resultPtr; } typedef struct GraphNodeQueue{ int* nodes; int front; int rear; }GraphNodeQueue, *QueuePtr; QueuePtr iniQueue(){ QueuePtr resultQueuePtr = (QueuePtr)malloc(sizeof(struct GraphNodeQueue)); resultQueuePtr->nodes = (int*)malloc(QUEUE_SIZE * sizeof(int)); resultQueuePtr->front = 0; resultQueuePtr->rear = 1; return resultQueuePtr; } bool isQueueEmpty(QueuePtr paraQueuePtr){ if ((paraQueuePtr->front + 1) % QUEUE_SIZE == paraQueuePtr->rear) { return true; } return false; } void enqueue(QueuePtr paraQueuePtr, int paraNode){ if ((paraQueuePtr->rear + 1) % QUEUE_SIZE == paraQueuePtr->front % QUEUE_SIZE) { printf("Error, trying to enqueue %d. queue full.rn", paraNode); return; } paraQueuePtr->nodes[paraQueuePtr->rear] = paraNode; paraQueuePtr->rear = (paraQueuePtr->rear + 1) % QUEUE_SIZE; } int dequeue(QueuePtr paraQueuePtr){ if (isQueueEmpty(paraQueuePtr)) { printf("Error, empty queuern"); return NULL; } paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE; return paraQueuePtr->nodes[paraQueuePtr->front]; } typedef struct AdjacencyNode{ int column; AdjacencyNode* next; }AdjacencyNode,*AdjacentNodePtr; typedef struct AdjacencyList{ int numNodes; AdjacencyNode* headers; }AdjacencyList,*AdjacencyListPtr; AdjacencyListPtr graphToAdjacentList(GraphPtr pPtr){ int i,j,tempNum; AdjacentNodePtr p,q; tempNum = pPtr->numNodes; AdjacencyListPtr resultPtr = (AdjacencyListPtr)malloc(sizeof(AdjacencyList)); resultPtr->numNodes = tempNum; resultPtr->headers = (AdjacencyNode*)malloc(tempNum * sizeof(AdjacencyNode)); for(i = 0;i < tempNum;i++){ p = &(resultPtr->headers[i]); p->column = -1; p->next = NULL; for(j = 0;j < tempNum;j++){ if(pPtr->connections[i][j] > 0){ q = (AdjacentNodePtr)malloc(sizeof(AdjacencyNode)); q->column = j; q->next = NULL; p->next = q; p = q; } } } return resultPtr; } void printAdjacentList(AdjacencyListPtr pPtr){ int i; AdjacentNodePtr p; int tempNum = pPtr->numNodes; printf("This is the graph:rn"); for(i = 0;i < tempNum;i++){ p = pPtr->headers[i].next; while(p != NULL){ printf("%d, ",p->column); p = p->next; } printf("n"); } } void widthFirstTranverse(AdjacencyListPtr pListPtr,int pStart){ printf("width first rn"); int i,j,tempNode; AdjacentNodePtr p; i = 0; visitedPtr = (int*)malloc(pListPtr->numNodes * sizeof(int)); for(i = 0;i < pListPtr->numNodes;i++){ visitedPtr[i] = 0; } QueuePtr tempQueuePtr = iniQueue(); printf("%d ",pStart); visitedPtr[pStart] = 1; enqueue(tempQueuePtr,pStart); while(!isQueueEmpty(tempQueuePtr)){ tempNode = dequeue(tempQueuePtr); for(p = &(pListPtr->headers[tempNode]);p != NULL;p = p->next){ j = p->column; if(visitedPtr[j]){ continue; } printf("%d ",j); visitedPtr[j] = 1; enqueue(tempQueuePtr,j); } } } void testGraphTranverse() { int i, j; int myGraph[5][5] = { {0, 1, 0, 1, 0}, {1, 0, 1, 0, 1}, {0, 1, 0, 1, 1}, {1, 0, 1, 0, 0}, {0, 1, 1, 0, 0}}; int** tempPtr; printf("Preparing datarn"); tempPtr = (int**)malloc(5 * sizeof(int*)); for (i = 0; i < 5; i ++) { tempPtr[i] = (int*)malloc(5 * sizeof(int)); } for (i = 0; i < 5; i ++) { for (j = 0; j < 5; j ++) { tempPtr[i][j] = myGraph[i][j]; } } printf("Data readyrn"); GraphPtr tempGraphPtr = iniGraph(5, tempPtr); AdjacencyListPtr tempListPtr = graphToAdjacentList(tempGraphPtr); printAdjacentList(tempListPtr); widthFirstTranverse(tempListPtr, 4); } int main(){ testGraphTranverse(); return 0; }
Preparing data Data ready This is the graph: 1, 3, 0, 2, 4, 1, 3, 4, 0, 2, 1, 2, width first 4 1 2 0 3



