数据结构——图——拓扑排序算法

article/2025/10/1 7:27:36

数据结构——图——拓扑排序算法

对AOV网进行拓扑排序的基本思路是:从AOV网中选择一个入度为0的顶点输出,然后删去此顶点,并删除以此顶点为尾的弧,继续重复此步骤,直到输出全部顶点或者AOV 网中不存在入度为0的顶点为止。

首先我们需要确定一下这个图需要使用的数据结构。前面求最小生成树和最短路径时,我们用的都是邻接矩阵,但由于拓扑排序的过程中,需要删除顶点,显然用邻接表会更加方便。因此我们需要为AOV网建立一个邻接表。考虑到算法过程中始终要查找入度为0的顶点,我们在原来顶点表结点结构中,增加一个入度域in,结构如表7-8-1所示,其中in就是入度的数字。

在这里插入图片描述
因此对于图7-8-2的第一幅图AOV网,我们可以得到如第二幅图的邻接表数据结构。

在这里插入图片描述
在这里插入图片描述
在拓扑排序算法中,涉及的结构代码如下。

typedef struct EdgeNode    /*边表结点*/
{int adjvex;            /*邻接点域,存储该顶点对应的下标*/int weight;            /*用于存储权值,对于非网图可以不需要*/struct EdgeNode* next; /*链域,指向下一个邻接点*/}EdgeNode;typedef struct VertexNode   /*顶点表结点*/
{int in;                 /*顶点入度*/int data;               /*顶点域,存储顶点信息*/EdgeNode* firstedge;     /*边表头指针*/
} VertexNode,AdjList[MAXVEX];typedef struct
{AdjList adjList;int numVertexes, numEdges;    /*图中当前顶点数和边数*/
}graphAdjList,*GraphAdjList;

在管法由.我还需要辅助的数据结构–栈,用来存储处理过程中入度为0的顶点,目的是为了避免每个查找时都要去遍历顶点表找有没有入度为0的顶点。

现在我们来看代码,并且模拟运行它。


/*拓扑排序,若GL无回路,则输出拓扑排序序列并返回true,若有回路返回false*/
bool TopologicalSort(GraphAdjList GL)
{EdgeNode* e;int i, k, gettop;int top = 0;        /*用于栈指针下标*/int count = 0;      /*用于统计输出顶点的个数*/int* stack;         /*建栈存储入度为0的顶点*/stack = (int*)malloc(GL->numVertexes * sizeof(int));for (i=0;i<GL->numVertexes;i++){if (GL->adjList[i].in==0){stack[++top] = i;   /*将入度为0的顶点入栈*/}}while (top!=0){gettop = stack[top--];/*出栈*/printf("%d ->",GL->adjList[gettop].data);/*打印此顶点*/count++;/*统计输出顶点数*/for (e=GL->adjList[gettop].firstedge;e;e=e->next){/*对此顶点弧表遍历*/k = e->adjvex;if (!(--GL->adjList[k].in))/*将k号顶点邻接点的入度减1*/{stack[++top] = k;/*若为0则入栈,以便于下次循环输出*/}}}if (count<GL->numVertexes)/*如果count小于顶点数,说明存在环*/{return false;}else{return true;}
}

在这里插入图片描述

1.程序开始运行,第3~7行都是变量的定义,其中stack是一个栈,用来存储整型的数字。
2.第8~10行,作了一个循环判断,把入度为0的顶点下标都入栈,从图7-8-3的右图邻接表可知,此时 stack应该为:{0,1,3},即v0、v1、v3的顶点入度为0,如图7-8-3所示。

在这里插入图片描述
3.第12~23行,while循环,当栈中有数据元素时,始终循环。
4.第14~~16行,v3出栈得到gettop=3。并打印此顶点,然后count 加1。
5.第17~22行,循环其实是对v3顶点对应的弧链表进行遍历,即图7-8-4中的灰色部分,找到v3连接的两个顶点v2和 v13,并将它们的入度减少一位,此时v2和v3的in值都为1。它的目的是为了将v3顶点上的弧删除。
在这里插入图片描述
6.再次循环,第12~23行。此时处理的是顶点v1。经过出栈、打印、count=2
后,我们对v1到v2、V4、v8的弧进行了遍历。并同样减少了它们的入度数,此时v2入度为0,于是由第20~21行知,v2入栈,如图7-8-5所示。试想,如果没有在顶点表中加入 in这个入度数据域,20行的判断就必须要是循环,这显然是要消耗时间的,我们利用空间换取了时间。
在这里插入图片描述
7.接下来,就是同样的处理方式了。图7-8-6展示了V2 V6 V0 V4 V5 V8的打印删除过程,后面还剩几个顶点都类似,就不图示了。
在这里插入图片描述
在这里插入图片描述

