数据结构作业之邻接表及广度优先遍历

1.代码如下

#include <stdio.h> 
#include <malloc.h>
#include <stdbool.h>
#define QUEUE_SIZE 10
int* visited;

typedef struct Graph{
	int** connection;
	int numNodes;
}*GraphPtr;

GraphPtr initGraph(int paraSize, int** paraData)
{
	int i,j;
	GraphPtr resultPtr=(GraphPtr)malloc(sizeof(struct Graph));
	resultPtr->connection=(int**)malloc(sizeof(int*)*paraSize);
	resultPtr->numNodes=paraSize;
	for(i=0;i<paraSize;i++)
	{
		resultPtr->connection[i]=(int*)malloc(sizeof(int)*paraSize);
		for(j=0;j<paraSize;j++)
		{
			resultPtr->connection[i][j]=paraData[i][j];
		}
	}
	return resultPtr;
}

typedef struct GraphNodeQueue{
	int front;
	int rear;
	int* node;
}*QueuePtr;

QueuePtr initQueue()
{
	QueuePtr resultQueuePtr=(QueuePtr)malloc(sizeof(struct GraphNodeQueue));
	resultQueuePtr->node=(int*)malloc(sizeof(int)*QUEUE_SIZE);
	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==paraQueuePtr->front)
	{
		printf("Error, trying to enqueue %d. queue full.\r\n",paraNode);
		return ;
	}
	paraQueuePtr->node[paraQueuePtr->rear]=paraNode;
	paraQueuePtr->rear=(paraQueuePtr->rear+1)%QUEUE_SIZE;
}

int dequeue(QueuePtr paraQueue)
{
	if(isQueueEmpty(paraQueue))
	{
		printf("Error, empty queue\r\n");
		return -1;
	}
	paraQueue->front=(paraQueue->front+1)%QUEUE_SIZE;
	return paraQueue->node[paraQueue->front];
}

typedef struct AdjacencyNode{
	int column;
	struct AdjacencyNode* next;
}AdjacencyNode,*AdjacencyNodePtr;

typedef struct AdjacencyList{
	int numNodes;
	AdjacencyNodePtr headers;
}AdjacencyList,*AdjacencyListPtr;

AdjacencyListPtr graphToAdjacentList(GraphPtr paraPtr)
{
	int i,j;
	AdjacencyNodePtr p,q;
	AdjacencyListPtr resultPtr=(AdjacencyListPtr)malloc(sizeof(struct AdjacencyList));
	resultPtr->numNodes=paraPtr->numNodes;
	resultPtr->headers=(AdjacencyNodePtr)malloc(sizeof(struct AdjacencyNode)*paraPtr->numNodes);
	for(i=0;i<resultPtr->numNodes;i++)
	{
		p=&resultPtr->headers[i];
		p->column=-1;
		p->next=NULL;
		for(j=0;j<resultPtr->numNodes;j++)
		{
			if(paraPtr->connection[i][j]>0)
			{
				q=(AdjacencyNodePtr)malloc(sizeof(struct AdjacencyNode));
				q->column=j;
				q->next=NULL;
				p->next=q;
				p=p->next;
			}
		}
	}
	return resultPtr;
}

void printAdjacentList(AdjacencyListPtr paraPtr)
{
	AdjacencyNodePtr p;
	int i;
	printf("This is the graph:\r\n");
	for(i=0;i<paraPtr->numNodes;i++)
	{
		p=paraPtr->headers[i].next;
		while(p!=NULL)
		{
			printf("%d ",p->column);
			p=p->next;
		}
		printf("\r\n");
	}
}

void widthFirstTranverse(AdjacencyListPtr paraListPtr, int paraStart)
{
	printf("width first \r\n");
	int i,tempNode;
	AdjacencyNodePtr p;
	int* visited=(int*)malloc(sizeof(int)*paraListPtr->numNodes);
	for(i=0;i<paraListPtr->numNodes;i++)
	{
		visited[i]=0;
	}
	visited[paraStart]=1;
	QueuePtr tempQueue=initQueue();
	printf("%d\t",paraStart);
	enqueue(tempQueue,paraStart);
	
	while(!isQueueEmpty(tempQueue))
	{
		tempNode=dequeue(tempQueue);
		for(p=paraListPtr->headers[tempNode].next;p!=NULL;p=p->next)
		{
			if(visited[p->column])
			{
				continue;
			}
			printf("%d\t",p->column);
			visited[p->column]=1;
			enqueue(tempQueue,p->column);
		}
	}
	printf("\r\n");
}

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 data\r\n");
	
	tempPtr=(int**)malloc(5*sizeof(int*));
	for(i=0;i<5;i++)
	{
		tempPtr[i]=(int*)malloc(sizeof(int)*5);
	}
	for(i=0;i<5;i++)
	{
		for(j=0;j<5;j++)
		{
			tempPtr[i][j]=myGraph[i][j];
		}
	}
	printf("Data ready\r\n");
	
	GraphPtr tempGraphPtr=initGraph(5,tempPtr);
	AdjacencyListPtr tempListPtr=graphToAdjacentList(tempGraphPtr);
	printAdjacentList(tempListPtr);
	widthFirstTranverse(tempListPtr,4);
}

int main()
{
	testGraphTranverse();
	return 0;
}

2.图示

3.代码说明

1)先使用指向结构体的指针的数组header完成每一行头结点的分配

2)每一行后面结点的插入和单链表的插入相同

3)广度遍历与图的广度遍历相同,都是用队列进行遍历

4.运行结果

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

--------------------------------
Process exited after 0.1073 seconds with return value 0
请按任意键继续. . .

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值