实验5基本检索与周游方法算法设计.docx

上传人:b****5 文档编号:30089910 上传时间:2023-08-04 格式:DOCX 页数:146 大小:447KB
下载 相关 举报
实验5基本检索与周游方法算法设计.docx_第1页
第1页 / 共146页
实验5基本检索与周游方法算法设计.docx_第2页
第2页 / 共146页
实验5基本检索与周游方法算法设计.docx_第3页
第3页 / 共146页
实验5基本检索与周游方法算法设计.docx_第4页
第4页 / 共146页
实验5基本检索与周游方法算法设计.docx_第5页
第5页 / 共146页
点击查看更多>>
下载资源
资源描述

实验5基本检索与周游方法算法设计.docx

《实验5基本检索与周游方法算法设计.docx》由会员分享,可在线阅读,更多相关《实验5基本检索与周游方法算法设计.docx(146页珍藏版)》请在冰豆网上搜索。

实验5基本检索与周游方法算法设计.docx

实验5基本检索与周游方法算法设计

 

《算法分析与设计》实验报告

 

实验5基本检索与周游方法算法设计

姓名xxx学号xxxxx班级xxxxxxx

 

时间:

xxxxxx地点:

xxxx

 

同组人:

指导教师:

xxxxx

 

实验目的

 

1.掌握基本检索与周游方法算法设计的一般思想。

 

2.掌握二元树、图的周游和检索算法。

 

3.理解树、与或树、对策树周游与检索的思想和方法。

 

实验内容

 

1.二元树周游

 

2.图的周游

 

3.准备模拟二元树和模拟图的数据。

 

4.用递归方法设计二元树周游和检索程序,调试通过。

周游和检索的次序可

 

以是先序、中序和后序。

 

5.用非递归方法设计二元树周游和检索程序,调试通过。

周游和检索的次序可以是先序、中序和后序。

 

6.用递归方法设计图的周游程序,调试通过。

周游的次序可以是深度优先,也可以是宽度优先。

 

7.用非递归方法设计图的周游程序,调试通过。

周游的次序可以是深度优先,也可以是宽度优先。

 

1

 

实验环境

 

硬件:

Intel(R)Pentium(R)CPURAM:

4G

 

软件:

Myeclipse2013

编程语言:

Java

 

实验前准备

1、算法设计:

二元树周游

a)、中根次序周游(LDR)

ProcedureINORDER(T)

//T是一棵二元树。

T的每个结点有三个信息段:

LCHILD、DATA、RCHILD//

IfT≠0thencallINORDER(LCHILD(T))

callVISIT(T)

callINORDER(RCHILD(T))

endif

endINORDER

b)、先根次序周游(DLR)

ProcedurePREORDER(T)

//T是一棵二元树。

T的每个结点有三个信息段:

LCHILD、DATA、RCHILD//

IfT≠0thencallVISIT(T)

callPREORDER(LCHILD(T))

callPREORDER(RCHILD(T))

endif

endPREORDER

c)、后根次序周游(LRD)

ProcedurePOSTORDER(T)

//T是一棵二元树。

T的每个结点有三个信息段:

LCHILD、DATA、RCHILD//

IfT≠0thencallPOSTORDER(LCHILD(T))

callPOSTORDER(RCHILD(T))

callVISIT(T)

endif

endINORDER

d)、中根次序周游的非递归算法

ProcedureINORDER1(T)

//T是一棵二元树,每个结点有三个信息段:

LCHILD、DATA、

RCHILD//

//使用大小为m的栈的一个非递归算法//

1integeri,m,STACK(M)

 

2

 

2

ifT=0

then

return

endif

//T为空//

3

P←T;i←0//

周游T;i

为栈顶//

4

Loop

5

While

LCHILD(P)

≠0

do

//周游左子树//

6

i←i+1

7

If

i>mthenprint(

‘stackoverflow’)

8

Stop

9

Endif

10STACK(i)←P;P←LCHILD(P)

11Repeat

12Loop

13

CallVISIT(P)

//P

的左子树周游完//

14

P

←RCHILD(P)

15

If

P≠0

thenexitendif

//周游右子树//

