图形结构源码

1、将图形转化为多元邻接列表

#include <stdlib.h>
#include <stdio.h>

struct edge
{
	int vertex1;
	int vertex2;
	struct edge *edge1;
	struct edge *edge2;
};
typedef struct edge *newedge;
struct node
{
	int vertex;
	struct edge *next;
};
typedef struct node *newnode;
struct node header[6];

void graph(int start,newedge New)
{
	newedge pointer,front;
	pointer=header[start].next;
	front=NULL;
	while(pointer!=NULL)
	{
		front=pointer;
		if(pointer->vertex1==start)
			pointer=pointer->edge1;
		else
			pointer=pointer->edge2;
	}
	if(front==NULL)
		header[start].next=New;
	else if(front->vertex1==start)
		front->edge1=New;
	else
		front->edge2=New;
}

void print(newnode head)
{
	newedge pointer=head->next;
	while(pointer!=NULL)
	{
		printf("(%d,%d)",pointer->vertex1,pointer->vertex2);
		if(pointer->vertex1==head->vertex)
			pointer=pointer->edge1;
		else
			pointer=pointer->edge2;
	}
	printf("\n");
}

void main()
{
	int i;
	int start,end;
	newedge edge;
	for(i=0;i<6;i++)
	{
		header[i].vertex=i;
		header[i].next=NULL;
	}

	while(1)
	{
		printf("please input the start point of the edge:");
		scanf("%d",&start);
		if(start==-1)
			break;
		printf("please input the end point of the edge:");
		scanf("%d",&end);
		edge=malloc(sizeof(struct edge));
		if(edge!=NULL)
		{
			edge->vertex1=start;
			edge->vertex2=end;
			edge->edge1=NULL;
			edge->edge2=NULL;
		}
		graph(start,edge);
		graph(end,edge);
	}
	for(i=0;i<6;i++)
	{
		printf("Vertex[%d] :",i);
		print(&header[i]);
	}
	system("pause");
}

2、深度优化搜索(DFS)

#include <stdlib.h>
#include <stdio.h>

#define maxvertex 9
struct node
{
	int vertex;
	struct node *next;
};

typedef struct node *graph;
struct node header[maxvertex];
int marked[20];

void creatlist(int start,int end)    //创建链表
{
	graph New,pointer;
	pointer=&header[start];
	New=(graph)malloc(sizeof(struct node));
	if(New!=NULL)
	{
		New->vertex=end;
		New->next=NULL;
	}
	while(pointer->next!=NULL)
	{
		pointer=pointer->next;
	}
	pointer->next=New;
}

void print(graph head)         //打印链表
{
	graph pointer=head->next;
	
	while(pointer!=NULL)
	{
		printf("[%d]",pointer->vertex);
		pointer=pointer->next;
	}
}

void DFS(int vertex)            //深度优化搜索
{
	graph pointer;
	marked[vertex]=1;
	printf("[%d]==>",vertex);
	pointer=header[vertex].next;
	while(pointer!=NULL)
	{
		if(marked[pointer->vertex]==0)
			DFS(pointer->vertex);
		pointer=pointer->next;
	}
}

void main()
{
	int i;
	int  Node[20][2] = { {1,2}, {2,1}, {1,3}, {3,1}, {2,4},
						{4,2}, {2,5}, {5,2}, {3,6}, {6,3},
						{3,7}, {7,3}, {4,8}, {8,4}, {5,8},
						{8,5}, {6,8}, {8,6}, {7,8}, {8,7} };	
	for(i=0;i<20;i++)
	{
		marked[i]=0;
	}
	for(i=0;i<maxvertex;i++)
	{
		header[i].vertex=i;
		header[i].next=NULL;
	}
	for(i=0;i<20;i++)
		creatlist(Node[i][0],Node[i][1]);
	for(i=0;i<maxvertex;i++)
	{
		printf("Vertex[%d]: ",i);
		print(&header[i]);
		printf("\n");
	}
	printf("Start==>");
	DFS(1);
	printf("End\n");
	system("pause");
}

3、广度优先搜索(BFS)

#include <stdlib.h>
#include <stdio.h>

#define maxvertex 9
#define queuemax 9
struct node
{
	int vertex;
	struct node *next;
};

typedef struct node *graph;
struct node header[maxvertex];
int marked[20];
int queue[queuemax];
int rear=-1;
int front=-1;

int enqueue(int vertex)              //压入列队
{
	if(rear>=queuemax)
		return -1;
	else
	{
		rear++;
		queue[rear]=vertex;
	}
}

