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");
}