16

Ifi=0thenreturnendif

17

P

←STACK(i);i←i-1

18

Repeat//

访问父结点//

19repeatendINORDER1

二、图的检索与周游

a)图的宽度优先检索算法

LineprocedureBFS(v)

//宽度优先检索G,它在结点v开始执行。

所有已访问结点都标上VISITED(i)=1。

图G和数组VISITED是全程量。

VISITED开始时都已置成0。

//

1

VISITED(V)←1;u

←v

2

将Q初始化库空

//Q是未检测结点的队列//

3

Loop

4

For

邻接于u的所有结点w

do

5

If

VISITED(w)=0then

callADDQ(w,Q)

//w未检

测//

6

VISITED(w)←1

7

Endif

8

Repeat

9

IfQ为空thenreturn

endif

//不再有还未检测的结点

//

10

CallDELETEQ(u,Q)

//从队中取一个未检测的结点//

11Repeat

12endBFS

b)图的宽度优先周游

ProcedureBFT(G,n)DeclareVISITED(n)

 

3

 

Fori←1tondo//将所有结点标注为未访问//

VISITED←0

Repeat

Fori←1tondo/反复调用BFS//

IfVISITED(i)=0thencallBFS(i)endif

Repeat

endBFT

c)图的深度优先检索算法procedureDFS(v)

//已知一个n结点无向(或有向)图G=(V,E)以及初值已置为零的数组VISITED(1:

n)。

这个算法访问由v可以到达的所有结点。

G和VISITED是全程量。

//

VISITED(V)←1;

For邻接于v的每个结点wdo

IfVISITED(w)=0thencallDFS(w)Endif

Repeat

endDFS

d)图的深度优先周游算法

ProcedureDFT(G,n)

DeclareVISITED(n)

Fori←1tondo//将所有结点标注为未访问//

VISITED←0

Repeat

Fori←1tondo/反复调用DFS//

IfVISITED(i)=0thencallDFS(i)endif

Repeat

endDFT

 

1、程序设计:

见附1

 

实验步骤

 

1、准备实验数据。

 

准备模拟二元树和模拟图的数据。

 

将二元树和模拟图的数据保存在文件中,在程序运行时读取,分别取名为

 

btree.txt和|Cost.txt

 

其中树的表现形式为第一行为根节点,其余若干行表示每行第一个数为子节

 

点,第二个数为父节点如:

 

4

 

图的表示方式为第一行为节点数,边数和是否为有向图,剩下的行是图和节点所组成的邻接矩阵,文件表示如下图:

 

其中∞表示为无穷即不可达

 

5

 

2、递归方法设计二元树周游和检索BinaryTree.java

 

根据算法设计的多段图向前处理法的sparks语言,写出相应的java程序,并

 

调试验证通过。

周游和检索的次序可以是先序、中序和后序。

(其中的为java

 

中的泛型类,类似c语言中的宏定义)visit()方法是访问该节点,将其加入到

 

一个链表中,方便以后输出,同时可以减少计算时间时噪声影响。

/**

*访问结点

*@paramnode

*/

publicvoidvisit(BinaryTreeNodenode){

list.add(node.getData());

}

 

/**

*递归实现二叉树的前序遍历

*@paramBT

*/

publicvoidpreOrderRecursive(BinaryTreeNodeBT){

if(BT!

=null){

visit(BT);

preOrderRecursive(BT.getLChild());

preOrderRecursive(BT.getRChild());

}

}

 

/**

*递归实现二叉树的中序遍历

*@paramBT

*/

publicvoidinOrderRecursive(BinaryTreeNodeBT){

if(BT!

=null){

inOrderRecursive(BT.getLChild());

visit(BT);

inOrderRecursive(BT.getRChild());

}

}

 

/**

*递归实现二叉树的后序遍历

 

6

 

*@paramBT

*/

publicvoidpostOrderRecursive(BinaryTreeNodeBT){

if(BT!

=null){

postOrderRecursive(BT.getLChild());

visit(BT);

postOrderRecursive(BT.getRChild());

}

}

 

分别将其结果保存到文件中,分析其结果

 

