图G是由顶点集V和边集E组成,记为G=(V,E),其中V(G)表示图G中顶点的有限非空集;E(G)表示图G中顶点之间的关系,也就是边的集合。
2.基本操作//定义图
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(sizeof(int*) * paraSize);
for(j = 0;j < paraSize;j++)
{
resultPtr->connections[i][j] = paraData[i][j];
}
}
return resultPtr;
}
图的遍历
建立一个数组用来记录结点是否被访问,是则标记为1。
void initTransverse(GraphPtr paraGraphPtr)
{
int i;
visitedPtr = (int*)malloc(paraGraphPtr->numNodes * sizeof(int));
for(i = 0;i < paraGraphPtr->numNodes;i ++)
{
visitedPtr[i] = 0;
}
}
1.深度优先遍历
深度优先遍历类似于二叉树的先序遍历。
//深度优先
void depthFirstTransverse(GraphPtr paraGraphPtr, int paraNode)
{
int i;
visitedPtr[paraNode] = 1;
printf("%d ",paraNode);
for(i = 0; i < paraGraphPtr->numNodes;i ++)
{
if(!visitedPtr[i])
{
if(paraGraphPtr->connections[paraNode][i])
{
depthFirstTransverse(paraGraphPtr,i);
}
}
}
}
2.广度优先遍历
广度优先遍历类似于二叉树的层序遍历,运用队列实现。
//广度优先
void widthFirstTransverse(GraphPtr paraGraphPtr, int paraStart)
{
int i,j,tempNode;
i = 0;
QueuePtr tempQueuePtr = initQueue();
printf("%d ",paraStart);
visitedPtr[paraStart] = 1;
enqueue(tempQueuePtr,paraStart);
while(!isQueueEmpty(tempQueuePtr))
{
tempNode = dequeue(tempQueuePtr);
visitedPtr[tempNode] = 1;
i ++;
for(j = 0;j < paraGraphPtr->numNodes;j ++)
{
if(visitedPtr[j])
continue;
if(paraGraphPtr->connections[tempNode][j] == 0)
continue;
printf("%d ",j);
visitedPtr[j] = 1;
enqueue(tempQueuePtr,j);
}
}
}
总代码
#include运行结果#include #include #define QUEUE_SIZE 10 int* visitedPtr; //图结点,队列 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("队空,不能出队.rn"); return -1; } paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE; return paraQueuePtr->nodes[paraQueuePtr->front]; } //定义图 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(sizeof(int*) * paraSize); for(j = 0;j < paraSize;j++) { resultPtr->connections[i][j] = paraData[i][j]; } } return resultPtr; } void initTransverse(GraphPtr paraGraphPtr) { int i; visitedPtr = (int*)malloc(paraGraphPtr->numNodes * sizeof(int)); for(i = 0;i < paraGraphPtr->numNodes;i ++) { visitedPtr[i] = 0; } } //深度优先 void depthFirstTransverse(GraphPtr paraGraphPtr, int paraNode) { int i; visitedPtr[paraNode] = 1; printf("%d ",paraNode); for(i = 0; i < paraGraphPtr->numNodes;i ++) { if(!visitedPtr[i]) { if(paraGraphPtr->connections[paraNode][i]) { depthFirstTransverse(paraGraphPtr,i); } } } } //广度优先 void widthFirstTransverse(GraphPtr paraGraphPtr, int paraStart) { int i,j,tempNode; i = 0; QueuePtr tempQueuePtr = initQueue(); printf("%d ",paraStart); visitedPtr[paraStart] = 1; enqueue(tempQueuePtr,paraStart); while(!isQueueEmpty(tempQueuePtr)) { tempNode = dequeue(tempQueuePtr); visitedPtr[tempNode] = 1; i ++; for(j = 0;j < paraGraphPtr->numNodes;j ++) { if(visitedPtr[j]) continue; if(paraGraphPtr->connections[tempNode][j] == 0) 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}}; printf("图的数组形式:n"); for(i = 0;i < 5;i ++) { for(j = 0;j < 5;j ++) { printf("%d ",myGraph[i][j]); } printf("n"); } int** tempPtr; 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]; } } GraphPtr tempGraphPtr = initGraph(5, tempPtr); printf("结点数 = %d rn", tempGraphPtr -> numNodes); printf("深度优先:rn"); initTransverse(tempGraphPtr); depthFirstTransverse(tempGraphPtr, 4); printf("n广度优先:rn"); initTransverse(tempGraphPtr); widthFirstTransverse(tempGraphPtr, 4); } int main() { testGraphTranverse(); return 1; }
图的矩阵形式: 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 结点数 = 5 深度优先遍历: 4 1 0 3 2 广度优先遍历: 4 1 2 0 3