int dequeue()                       //删除队头
{
	if(front==rear)
		return -1;
	else
	{
		front=front+1;
		return queue[front];
	}	
}

int getfront()                      //获取队头
{
	int k;
	if(front==rear)
		return -1;
	else
	{
		k=front+1;
		return queue[k];
	}	
}

void creatlist(int start,int end)    //创建链表
{
	graph New,pointer;
	pointer=&header[start];
	New=(graph)malloc(sizeof(struct node));
	if(New!=NULL)
	{
		New->vertex=end;
		New->next=NULL;
	}
	while(pointer->next!=NULL)
	{
		pointer=pointer->next;
	}
	pointer->next=New;
}

void print(graph head)         //打印链表
{
	graph pointer=head->next;
	
	while(pointer!=NULL)
	{
		printf("[%d]",pointer->vertex);
		pointer=pointer->next;
	}
}

void BFS(int vertex)            //深度优化搜索
{
	graph pointer;
	printf("[%d]==>",vertex);
	marked[vertex]=1;           //标记已经输出	
	enqueue(vertex);
	pointer=header[vertex].next;
	while(front!=rear)          //如果列队非空
	{
		while(pointer!=NULL)    //将头结点列表中所有节点压入列队中
		{
			if(marked[pointer->vertex]==0)
			{
				enqueue(pointer->vertex);
				printf("[%d]==>",pointer->vertex);
				marked[pointer->vertex]=1;
			}
			pointer=pointer->next;
		}
		dequeue();              //删除列队头节点
		pointer=header[getfront()].next;      //获取列队中下一个头结点列表指针
	}
}

void main()
{
	int i;
	int  Node[20][2] = { {1,2}, {2,1}, {1,3}, {3,1}, {2,4},
						{4,2}, {2,5}, {5,2}, {3,6}, {6,3},
						{3,7}, {7,3}, {4,8}, {8,4}, {5,8},
						{8,5}, {6,8}, {8,6}, {7,8}, {8,7} };	
	for(i=0;i<20;i++)
	{
		marked[i]=0;
	}
	for(i=0;i<maxvertex;i++)
	{
		header[i].vertex=i;
		header[i].next=NULL;
	}
	for(i=0;i<20;i++)
		creatlist(Node[i][0],Node[i][1]);
	for(i=0;i<maxvertex;i++)
	{
		printf("Vertex[%d]: ",i);
		print(&header[i]);
		printf("\n");
	}
	printf("Start==>");
	BFS(1);
	printf("End\n");
	system("pause");
}


#include <stdlib.h>
#include <stdio.h>

#define maxvertex 9
#define queuemax 9
struct node
{
	int vertex;
	struct node *next;
};

typedef struct node *graph;
struct node header[maxvertex];
int marked[20];
int queue[queuemax];
int rear=-1;
int front=-1;

int enqueue(int vertex)              //压入列队
{
	if(rear>=queuemax)
		return -1;
	else
	{
		rear++;
		queue[rear]=vertex;
	}
}

int dequeue()                       //删除队头
{
	if(front==rear)
		return -1;
	else
	{
		front=front+1;
		return queue[front];
	}	
}

void creatlist(int start,int end)    //创建链表
{
	graph New,pointer;
	pointer=&header[start];
	New=(graph)malloc(sizeof(struct node));
	if(New!=NULL)
	{
		New->vertex=end;
		New->next=NULL;
	}
	while(pointer->next!=NULL)
	{
		pointer=pointer->next;
	}
	pointer->next=New;
}

void print(graph head)         //打印链表
{
	graph pointer=head->next;
	
	while(pointer!=NULL)
	{
		printf("[%d]",pointer->vertex);
		pointer=pointer->next;
	}
}

void BFS(int vertex)            //深度优化搜索
{
	graph pointer;
	printf("[%d]==>",vertex);
	marked[vertex]=1;           //标记已经输出	
	enqueue(vertex);
	while(front!=rear)          //如果列队非空
	{
		vertex=dequeue();
		pointer=header[vertex].next;
		while(pointer!=NULL)    //将头结点列表中所有节点压入列队中
		{
			if(marked[pointer->vertex]==0)
			{
				enqueue(pointer->vertex);
				printf("[%d]==>",pointer->vertex);
				marked[pointer->vertex]=1;
			}
			pointer=pointer->next;
		}		
	}
}