3、非递归方法设计二元树周游和检索BinaryTree.java

 

根据最短路径问题的动态规划程序算法的sparks语言写出对应的java程序,

 

并调试验证通过,对比递归和非递归程序,验证其正确性;

/**

 

7

 

*非递归实现二叉树的中序遍历

*@paramBT

*/

publicvoidinNotOrderRecursive(BinaryTreeNodeBT){

/*MyArrayStack>stack;

intmaxStackSize=50;

stack=newMyArrayStack>(maxStackSize);*/

MyLinkedStack>stack=new

MyLinkedStack>();

 

BinaryTreeNodep=BT;

while(p!

=null||!

stack.isEmpty()){

while(p!

=null){//找到左子树

stack.push(p);

p=p.getLChild();

}

if(!

stack.isEmpty()){

p=stack.pop();//先从栈中弹出要结点

visit(p);//再访问根结点

p=p.getRChild();//然后再指向右子树

}

}

}

 

输出结果保存到文件中,可以看出与递归结果一致;

 

4、图的宽度优先检索和周游GraphSearch.java

 

用邻接矩阵的方式表示整个图并将每个节点是否访问用一个数组表示,同时访

 

问时将该结点加入到一个链表中去,方便以后输出使用并减少噪声影响;

/**

*

图的宽度优先检索

*

G,它在结点v开始执行,所有已访问结点都标上visited[i]=1,图G和数组

visited是全程变量,visited开始记为0

*@paramv

*/

 

8

 

publicvoidBFS(intv){

visit(v);

visited[v]=1;

intu=v;

LinkedListQ=newLinkedList();//当作放置未检测结

点的队列

while(true){

LinkedListlist=G.costList[u];

for(Edgee:

list){//邻接于u的所有结点

intw=e.v;

if(visited[w]==0){

Q.add(w);//将未检测的结点为w放入队列

visit(w);//访问该结点

visited[w]=1;//将该结点标记为1

}

}

if(!

Q.isEmpty()){//若队列不为空

u=Q.remove();//将未访问的结点从队列取出赋给u,并准备下一轮循环

}else{//队列为空表示所有结点访问结束

return;

}

}

}

 

/**

*宽度优先周游算法

*/

publicvoidBFT(){

for(inti=1;i<=G.n;i++){//将所有结点标注为未访问//

visited[i]=0;

}

for(inti=1;i

if(visited[i]==0)

BFS(i);

}

}

 

宽度优先检索结果(最后一行为检索的结果顺序)

 

9

 

宽度优先周游的结果:

 

5、图的深度度优先检索和周游GraphSearch.java

 

用邻接矩阵的方式表示整个图并将每个节点是否访问用一个数组表示,同时访

 

问时将该结点加入到一个链表中去,方便以后输出使用并减少噪声影响;

/**

*

图的深度优先检索

*

已知一个n结点的无向(或有向图)G,以及初会已置为零的数组visited,这个

算法可到达访问由v所可以到过的所有结点,G和visite是全程变量

*@paramv

*/

publicvoidDFS(intv){

visit(v);//访问该结点

visited[v]=1;//将该结点标记为1

LinkedListlist=G.costList[v];

for(Edgee:

list){//邻接于u的所有结点

intw=e.v;

if(visited[w]==0){

DFS(w);

}

}

 

10

 

}

 

/**

*图的深度优先周游

*/

publicvoidDFT(){

for(inti=1;i<=G.n;i++){//将所有结点标注为未访问//

visited[i]=0;

}

for(inti=1;i

if(visited[i]==0)

DFS(i);

}

}

 

深度优先检索结果(最后一行为检索的结果顺序)

 

深度优先周游的结果:

 

11

 

5、【附】查找族谱中的近亲FamilyTree.java

 

采用二元树相同的方法将村的结果存储在文件中,并以二叉树的方式表示树的

 

结构,但解释与二叉树不中,其中左孩子表示子辈,右孩子表示同辈;查找是否

 

是近亲时首先查找该节点,将该人的父辈祖先保存在栈中,采用一般树的后序遍

 

历方法(即二叉树的中序周游方法)可以达到此效果,然后再比较它们在规定的

 

