@【数据结构】(图-拓扑排序)

@【数据结构】(图-拓扑排序)

方法1:采用邻接表存储结构,按照堆栈的实现。
方法2:采用邻接矩阵实现:

在这里插入图片描述

#include<iostream>
#include<iomanip>
#include<stdlib.h>
#include<stdio.h>
#define INF 65535  //设为双字节无符号整数的最大值
using namespace std;
#define MAX 9999
//邻接矩阵结构
typedef struct
{
	char vexs[100];    //顶点表
	int edges[100][100];       //邻接表,即边表
	int n, e;    //顶点数和边数
}MGraph;
//邻接表结构
typedef char VextexType[10];
typedef struct edgenode
{
	int adjvex;   //相邻点序号
	int weight;     
	struct edgenode *nextarc;   //下一条边的顶点
}ArcNode;
typedef struct vexnode
{
	char data;    //存放一个顶点的信息;
	ArcNode *firstarc;   //指向第一条边结点
}VHeadNode;
typedef struct
{
	int n, e;
	VHeadNode adjlist[MAX];   //单链表头结点指针
}AdjGraph;     //图的邻接表类型


void createMG(MGraph &G)
{
	int n, e;
	int i, j, k, w;
	cout << "输入图的顶点数和边数:";
	cin >> n >> e;
	G.n = n; G.e = e;

	for (i = 0; i < n; i++)   //矩阵初始化
		for (j = 0; j < n; j++)
			G.edges[i][j] = 0;

	cout << "输入每条边对应的顶点序号(从0开始)与权值:" << endl;
	for (k = 0; k < e; k++)
	{
		cin >> i >> j >> w;
		G.edges[i][j] = w;  //图的邻接矩阵
	}
}
void outG(MGraph G)
{
	for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
			if (G.edges[i][j] != 0 && G.edges[i][j] < INF)
				cout << setw(4) << G.edges[i][j];
			else if (i == j) cout << setw(4) << "0";
			else cout << setw(4) << "∞";
		cout << endl;
	}

}
void MatToAdj(MGraph G, AdjGraph *&g)
{
	int i, j; ArcNode *p;
	g = (AdjGraph*)malloc(sizeof(AdjGraph));
	for (i = 0; i < G.n; i++)
		g->adjlist[i].firstarc = NULL;
	for(i=0;i<G.n;i++)
		for(j=G.n-1;j>=0;j--)
			if (G.edges[i][j] != 0)
			{
				p = (ArcNode*)malloc(sizeof(ArcNode));
				p->adjvex = j;
				p->weight = G.edges[i][j];
				p->nextarc = g->adjlist[i].firstarc;
				g->adjlist[i].firstarc = p;
			}
	g->n = G.n; g->e = G.e;
}
void Indegree(MGraph G, int A[])
{
	int i, j, w = 0;
	for (j = 0; j < G.n; j++)
	{
		int in = 0;
		for (i = 0; i < G.n; i++)
		{
			if (G.edges[i][j] != INF)
				w++;
		}
		A[j] = w;
	}

}
void topsort1(MGraph &G)
{
	int i, j, visit[MAX], A[20];
	int Qu[MAX], front = 0, rear = 0;  //定义循环队列
	for (i = 0; i < G.n; i++)
		visit[i] = 0;
	for (int a = 0; a < G.n; a++)
		if (visit[a] == 0)   //如果还有顶点没有被访问到
		{
			for (j = 0; j < G.n; j++)
			{
				int in = 0;
				for (i = 0; i < G.n; i++)
				{
					if (G.edges[i][j] != 0)
						in++;
				}
				A[j] = in;
			}
			for (i = 0; i < G.n; i++)
			{
				if (A[i] == 0 && visit[i] == 0)   //入度为0先排序
				{
					visit[i] = 1;
					rear = (rear + 1) % MAX; Qu[rear] = i;  //初始结点进队
					for (j = 0; j < G.n; j++)
						G.edges[i][j] = 0;     //把入度为零的结点行值改为0即为删除其出度
				}
			}
		}
	if (rear < G.n)
		cout << "有环路" << endl;
	else
		for (j = 1; j <= G.n; j++)
			cout << Qu[j] << "  ";
	cout << endl;
}
void out(AdjGraph *g)
{
	ArcNode *p;
	int i;
	cout << "顶点-->相邻顶点序号与权值为:" << endl;
	for (i = 0; i < g->n; i++)
	{
		cout <<i;
		p = g->adjlist[i].firstarc;
		if (p != NULL)
		{
			cout << "-->";
		}
		while (p != NULL)
		{
			cout << p->adjvex << "   " << p->weight << "   /";
			p = p->nextarc;
		}
		cout << endl;
	}
}
void topsort2(AdjGraph *g)
{
	int i, j, visit[MAX], A[20];

}
int indegree[MAX];//用来存储所有节点的入度之和
typedef struct
{
	int top;
	int *base;
	int stacksize;
}SqStack;
void FindInputDgeree(AdjGraph *G)//计算所有节点的入度
{
	ArcNode *p;
	int i;
 
	for(i = 0; i < G->n; i ++)
		indegree[i] = 0;
	for(i = 0; i < G->n; i ++)
	{
		p = G->adjlist[i].firstarc;
 
		while(p)
		{
			indegree[p->adjvex] ++;
			p = p->nextarc;
		}
	}
}
typedef struct node
{
	int data;
	struct node *next;
}StackNode, *LinkStack;
LinkStack Init()  //置空栈
{
	return NULL;
}
int Empty(LinkStack top)
{
	if (top == NULL) return 1;
	else return 0;
}
LinkStack push(LinkStack top, int x)
{
	StackNode *s;
	s = (StackNode*)malloc(sizeof(StackNode));
	s->data = x;
	s->next = top; top = s;   //新结点插入链表
	return top;
}
LinkStack pop(LinkStack top, int &x)
{
	StackNode *s;
	if (top == NULL)  return(NULL);  //空栈,返回空

	else
	{
		x = top->data; s = top;
		top = top->next;  free(s);
		return top;   //返回原栈顶结点数据域的值
	}
}

void TopologicalSort(AdjGraph *G)
{
	FindInputDgeree(G);
	int count = 0,i;
	LinkStack top;
	ArcNode *p;
	top = Init();
 
	for(i = 0; i < G->n; i ++)
		if (indegree[i] == 0)//把入度为零的节点入栈
			top = push(top, i);
			
	while(!Empty(top))
	{
		top=pop(top,i);
		cout<<i<<"  ";	count ++;
 
		p = G->adjlist[i].firstarc;
 
		while(p)
		{
			
			if(-- indegree[p->adjvex]==0)//判断去掉一条边后节点的入度是否为零
				top = push(top, p->adjvex);
			p = p->nextarc;
		}		
	}
	cout << endl;;
}
void main()
{
    cout << "1.采用邻接矩阵存储实现:" << endl;
	MGraph G;  
	
	createMG(G);
	cout << "建立的邻接矩阵如下:" << endl;
	outG(G);
	cout << endl;
	cout << "2.采用邻接表存储,按照堆栈实现:" << endl;
	AdjGraph *g;
	MatToAdj(G, g);
	cout << "输入的邻接表为:" << endl;
	out(g);
	cout << endl;
	cout << "-----------------------------------------------------" << endl;
	cout << "邻接矩阵拓扑排序结果为:" << endl;
	topsort1(G);
	cout << "邻接表拓扑排序结果为:" << endl;
	TopologicalSort(g);
	system("pause");
}


测试:
在这里插入图片描述
在这里插入图片描述
有向无环图的拓扑排序不唯一

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值