void main()
{
	int i;
	int  Node[20][2] = { {1,2}, {2,1}, {1,3}, {3,1}, {2,4},
						{4,2}, {2,5}, {5,2}, {3,6}, {6,3},
						{3,7}, {7,3}, {4,8}, {8,4}, {5,8},
						{8,5}, {6,8}, {8,6}, {7,8}, {8,7} };	
	for(i=0;i<20;i++)
	{
		marked[i]=0;
	}
	for(i=0;i<maxvertex;i++)
	{
		header[i].vertex=i;
		header[i].next=NULL;
	}
	for(i=0;i<20;i++)
		creatlist(Node[i][0],Node[i][1]);
	for(i=0;i<maxvertex;i++)
	{
		printf("Vertex[%d]: ",i);
		print(&header[i]);
		printf("\n");
	}
	printf("Start==>");
	BFS(1);
	printf("End\n");
	system("pause");
}
4、最小生成树(Kruskal算法)

#include <stdlib.h>
#include <stdio.h>
#define Max 10
#define VertexNum 5

struct	List	                     /* 节点结构声明 */
{
	int		Vertex1;
	int		Vertex2;
	int		Weight;
	struct	List	*Next;
};
typedef	struct	List	Node;
typedef	Node	*Edge;			/* 定义邻接边的节点 */

int Edges[10][3] =	                /* 输入数据 */
	{ 	{1,2,7}, {1,3,6}, {1,4,5}, {1,5,12}, {2,3,14},
		{2,4,8}, {2,5,8}, {3,4,3}, {3,5,9}, {4,5,2} };

int Visited[VertexNum];	           /* 查找记录 */

/* --------------------------------------------------- */
/* Kruskal算法                                                  */
/* --------------------------------------------------- */
void Kruskal(Edge Head)
{
	Edge	Pointer;	               /* 节点声明 */
	int	EdgeNum = 0;	          /* 已连结边的数目 */
	int	Weight = 0;

	Pointer = Head;

			        /* 当边的数目为顶点的数目减1时,结束循环 */
	while ( EdgeNum != ( VertexNum - 1 )  )	
	{
			        /* 有一顶点不在生成树中时 */
		if ( Visited[Pointer->Vertex1] == 0
			|| Visited[Pointer->Vertex2] == 0 ) 
		{

			printf("==>[%d,%d]",Pointer->Vertex1,Pointer->Vertex2);
			printf("(%d)",Pointer->Weight);
			Weight += Pointer->Weight;
			EdgeNum++;	/* 边数加1 */
			Visited[Pointer->Vertex1] = 1;	/* 设为已查找 */
			Visited[Pointer->Vertex2] = 1;  /* 设为已查找  */
		}
		Pointer = Pointer->Next;	           /* 往下一个节点 */

		if ( Pointer == NULL )	           /* 已无边时 */
		{
			printf("No Spanning Tree \n");
			break;
		}
	}
	printf("\nTotal weight = %d\n",Weight);	/* 输出加权值总和 */
}

/* --------------------------------------------------- */
/* 输出链表数据                                              */
/* --------------------------------------------------- */
void Print_Edge(Edge Head)
{
	Edge	Pointer;		                /* 节点声明 */
	Pointer = Head;			           /* Pointer指针设为首节点 */
	while (	Pointer != NULL )	      /* 当节点为NULL结束循环 */
	{
		printf("[%d,%d]",Pointer->Vertex1,Pointer->Vertex2);
		printf("(%d)",Pointer->Weight); /* 输出加权值 */
		Pointer = Pointer->Next;	      /* 往下一个节点 */
	}
	printf("\n");
}

/* --------------------------------------------------- */
/* 递增插入邻接边至链表内                                     */
/* --------------------------------------------------- */
Edge Insert_Edge(Edge Head,Edge New)
{
	Edge	Pointer;		                 /* 节点声明 */

	Pointer = Head;			            /* Pointer指针设为首节点 */

	while ( 1 )
	{
		if ( New->Weight < Head->Weight ) /* 新的加权值比首节点小 */
		{
			New->Next = Head;	        /* 插入在首节点之前 */
			Head = New;
			break;
		}

		if ( New->Weight >= Pointer->Weight
			&& Pointer->Next==NULL) 
		{			
			Pointer->Next = New;
			break;
		}
		
		if ( New->Weight >= Pointer->Weight
			&& New->Weight < Pointer->Next->Weight) 
		{
			New->Next = Pointer->Next;
			Pointer->Next = New;
			break;
		}

		Pointer = Pointer->Next;	/* 往下一个节点 */
	}
	return Head;
}