代数如5代内是否有相同的祖先,如果有则表示他们为近亲;

publicbooleanisNearRelation(myTypex,myTypey,intn){

MyLinkedStack>stack0=xStack(x);

MyLinkedStack>stack1=xStack(y);

if(stack0==null){//若有一个结点未找到

System.out.println("未找到结点"+x.data);

returnfalse;

}elseif(stack1==null){

System.out.println("未找到结点"+y.data);

returnfalse;

}

 

inti=0;

LinkedListarryx=newLinkedList();

LinkedListarryy=newLinkedList();

//将两个结点的父辈们组成的栈加入链表中,只取前n个

while(!

stack0.isEmpty()&&i

BinaryTreeNodes=stack0.pop();

myTypem=s.getData();

arryx.add(m);

i++;

}

i=0;

while(!

stack1.isEmpty()&&i

BinaryTreeNodes=stack1.pop();

myTypem=s.getData();

arryy.add(m);

i++;

}

//比较链表是否有相同元素

for(intj=0;j

for(intk=0;k

if(arryx.get(j).equals(arryy.get(k))){

 

12

 

returntrue;

}

}

}

returnfalse;

}

 

/**

*采用后序遍历的方法对就二叉树的中序遍历方法,查找x元素,并将该结点的父辈们加

入到一个栈中

*@paramx

*@return

*/

@SuppressWarnings("unused")

publicMyLinkedStack>xStack(myTypex){

BinaryTreeNodep=familyTree.getRoot();

MyLinkedStack>stack=new

MyLinkedStack>();

 

while(p!

=null||!

stack.isEmpty()){

while(p!

=null){//先找到子树的最左边结点

stack.push(p);

p=p.getLChild();

}

if(!

stack.isEmpty()){

if(!

stack.isEmpty()){

p=stack.pop();//先从栈中弹出要结点

if(p.getData().equals(x)){//找到的话直接结束查找,最终返回

的是其父辈的终成的栈

returnstack;

}

p=p.getRChild();//然后再指向右子树

}

}

}//未找到返回空

returnnull;

}

 

族谱结构为(从1开始顺序编号)

 

13

 

表示的图形为

 

14

 

用二叉树表示如下:

 

比如查找F2和E8是否是5代以内的近亲,由图中可以清楚看到是,结果与之一致

 

15

 

查找它们是否为4代以内的近亲时,可以看出它是不是的

 

实验结果及其分析

 

1、递归方法设计二元树周游和检索

 

如果访问一个结点所需要的时间和空间为O

(1),n个结点每个结点均门访问

 

一次,这么算法的时间和空间复杂度均为O(n);

 

2、图的宽度优先检索和周游

 

图的宽度优先检索,t(n,e)=O(n+e)

 

图的宽度优先检索

BFS

n

10

20

30

40

50

60

70

80

90

100

100000次运行耗时

123

252

447

657

967

1335

1774

2276

2852

3452

 

16

 

图的宽度度优先周游,t(n)=O(n2)

 

图的宽度优先周游

BFT

n

10

20

30

40

50

60

70

80

90

100

100000次运行耗时

126

249

440

665

976

1349

1770

2290

2811

3477

 

3、图的深度优先检索和周游

 

图的深度度优先检索,t(n,e)=O(n+e)

 

图的深度优先检索

DFS

 

17

 

n

10

20

30

40

50

60

70

80

90

100

100000次运行耗时

139

180

354

634

968

1335

1749

2304

2981

3742

 

图的深度度优先周游,t(n)=O(n2)

 

图的深度优先周游

DFT

n

10

20

30

40

50

60

70

80

90

100

100000次运行耗时

174

198

363

654

967

1342

1782

2328

2993

3596

 

4、总结

 

基本的检索和周游算法主要包括对树和图各结点的遍历访问。

二元树的访问

 

根据每个子树的访问次序可分为前序周游,中序周游和后序周游,三种方法周游

 

18

 

所需要的时间和空间复杂度相同,但过程中在栈中所存储和结点不同,在实际情

 

况中可根据需要采取不同的周游方法(比如在查找近亲一

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1