标签:可变 有用 返回 ++i 字符串 防止 入队 意义 教材
边(edge):图中连接这些顶点的线,如图一
图结构中顶点集合V(G)不能为空,必须包含一个顶点,而图结构边集合可以为空,表示没有边。
如果一个图结构中,所有的边都没有方向性,那么这种图便称为无向图。典型的无向图,如图二所示。由于无向图中的边没有方向性,这样我们在表示边的时候对两个顶点的顺序没有要求。例如顶点VI和顶点V5之间的边,可以表示为(V2, V6),也可以表示为(V6,V2)。
一个图结构中,边是有方向性的,那么这种图就称为有向图,如图三所示。由于图的边有方向性,我们在表示边的时候对两个顶点的顺序就有要求。我们采用尖括号表示有向边,例如<V2,V6>表示从顶点V2到顶点V6,而<V6,V2>表示顶点V6到顶点V2。
如果在一个无向图中, 每两个顶点之间都存在条边,那么这种图结构称为无向完全图。典型的无向完全图,如图四所示。
如果在一个有向图中,每两个顶点之间都存在方向相反的两条边,那么这种图结构称为有向完全图。典型的有向完全图,如图五所示。
这里的权可以理解成一个数值,就是说节点与节点之间这个边是否有一个数值与它对应,对于无权图来说这个边不需要具体的值。对于有权图节点与节点之间的关系可能需要某个值来表示,比如这个数值能代表两个顶点间的距离,或者从一个顶点到另一个顶点的时间,所以这时候这个边的值就是代表着两个节点之间的关系,这种图被称为有权图;
图的每个节点不一定每个节点都会被边连接起来,所以这就涉及到图的连通性,如下图:
这两种边都是有意义的,比如从A城市到B城市可能不仅仅有一条路,比如有三条路,这样平行边就可以用到这种情况。不过这两种边在算法设计上会加大实现的难度。而简单图就是不考虑这两种边。
首先,我们将起点的路径长设为0,其他顶点路径长设为负数(也可以是其他不可能的值,图例中用?表示),下例以v1作为起点
接着我们将起点所指向的顶点的路径长设为1,可以肯定的是,只有被路径长为0的起点所指向的顶点的路径长为1,本例中即v3和v4:
接下来,我们将路径长为1的顶点(v3和v4)所指向的顶点的路径长设为2,同样可以肯定,只有被路径长为1的顶点所指向的顶点的路径长为2。不过此时会遇到一个问题:v3是v4所指向的顶点,但v3的路径长显然不应该被设为2。所以我们需要对已知路径长的顶点设一个“已知”标记,已知的顶点不再更改其路径长,具体做法在给出代码时将写明。本例中,路径长要被设为2的顶点是v2、v5、v6
将最短路径的计算结果存于一个线性表中,其结构如下:
其中“一行”为线性表中的一个元素,每一行的四个单元格就是一个元素中的四个域:顶点、是否已知、与起点最短路径长、最短路径中自身的前一个顶点。
//无权最短路径计算,图存于邻接表graph,结果存入pathTable,起点即start
void unweightedPath(Node* graph,struct pathNode* pathTable,size_t start)
{
pathTable[start].known=true;
pathTable[start].distance=0; //若pathTable[x].distance为0,则其preV是无用的,我们不予理睬
//初始化pathTable中的其他元素
//curDis即当前距离,我们要做的是令distance==curDis的顶点所指的未知顶点的distance=curDis+1
for(int curDis=0;curDis<numVertex;++curDis)
{
for(int i=0;i<numVertex;++i)
{
if(!pathTable[i].known&&pathTable[i].distance==curDis)
{
pathTable[i].known=true;
//遍历pathTable[i]所指向的顶点X
{
if(!pathTable[X].known)
{
pathTable[X].preV=i;
pathTable[X].distance=curDis+1;
}
}
}
}
}
}
解决的思路是:我们罗列出所有已知顶点指向的所有未知顶点,看这些未知顶点中谁的distance被修改后会是最小的,最小的那个我们就修改其distance,并认为它已知。
首先是正常的初始化(我们将边的权重也标识出来),假设起点为v0:
接着我们罗列出所有已知顶点(只有v0)指向的所有未知顶点:v1、v2、v3。然后发现若修改它们的distance,则v1.distance=v0.distance+1=1,v2.distance=v0.distance+3=3,v3.distance=v0.distance+5=5。显然v1被修改后的distance是未知顶点中最小的,所以我们只修改v1的distance,并将v1设为已知,v2、v3不动:
接着我们继续罗列出所有已知顶点(v0、v1)指向的所有未知顶点:v2、v3、v4。然后发现若修改它们的distance,则v2.distance=v0.distance+3=3,v4.distance=v1.distance+1=2,v3.distance=v1.distance+1=2(虽然v0也指向v3,但是通过v0到v3的路径长大于从v1到v3,所以v3的distance取其小者),其中v3和v4的新distance并列最小,我们任选其一比如v4,然后只修改v4的distance,并将v4设为已知,其它不动:
继续,我们罗列出所有已知顶点(v0、v1、v4)指向的所有未知顶点:v2、v3、v6,发现若修改,则v2.distance=3,v3.distance=2,v6.distance=3,所以我们只修改v3的distance,并将v3设为已知:
继续,我们罗列出所有已知顶点(v0、v1、v3、v4)指向的所有未知顶点:v2、v5、v6,发现若修改,则v2.distance=3,v5.distance=10,v6.distance=3,我们在v2和v6中任选一个如v2,只修改v2.distance,并将v2设为已知:
继续,我们罗列出所有已知顶点指向的所有未知顶点:v5、v6,发现若修改,则v5.distance=5,v6.distance=3,所以我们只修改v6:
最后,罗列出的未知顶点只有v5,若修改,其distance=5,我们将其修改并设为已知,算法结束:
有权图伪代码:
//有权最短路径计算,图存于邻接表graph,结果存入pathTable,起点即start
void weightedPath(Node* graph,struct pathNode* pathTable,size_t start)
{
//初始化pathNode数组
size_t curV;
while(true)
{
//找到可确定distance的未知顶点中新distance最小的那个,存入curV,若没有则跳出循环
//令pathNode[curV].distance和pathNode[curV].prev修改为正确的值
pathNode[curV].known=true;
}
}
问题1解决方案:(详见链接5)
伪代码:
void topSort(graph* g,size_t numVertex,size_t topResult)
{
//两个表示顶点的变量,后面用
size_t tempV,adjV;
//存储各顶点入度的数组,顶点x的入度为indegree[x]
size_t indegree[numVertex];
伪:根据图g初始化indegree数组
for(int i=0;i<numVertex;++i)
{
伪:从indegree中找到一个入度为0的顶点,存入tempV
if(伪:没找到入度为0的顶点)
伪:报错、返回
topResult[i]=tempV;
伪:通过g[tempV]遍历tempV为起点的边的终点,存入adjV
indegree[adjV]--;
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Reptile {
public static void main(String[] args) {
// 传入你所要爬取的页面地址
String url1 = "http://www.xxxx.com.cn/";
// 创建输入流用于读取流
InputStream is = null;
// 包装流, 加快读取速度
BufferedReader br = null;
// 用来保存读取页面的数据.
StringBuffer html = new StringBuffer();
// 创建临时字符串用于保存每一次读的一行数据,然后 html 调用 append 方法写入 temp;
String temp = "";
try {
// 获取 URL;
URL url2 = new URL(url1);
// 打开流,准备开始读取数据;
is = url2.openStream();
// 将流包装成字符流,调用 br.readLine() 可以提高读取效率,每次读取一行;
br = new BufferedReader(new InputStreamReader(is));
// 读取数据, 调用 br.readLine() 方法每次读取一行数据, 并赋值给 temp, 如果没数据则值 ==null,
// 跳出循环;
while ((temp = br.readLine()) != null) {
// 将 temp 的值追加给 html, 这里注意的时 String 跟 StringBuffer
// 的区别前者不是可变的后者是可变的;
html.append(temp);
}
// 接下来是关闭流, 防止资源的浪费;
if (is != null) {
is.close();
is = null;
}
// 通过 Jsoup 解析页面, 生成一个 document 对象;
Document doc = Jsoup.parse(html.toString());
// 通过 class 的名字得到(即 XX), 一个数组对象 Elements 里面有我们想要的数据, 至于这个 div的值,打开浏览器按下 F12 就知道了;
Elements elements = doc.getElementsByClass("xx");
for (Element element : elements) {
// 打印出每一个节点的信息; 选择性的保留想要的数据, 一般都是获取个固定的索引;
System.out.println(element.text());
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
for(i=0;i<5;i++){
for(j=0;j<5;j++){
a[i]=0;
b[i]=0;
dig[i][j]=-1;
}
}
问题2:输入点不能溢出,如下图:
问题2解决方案:
for(i=0;i<5;i++){
System.out.println("请输入第一个: ");
int input0 = scan.nextInt();
dig[i][j] = input0;
for(j=1;;j++){
System.out.println("请问是否有下一个接点 ");
String kong = scan.nextLine();
char yn = scan.next().charAt(0);
if(('Y' == yn)||(yn == 'y')){
String kong2 = scan.nextLine();
int input = scan.nextInt();
dig[i][j] = input;
a[i]++;
}
else{
j=0;
break;
}
}
}
for(int k=0;k<5;k++) {
for(j=0;j<5;j++){
for(i=0;dig[j][i]!=-1;i++){
if(dig[j][i]==k)
b[k]++;
}
}
}
(statistics.sh脚本的运行结果截图)
最近无检测,故无错题
- 结对学习内容
- 学习图的定义
- 学习图的遍历
团队是重要,合作起来我们可以攻克所有难关。
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 10000行 | 30篇 | 400小时 | |
第一周 | 69/69 | 2/2 | 30/30 | Scanner |
第二、三周 | 529/598 | 3/5 | 25/55 | 部分常用类 |
第四周 | 300/1300 | 2/7 | 25/80 | junit测试和编写类 |
第五周 | 2665/3563 | 2/9 | 30/110 | 接口与远程 |
第六周 | 1108/4671 | 1/10 | 25/135 | 多态与异常 |
第七周 | 1946/6617 | 3/13 | 25/160 | 栈、队列 |
第八周 | 831/7448 | 1/14 | 25/185 | 查找、排序 |
第九周 | 6059/13507 | 3/17 | 35/220 | 二叉查找树 |
第十周 | 6059/13507 | 3/20 | 45/265 | 图 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
计划学习时间:30小时
实际学习时间:45小时
改进情况:
这周没有太多别的事情,专心学习Java,攻读数据结构。
20182301 2019-2020-1 《数据结构与面向对象程序设计》第十周学习总结
标签:可变 有用 返回 ++i 字符串 防止 入队 意义 教材
原文地址:https://www.cnblogs.com/zhaopeining/p/11931443.html