邻接表,存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。
对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。
图的邻接表存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。如词条概念图所示,表结点存放的是邻接顶点在数组中的索引。对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。
#include#include #define QUEUE_SIZE 10 int* visitedPtr; typedef struct Graph{ int** connections; int numNodes; } *GraphPtr; GraphPtr initGraph(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 initQueue(){ 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 paraPtr) { int i, j, tempNum; AdjacentNodePtr p, q; tempNum = paraPtr->numNodes; AdjacencyListPtr resultPtr = (AdjacencyListPtr)malloc(sizeof(struct AdjacencyList)); resultPtr->numNodes = tempNum; resultPtr->headers = (AdjacencyNode*)malloc(tempNum * sizeof(struct AdjacencyNode)); for (i = 0; i < tempNum; i ++) { p = &(resultPtr->headers[i]); p->column = -1; p->next = NULL; for (j = 0; j < tempNum; j ++) { if (paraPtr->connections[i][j] > 0) { q = (AdjacentNodePtr)malloc(sizeof(struct AdjacencyNode)); q->column = j; q->next = NULL; p->next = q; p = q; } } } return resultPtr; } void printAdjacentList(AdjacencyListPtr paraPtr) { int i; AdjacentNodePtr p; int tempNum = paraPtr->numNodes; printf("这就是宁要的邻接表:rn"); for (i = 0; i < tempNum; i ++) { p = paraPtr->headers[i].next; while (p != NULL) { printf("%d, ", p->column); p = p->next; } printf("rn"); } } void widthFirstTranverse(AdjacencyListPtr paraListPtr, int paraStart){ printf("width first rn"); int i, j, tempNode; AdjacentNodePtr p; i = 0; visitedPtr = (int*) malloc(paraListPtr->numNodes * sizeof(int)); for (i = 0; i < paraListPtr->numNodes; i ++) { visitedPtr[i] = 0; } QueuePtr tempQueuePtr = initQueue(); printf("%dt", paraStart); visitedPtr[paraStart] = 1; enqueue(tempQueuePtr, paraStart); while (!isQueueEmpty(tempQueuePtr)) { tempNode = dequeue(tempQueuePtr); for (p = &(paraListPtr->headers[tempNode]); p != NULL; p = p->next) { j = p->column; if (visitedPtr[j]) //如果if通过,那么进行下一个循环嗷 continue; printf("%dt", j); visitedPtr[j] = 1; //用过啦 enqueue(tempQueuePtr, j); //进去啊 } } printf("rn"); } 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("准备数据嗷 0就是没关系,1就是有关系rn"); tempPtr = (int**)malloc(5 * sizeof(int*)); for (i = 0; i < 5; i ++) { tempPtr[i] = (int*)malloc(5 * sizeof(int)); }//Of for i for (i = 0; i < 5; i ++) { for (j = 0; j < 5; j ++) { tempPtr[i][j] = myGraph[i][j]; printf("i = %d, j = %d, %drn", i, j, tempPtr[i][j]); } } printf("数据在上嗷rn"); GraphPtr tempGraphPtr = initGraph(5, tempPtr); AdjacencyListPtr tempListPtr = graphToAdjacentList(tempGraphPtr); printAdjacentList(tempListPtr); widthFirstTranverse(tempListPtr, 4); } int main(){ testGraphTranverse(); return 1; }
运算结果:
准备数据嗷 0就是没关系,1就是有关系 i = 0, j = 0, 0 i = 0, j = 1, 1 i = 0, j = 2, 0 i = 0, j = 3, 1 i = 0, j = 4, 0 i = 1, j = 0, 1 i = 1, j = 1, 0 i = 1, j = 2, 1 i = 1, j = 3, 0 i = 1, j = 4, 1 i = 2, j = 0, 0 i = 2, j = 1, 1 i = 2, j = 2, 0 i = 2, j = 3, 1 i = 2, j = 4, 1 i = 3, j = 0, 1 i = 3, j = 1, 0 i = 3, j = 2, 1 i = 3, j = 3, 0 i = 3, j = 4, 0 i = 4, j = 0, 0 i = 4, j = 1, 1 i = 4, j = 2, 1 i = 4, j = 3, 0 i = 4, j = 4, 0 数据在上嗷 这就是宁要的邻接表: 1, 3, 0, 2, 4, 1, 3, 4, 0, 2, 1, 2, width first 4 1 2 0 3
附加图片方便大家理解这个答案是什么意思:
这题是个无向图欸,如果是有向图的话......
比如
那答案就是
V0 : ->1->3
V1: ->2->4
V2: ->3->4
V3:
V4:
为什么不画图,因为太丑啦!
#include#include #include #include #include using namespace std; typedef char VertexType[4]; typedef char InfoPtr; typedef int VRType; #define MAXSIZE 100 typedef enum {DG,DN,UG,UN}GraphKind; typedef struct ArcNode { int adjvex; InfoPtr *info; struct ArcNode *nextarc; }ArcNode; typedef struct VNode { VertexType data; ArcNode *firstarc; }VNode,AdjList[MAXSIZE]; typedef struct { AdjList vertex; int vexnum, arcnum; GraphKind kind; }AdjGraph; int LocateVertex(AdjGraph G, VertexType v); void CreateGraph(AdjGraph *G); void DisplayGraph(AdjGraph G); void DestoryGraph(AdjGraph *G); int LocateVertex(AdjGraph G, VertexType v) { int i; for (i = 0; i < G.vexnum; ++i) { if (strcmp(G.vertex[i].data, v) == 0) { return i; } } return -1; } void CreateGraph(AdjGraph *G) { int i, j, k; VertexType v1, v2; ArcNode *p; cout << "请输入图的顶点数和边数 "; cin >> (*G).vexnum >> (*G).arcnum; cout << "请输入" < vexnum<< "个顶点的值:" << endl; for (i = 0; i < G->vexnum;i++) { cin >> G->vertex[i].data; G->vertex[i].firstarc = NULL; } cout << "请输入弧尾 弧头" << endl; for (k = 0; k < G->arcnum;k++) { cin >> v1 >> v2; i = LocateVertex(*G, v1); j = LocateVertex(*G, v2); p = (ArcNode*)malloc(sizeof(ArcNode)); p->adjvex = j; p->info = NULL; p->nextarc = G->vertex[i].firstarc; G->vertex[i].firstarc = p; } (*G).kind = DG; } void DestoryGraph(AdjGraph *G) { int i; ArcNode *p, *q; for (i = 0; i < (*G).vexnum;i++) { p = G->vertex[i].firstarc; if (p!=NULL) { q = p->nextarc; free(p); p = q; } } (*G).vexnum = 0; (*G).arcnum = 0; } void DisplayGraph(AdjGraph G) { int i; ArcNode *p; cout << G.vexnum << "个顶点:" << endl; for (i = 0; i < G.vexnum;i++) { cout << G.vertex[i].data << " "; } cout << endl << G.arcnum << "条边:"< adjvex].data << " "; p = p->nextarc; } cout << endl; } } int main() { AdjGraph G; cout << "采用邻接矩阵创建有向图G:" << endl; CreateGraph(&G); cout << "输入有向图G的邻接表:" << endl; DisplayGraph(G); DestoryGraph(&G); system("pause"); return 0; }
运算内容加结果:
采用邻接矩阵创建有向图G: 请输入图的顶点数和边数 6 9 请输入6个顶点的值: a b c d e f 请输入弧尾 弧头 a b a c a f f c b c c d d a e d b f 输入有向图G的邻接表: 6个顶点: a b c d e f 9条边: a→f a→c a→b b→f b→c c→d d→a e→d f→c 请按任意键继续. . .
结束.