8.最终拓扑排序打印结果为3->1->2->6->0->4->5->8->7->12->9->10->13->11。
当然这结果并不是唯一的一种拓扑排序方案。

分析整个算法,对一个具有n个顶点e条弧的AOV网来说,第8~10行扫描顶点表,将入度为0的顶点入栈的时间复杂为o(n),而之后的while 循环中,每个顶点进一次栈,出一次栈,入度减1的操作共执行了e次,所以整个算法的时间复杂度为o(n+e)。


http://chatgpt.dhexx.cn/article/QsVNTQW3.shtml

相关文章

拓扑排序详解(包含算法原理图解、算法实现过程详解、算法例题变式全面讲解等)

前置知识 有向无环图 在图论中&#xff0c;如果一个有向图无法从某个顶点出发经过若干条边回到该点&#xff0c;则这个图是一个有向无环图&#xff08;DAG图&#xff09;。 如图所示。 入度 对于一个有向图&#xff0c;若x点指向y点&#xff0c;则称x点为y点的入度。 出度…

拓扑排序算法分析(通俗易懂)

拓扑排序&#xff08;其实是一种依赖关系&#xff09;&#xff1a;对于有向且无环的图来说&#xff0c;当前这个节点的依赖来其之前已经完成了。 下面附上一个图让大伙更好的理解&#xff1a; 比如这个图&#xff1a;B需要依赖A才能完成&#xff0c;A需要依赖C和D才能完成&…

拓扑排序算法详讲

经过一天的专研,终于明白了拓扑排序算法,写篇博客记录一下心得. 一.拓扑排序介绍 在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们称为AOV网. 设G(V,E)是一个具有n个顶点的有向图,v中的顶点序列v1,v2…,vn,满足若从…

C++ 拓扑排序算法

拓扑排序 有向无环图 如果一个有向图的任意顶点都无法通过一些有向边回到自身&#xff0c;那么称这个有向图为有向无环图。 拓扑排序 拓扑排序是将有向无环图G的所有顶点排成一个线性序列&#xff0c;使得对图G中的任意两个顶点u、v&#xff0c;如果存在边u->v&#xff0c;那…

拓扑排序

拓扑排序 一、拓扑排序的定义&#xff1a; 先引用一段百度百科上对于拓扑排序的定义&#xff1a; 对一个有向无环图 ( Directed Acyclic Graph 简称 DAG ) G 进行拓扑排序&#xff0c;是将 G 中所有顶点排成一个线性序列&#xff0c;使得图中任意一对顶点 u 和 v &#xff0c…

拓扑排序算法

拓扑排序介绍 拓扑排序(Topological Order)是指&#xff0c;将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列。 这样说&#xff0c;可能理解起来比较抽象。下面通过简单的例子进行说明&#xff01; 例如&#xff0c;一个项目包括A、B、C…

经典算法之拓扑排序

定义&#xff1a; 把AOV网&#xff08;用定点表示活动&#xff0c;用弧表示活动间优先关系的有向图&#xff09;络中各个顶点按照它们互相之间的优先关系排列成一个线性序列的过程叫做拓扑排序。 方法&#xff1a; 在有向图中选一个没有前驱的顶点并且输出从图中删除该顶点和…

拓扑排序(topological sorting)介绍及Python实现

目录 1. 拓扑排序 2. 拓扑排序存在的前提 3. 拓扑排序的唯一性问题 4. 拓扑排序算法原理 4.1 广度优先遍历 4.2 深度优先遍历 5. 代码实现 5.1 Graph类的实现 5.2 广度优先搜索 5.3 深度优先搜索简易版&#xff08;无loop检测&#xff09; 5.4 深度优先搜索完整版 …

【算法】拓扑排序

今天学习拓扑排序。如果一个有向图的任意顶点都无法通过一些有向边回到自身&#xff0c;那么称这个有向图为有向无环图&#xff08;Directed Acyclic Graph&#xff0c;DAG&#xff09;。拓扑排序就是将有向无环图的所有顶点排序&#xff0c;使得图中任意两个点 u、v&#xff0…