/* --------------------------------------------------- */
/* 释放链表                                                   */
/* --------------------------------------------------- */
void Free_Edge(Edge Head)
{
	Edge	Pointer;		     /* 节点声明 */

	while (	Head != NULL )	/* 当节点为NULL结束循环 */
	{
		Pointer = Head;
		Head = Head->Next;	/* 往下一个节点 */
		free(Pointer);
	}
}

/* --------------------------------------------------- */
/* 建立链表                                                   */
/* --------------------------------------------------- */
Edge Create_Edge(Edge Head)
{
	Edge	New;			                /* 节点声明 */
	Edge	Pointer;		                /* 节点声明 */
	int	i;

	Head = (Edge) malloc(sizeof(Node));	/* 内存配置 */

	if ( Head == NULL )
		printf("Memory allocate Failure!!\n");	/* 内存配置失败 */

	else
	{
		Head->Vertex1 = Edges[0][0];
		Head->Vertex2 = Edges[0][1];
		Head->Weight = Edges[0][2];	          /* 定义节点加权值 */
		Head->Next = NULL;

		for ( i=1;i<10;i++ )
		{
			New = (Edge) malloc(sizeof(Node));

			if ( New != NULL )
			{
				New->Vertex1 = Edges[i][0];
				New->Vertex2 = Edges[i][1];
				New->Weight = Edges[i][2];      /* 定义节点加权值 */
				New->Next = NULL;

				Head = Insert_Edge(Head,New);   /* 则插入新节点 */
			}
		}
	}
	return Head;
}
/* --------------------------------------------------- */
/* 主程序                                                         */
/* --------------------------------------------------- */
void main ()
{
	Edge	Head;			           /* 节点声明 */
	int	i;			

	for ( i=0;i<VertexNum;i++ )	/* 清除查找记录 */
		Visited[i] = 0;
	Head=(Edge)malloc(sizeof(struct List));
	Head = Create_Edge(Head);	     /* 调用建立链表 */

	if ( Head != NULL )
	{
		printf("Kruskal  Algorithm : \n");
		printf("First Step : Sorting \n");
		Print_Edge(Head);
		printf("Second Step : Find Minimal Spanning Tree. \n");

		Kruskal(Head); 		/* 调用kruskal算法 */

		Free_Edge(Head);	/* 调用释放链表 */
	}
	system("pause");
}

5、最小生成树(Prims算法)

#include <stdlib.h>
#include <stdio.h>
#define Max 10
#define VertexNum 5

struct	List				/* 节点结构声明 */
{
	int		Marked;		/* 查找标记 */
	int		Vertex1;	     /* 顶点声明 */
	int		Vertex2;    	/* 顶点声明 */
	int		Weight;		/* 加权值 */
	struct	List	*Next;
};
typedef	struct	List	Node;
typedef	Node	*Edge;			/* 定义邻接边的节点 */

int Edges[10][3] =	                /* 输入数据 */
	{ 	{1,2,7}, {1,3,6}, {1,4,5}, {1,5,12}, {2,3,14},
		{2,4,8}, {2,5,8}, {3,4,3}, {3,5,9}, {4,5,2} };

int Visited[VertexNum+1];	           /* 查找记录 */

/* --------------------------------------------------- */
/* Prims算法                                         -------  */
/* --------------------------------------------------- */
void Prims(Edge Head,int Index)
{
	Edge	Pointer;	           /* 节点声明 */
	Edge	MinEdge;
	int		EdgeNum = 0;	/* 已连结边的数目 */
	int		Weight = 0;	/* 累计加权值 */
	int		i;

	Visited[Index] = 1;	      /* 设置已查找过 */
	MinEdge=(Edge)malloc(sizeof(struct List));
			                /* 当边的数目为顶点的数目减1时,结束循环 */
	while ( EdgeNum != ( VertexNum - 1 )  )
	{
		MinEdge->Weight = 999;		/* 将最小边的加权值设到最大 */

		for ( i=1;i<=VertexNum;i++ )	/* 判断未建立的邻接顶点 */

		{
			Pointer = Head;
			if ( Visited[i] == 1 )	/* 已存在生成树集合的顶点 */
			{
		while ( Pointer->Marked == 1 )	/* 往下一个未建立的邻接边 */
					Pointer = Pointer->Next;
				if ( MinEdge->Weight > Pointer->Weight && ( Pointer->Vertex1 == i
							|| Pointer->Vertex2 == i ) )
				MinEdge = Pointer;	/* 找出加权值最小的邻接边 */

				while (	Pointer != NULL )
		{
           /* 如果两顶点皆存在生成树集合中,表示是已查找过的边 */

					if ( Visited[Pointer->Vertex1] == 1
					&& Visited[Pointer->Vertex2] == 1 )
						Pointer->Marked = 1;
				/* 找出加权值最小的邻接边 */
					if ( MinEdge->Weight > Pointer->Weight
						&& Pointer->Marked == 0
						&& ( Pointer->Vertex1 == i
							|| Pointer->Vertex2 == i ) )
						MinEdge = Pointer;
					Pointer = Pointer->Next;
				}
			}
		}
	Visited[MinEdge->Vertex1] = 1;	/* 将顶点1设为存在生成树集合中 */

	Visited[MinEdge->Vertex2] = 1;	/* 将顶点2设为存在生成树集合中 */

		EdgeNum++;			           /* 生成树的边数加1 */
		Weight += MinEdge->Weight;	      /* 累计加权值 */
		printf("[%d,%d]",MinEdge->Vertex1,MinEdge->Vertex2);
		printf("(%d)",MinEdge->Weight);
	}
	printf("\nTotal weight = %d\n",Weight);/* 输出加权值总和 */
}

