#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Arcnode //边表结点
{
int adjvex;
Arcnode* next;
};
struct Vertexnode//顶点表结点
{
char vertex;
Arcnode* first;
};
struct node//记录邻接表的结点数目和首地址
{
int num;
Arcnode *head;
};
const int MAX_VERTEX = 10;
Vertexnode adjlist[MAX_VERTEX];
//线性表的排序,采用冒泡排序
void Listsort(Arcnode* head,int num)
{
int i = 0;
int j = 0;
//用于变量链表
Arcnode * L = head;
//作为一个临时量
Arcnode * p;
Arcnode * p1;
//如果链表为空直接返回
if (num== 0)
return;
for (i = num-1; i>=1; i--) //i表示L能指向的最右端
{
L = head;
for (j = 1; j <= i; j++) //执行从1到i的冒泡排序
{
//得到两个值
p = L;
p1 = L->next;//指向当前结点的下个结点
//如果前面的那个比后面的那个大,就交换它们之间的是数据域
if (p->adjvex > p1->adjvex)
{
int temp = p->adjvex;
p->adjvex = p1->adjvex;
p1->adjvex = temp;
}
L = L->next;//指向下个结点
}
}
}
void Creategraph(char a[], int n, int e)
{
node b[100];//用来储存每个结点边表的首地址和结点数目
for (int i = 0; i < n; i++)//每个结点的边表的结点数目初始化为0
{
b[i].num= 0;
}
int vernum = n;
int arcnum = e;
for (int i = 0; i < vernum; i++)//初始化顶点表
{
adjlist[i].vertex = a[i];
adjlist[i].first = NULL;
}
for (int i = 0; i < arcnum; i++)//动态建立边表,此时边表的结点并不是有序的
{
int vi,vj;
printf("边的起点和终点序号为:");
scanf_s("%d,%d", &vi, &vj);
Arcnode* s = (Arcnode*)malloc(sizeof(Arcnode));
b[vi].num++;
s->adjvex = vj;
s->next = NULL;
s->next = adjlist[vi].first;
adjlist[vi].first = s;
}
for (int i = 0; i < n; i++)//把顶点对应的边表首地址赋给记录表b
{
b[i].head = adjlist[i].first;
}
for (int i = 0; i < vernum; i++)//对每个顶点的边表进行由小到大冒泡排序
Listsort(b[i].head,b[i].num);
//printf("%d,%d", adjlist[0].first->adjvex, adjlist[0].first->next->adjvex);
//printf("%d,%d", adjlist[1].first->adjvex, adjlist[1].first->next->adjvex);
}
int vist[MAX_VERTEX] = { 0 };
void DFStraverse(int v)//深度递归遍历,从v开始遍历
{
vist[v] = 1;//vist数组记录对应下标结点是否已经被访问过
printf("%c", adjlist[v].vertex);//访问输出结点v
Arcnode* p = adjlist[v].first;//准备访问结点v的第一个邻接点
while (p != NULL)//该节点存在
{
if (vist[p->adjvex] == 0)//该结点没有被访问过
{
DFStraverse(p->adjvex);//访问该节点
}
else
p = p->next;//若该结点已经被访问过了,指向v的下一个邻接点
}
}
int visit[MAX_VERTEX] = { 0 };
void DFStraverse1(int v)//深度非递归遍历,从v结点开始
{
int stack[MAX_VERTEX];
int top = -1, w, x;
Arcnode* p = NULL;
printf("%c", adjlist[v].vertex);//输出结点v
visit[v] = 1;//标记已读
top++;//进栈
stack[top] = v;
while (top > -1)//若栈不为空执行循环操作
{
x = stack[top];//取栈顶(并没有退栈)
p = adjlist[x].first;//指向其第一个邻接点
while (p != NULL)//存在邻接点
{
w = p->adjvex;
if (visit[w] != 1)//该邻接点没有被访问过
{
printf("%c", adjlist[w].vertex);//输出该邻接点
visit[w] = 1;//标记已读
top++;//该邻接点进栈
stack[top] = w;
break;//跳出循环,回到取栈顶的操作
}
p = p->next;//若该邻接点已读则指向下一个邻接点
}
if (p == NULL)//若该结点没有未访问过的结点则退栈
top--;
}
}
int main()
{
char verlist[] = "ABCDEFG";
Creategraph(verlist, 7, 8);
//printf("深度搜索递归结果为\n");
//DFStraverse1(0);
//printf("\n");
//printf("深度搜索非递归结果为\n");
DFStraverse(0);
}
有向图邻接表的递归非递归深度优先遍历
最新推荐文章于 2023-04-02 14:32:24 发布