拓扑排序及算法实现

一、拓扑排序概念 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序&#xff0c;是将G中所有顶点排成一个线性序列&#xff0c;使得图中任意一对顶点u和v&#xff0c;若边<u,v>∈E(G)&#xff0c;则u在线性序列中出现在v之前。通常&#xff0c;这样的线性…

利用迭代法求平方根——迭代法开平方运算

一、题目 用迭代法求&#xff1a; 的值。要求精度为0.00001&#xff0c;即 二、迭代公式 求平方根的迭代公式为&#xff1a; 当满足 时&#xff0c;这时的即是求得的根。如果 得到是精确值。如果不为0&#xff0c;则是近似值。 三、C代码 先给出开平方运算的函数。再给出主…

【算法】牛顿迭代法求平方根的原理和误差分析

前言 在《算法(第四版)》中的P23页&#xff0c;给出了经典的利用牛顿迭代法求平方根的算法&#xff0c;牛顿迭代法在数值计算中应用十分广泛&#xff0c;但是在看书中的代码时&#xff0c;我最困惑的是其中对收敛条件的判断&#xff0c;经过查阅资料和论坛&#xff0c;找到…

使用迭代法来求a的平方根

今天朋友问我一道使用迭代法求a的平方根的题&#xff0c;感觉受益匪浅&#xff0c;与诸君相分享 首先我们来看一下题目 我们也无需了解迭代法是什么原理&#xff0c;根据这个题目可以分析得到&#xff0c;需要使用while循环&#xff0c;下面是我的代码实践 #define _CRT_SEC…

利用牛顿迭代法求平方根

求n的平方根&#xff0c;先假设一猜测值X0 1&#xff0c;然后根据以下公式求出X1&#xff0c;再将X1代入公式右边&#xff0c;继续求出X2…通过有效次迭代后即可求出n的平方根&#xff0c;Xk1 先让我们来验证下这个巧妙的方法准确性&#xff0c;来算下2的平方根 (Computed b…

牛顿迭代法求解平方根

一个实例迭代简介牛顿迭代法 牛顿迭代法简介简单推导泰勒公式推导延伸与应用 一个实例 //java实现的sqrt类和方法 public class sqrt {public static double sqrt(double n){if (n<0) return Double.NaN;double err 1e-15;double t n;while (Math.abs(t - n/t) > err…

牛顿迭代法求一个数的平方根(python)

# !/usr/bin/env python # -*- coding: utf-8 -*- """ Author: P♂boy License: (C) Copyright 2013-2017, Node Supply Chain Manager Corporation Limited. Contact: 17647361832163.com Software: Pycharm File: sqrt.py.py Time: 2018/11/19 16:22 Desc:牛顿…

c++迭代法求平方根

用迭代法求x &#xff0c;要求前后两次求出的x的差的绝对值小于10-5&#xff0c;求平方根的迭代公式为&#xff1a; 输入 一个数a。 输出 的值。 样例输入 2.0样例输出 The square root of 2.00 is 1.41421 这道题我无语了...&#xff1a; #include<bits/stdc.h> …

牛顿迭代法求平方根原理

牛顿迭代法可以求解n次方的根&#xff0c;但这里只讨论用它来求平方根。 牛顿迭代法求平方根过程 Java代码实现 /*** 求一个数的平方根* param number* return*/public static double squareRoot(double number){if(number < 0){ //小于0的数无法开平方return Double.NaN;}e…

【算法】牛顿迭代法求平方根及多次方根

1. 概述 牛顿迭代法 牛顿迭代法 牛顿迭代法 是非常高效的求解方程的根的方法。其求解原理可以参考各文献。大体的思路如下&#xff1a; 通过不断地做切线来逼近真实的根&#xff0c;直到误差小于精度。 可得迭代公式&#xff1a; x n 1 x n − f ( x n ) f ′ ( x n ) x_{…

二分法和牛顿迭代法求平方根(Python实现)

求一个数的平方根函数sqrt(int num) ,在大多数语言中都提供实现。那么要求一个数的平方根&#xff0c;是怎么实现的呢&#xff1f; 实际上求平方根的算法方法主要有两种&#xff1a;二分法(binary search)和牛顿迭代法(Newton iteration) 1&#xff1a;二分法 求根号5 a:折半…