/* --------------------------------------------------- */
/* 释放链表                                       --------  */
/* --------------------------------------------------- */
void Free_Edge(Edge Head)
{
	Edge	Pointer;		      /* 节点声明 */

	while (	Head != NULL )	 /* 当节点为NULL结束循环 */
	{
		Pointer = Head;
		Head = Head->Next;	 /* 往下一个节点 */
		free(Pointer);
	}
}

/* --------------------------------------------------- */
/* 输出链表数据                                                                            */
/* --------------------------------------------------- */
void Print_Edge(Edge Head)
{
	Edge	Pointer;		          /* 节点声明 */

	Pointer = Head;			     /* Pointer指针设为首节点 */
	while (	Pointer != NULL )	/* 当节点为NULL结束循环 */
	{
		printf("[%d,%d]",Pointer->Vertex1,Pointer->Vertex2);
		printf("(%d)",Pointer->Weight);  /* 输出加权值 */
		Pointer = Pointer->Next;	       /* 往下一个节点 */
	}
	printf("\n");
}

/* --------------------------------------------------- */
/* 插入邻接边至链表中                                             */
/* --------------------------------------------------- */
Edge Insert_Edge(Edge Head,Edge New)
{
	Edge	Pointer;		          /* 节点声明 */

	Pointer = Head;			     /* Pointer指针设为首节点 */

	while ( Pointer->Next != NULL )	/* 插入在链表尾端 */
		Pointer = Pointer->Next;
	Pointer->Next = New;

	return Head;
}

/* --------------------------------------------------- */
/* 建立链表                                        -------- */
/* --------------------------------------------------- */
Edge Create_Edge(Edge Head)
{
	Edge	New;			                          /* 节点声明 */
	Edge	Pointer;		                          /* 节点声明 */
	int	i;

	Head = (Edge) malloc(sizeof(Node));	          /* 内存配置 */

	if ( Head == NULL )
		printf("Memory allocate Failure!!\n");	/* 内存配置失败 */

	else
	{
		Head->Marked = 0;
		Head->Vertex1 = Edges[0][0];
		Head->Vertex2 = Edges[0][1];
		Head->Weight = Edges[0][2];	          /* 定义节点加权值 */
		Head->Next = NULL;

		for ( i=1;i<10;i++ )
		{
			New = (Edge) malloc(sizeof(Node));

			if ( New != NULL )
			{
				New->Marked = 0;
				New->Vertex1 = Edges[i][0];
				New->Vertex2 = Edges[i][1];
				New->Weight = Edges[i][2];      /* 定义节点加权值 */
				New->Next = NULL;

				Head = Insert_Edge(Head,New);   /* 则插入新节点 */
			}
		}
	}
	return Head;
}
/* --------------------------------------------------- */
/* 主程序                                                         */
/* --------------------------------------------------- */
void main ()
{
	Edge	Head;			           /* 节点声明 */
	int	i;

	for ( i=1;i<=VertexNum;i++ )	/* 清除查找记录 */
		Visited[i] = 0;
	Head=(Edge)malloc(sizeof(struct List));
	Head = Create_Edge(Head);	      /* 调用建立链表 */
	Print_Edge(Head);

	if ( Head != NULL )
	{
		printf("Prims Algorithm : \n");
		printf("Start from Vertex 1.\n");
		printf("Find Minimal Spanning Tree.\n");

		Prims(Head,1); 		/* 调用Prims算法 */
		free(Head);		/* 调用释放链表 */
	}
	system("pause");
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值