当前位置:文档之家› 基于DFS算法的图的遍历问题求解(MFC)

基于DFS算法的图的遍历问题求解(MFC)

基于DFS算法的图的遍历问题求解(MFC)
基于DFS算法的图的遍历问题求解(MFC)

封皮

(按学校要求手工填写)

成绩评定表

课程设计任务书

摘要

深度优先搜索(Depth-First-Search)是搜索算法的一种。是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。

目录

1 需求分析........................................................................................... - 1 -

2 算法基本原理................................................................................... - 1 -

3 类设计............................................................................................... - 3 -

4 详细设计........................................................................................... - 3 -4.1类的成员初步设计 ........................................................... 错误!未定义书签。

4.2类的成员函数设计 ........................................................... 错误!未定义书签。

4.3主函数设计 ....................................................................... 错误!未定义书签。

5 DOS界面程序运行结果及分析....................................................... - 6 -5.1程序运行结果 . (6)

5.2运行结果分析 (6)

6 基于MFC的图形界面程序开发 .................................................... - 6 -6.1基于MFC的图形界面程序设计. (7)

6.2程序测试 (13)

6.3MFC程序编写总结 .......................................................... 错误!未定义书签。

7 参考文献......................................................................................... - 15 -

1 需求分析

(1)图的应用和研究可追溯到18世纪。1736年,被称为图论之父的欧拉解决了哥尼斯堡(Konigsberg )问题,从而奠定了图论这门学科及其应用的基础。

(2)图作为一种非线性数据结构,被广泛应用与多个技术领域,诸如系统工程、化学分析、统计力学、遗传学、控制论、人工智能、编译系统等领域,在这些技术领域中把图结构作为解决的数学手段之一。

(3)程序测试数据来自姜学军李筠主编的《数据结构(C 语言描述)》中,所选的无向图是:

2 算法基本原理

(1) 邻接矩阵是表示节点之间的相邻接关系的矩阵。

若G 是有n 个节点的图,则G 的邻接矩阵是如下定义的n X n 矩阵。 如图所示图G 的邻接矩阵如下:

图GG 的邻接矩阵

0 1 1 1 1 0 1 0 1 1 0 1

1 0 1 0

(2)图的遍历——深度优先搜索

例如,有如下无向图:

操作步骤如下:

①先输出1(1为起点);

②将1的邻接顶点2和3压入栈中;

③弹出栈顶元素2,由于2未被访问过,输出2,然后将2的邻接顶点4

和5压栈;

④弹出栈顶元素4,由于4未被访问过,输出4,然后将4的邻接顶点8

和2压栈;

⑤弹出2,由于2已经被访问过,故弹出8,由于8未被访问过,输出8,

再将8的邻接顶点4、5、6、7压栈;

⑥弹出4,由于4已经被访问过,故弹出5,由于5未被访问,输出5,

然后将5的邻接顶点2和8压栈;

⑦弹出已经访问过的2和8,再弹出6,由于6未被访问过,输出6,再

将6的邻接顶点3和8压栈;

⑧弹出3,由于3未被访问过,输出3,将3的邻接顶点1、6、7压栈;

⑨弹出已经访问过的1和6,再弹出7,由于7未被访问过,输出7,再

将7的邻接顶点3和8压栈;

⑩最后弹出都已经访问过的3、8、8、7、5、3;此时栈为空,表示搜索结束。

3 类设计

本题设计的关键是对图的深度优先搜索算法的设计,由于使用邻接矩阵来存储图,就要将深度优先搜索的算法扩展到矩阵中。首先应设计无向图类graph,然后设计成员变量,用二维数组e来表示图边的权值,二维数组v来表示顶点信息,eNum来表示边的无数量,vNum来表示顶点数量,以及在遍历中需要的访问标记数组visited。最后还要设计成员函数实现对邻接矩阵的输出print(),深度优先搜索函数DFS()和递归调用dfs()。考虑到图的初始化比较复杂,需要输入各个顶点信息,和每条边的权值,还要设计函数InitGraph()实现对数组的初始化。

4 详细设计

由于类的设计较为简单,将类和主函数放在同一个文件中,方便调试,首先声明无向图类graph,进行类的设计,然后设计主函数,直接在主函数中实现类,并输出邻接矩阵和深度优先搜索结果。

#include

#include

using namespace std;

constintmaxnum = 100;

class graph

{

public:

char v[maxnum];

int e[maxnum][maxnum];

intvNum;

inteNum;

int visited[maxnum];

graph(inta,int b);

intInitGraph();

void print();

void dfs(int i);

void DFS();

} ;

graph ::graph(inta,int b)

{

cout<<"创建顶点数为"<

vNum=a;

eNum=b;

for(int i=0;i

{

for(int j=0;j

{

e[i][j] = 0;

}

}

}

int graph ::InitGraph()

{

inti,j,temp,flag=0;

for (i=0; i

{

cout<<"请输入第"<

cin>> v[i];

}

cout<<"请输入各个边的权值"<

for (i=0; i

{

for(j=i+1;j

{

cout<< v[i]<<"->"<< v[j]<<"的权值";

cin>>temp;

e[i][j] = temp;

e[j][i] = temp;

if(temp)

flag++;

if(flag==eNum)

{

cout<<"初始化无向图邻接矩阵完毕"<

return 0;

}

}

}

return 1;

}

void graph :: print()

{

cout<<"邻接矩阵为"<

inti,j;

for (i=0; i

{

for (j=0;j

cout<< e[i][j]<<" ";

cout<

}

}

void graph :: dfs(int i)

{

cout<";

visited[i] = 1;

for(int j=0;j

{

if( e[i][j]!=0 && visited[j]==0) {

dfs(j);

}

}

}

void graph :: DFS()

{

int i;

for(i=0;i

{

visited[i] = 0;

}

for(i=0;i

if(visited[i]==0)

{dfs(i);}

cout<

}

}

int main(){

graph g(5,6);

g.InitGraph();

g.print();

cout<<"深度优先搜索的结果:"<

g.DFS();

return 0;

}

5 DOS界面程序运行结果及分析

5.1 程序运行结果

程序运行结果如图2所示。

图2 程序运行结果

5.2运行结果分析

程序运行后首先创建了图类的对象,调用构造函数,产生一个顶点数为5,边数为6的无向图,然后初始化这个图,输入每个顶点的信息和每条边的权值。在主函数中直接调用邻接矩阵输出函数和深度优先搜索结果。

6 基于MFC的图形界面程序开发

MFC的图形界面程序设计可在上述类设计的基础上进行改造,MFC的图形

界面程序与DOS界面程序的主要不同点是:MFC图形界面程序与DOS界面程序的输入输出方式不同,DOS界面程序采用字符交互式实现数据输入输出,主要通过cin,cout等I/O流实现,而MFC的图形程序界面采用标准Windows窗口和控件实现输入输出,因此必须在MFC类的框架下加入上面所设计的图类,并通过图形界面的输入输出改造来完成。

6.1 基于MFC的图形界面程序设计

(1)界面设计

首先在VC中建立MFC AppWizard(exe)工程,名称为DFS,并在向导的Step1

中选择Dialog based,即建立基于对话框的应用程序,如下图4~5所示。

图4 建立MFC AppWizard(exe)工程

图5 建立基于对话框的应用程序

将对话框资源中的默认对话框利用工具箱改造成如下界面,如图6所示。

图6 方程组求解程序界面设计

图6所示的界面中包含了1个Static Text控件,3个Button控件,和12个Edit Box控件,控件的基本信息列表如下表1所示。

(2)代码设计

为了能够将对话框界面上的控件能够与代码联系起来,需要为12个Edit Box 控件建立Member Variables,按Ctrl+w键进入MFC ClassWizard界面,选择Member Variables选项卡,可显示成员变量设置界面,如图7所示。

图7 成员变量设置界面

通过该界面设置与24个Edit Box控件对应的成员变量,具体如表2所示。

下面是编写代码的重要阶段,可以借鉴在设计基于DOS界面的控制台应用程序的代码,并将其作必要的改写,具体改写的步骤与内容如下。

①将DFS.cpp文件重新命名为DFS.h,并将其加入MFC工程。

②修改DFS.h文件具体包括:

●将显示矩阵print()函数注释掉,在图形界面的程序上已经不需要个函数

承担输出功能了;

●将主函数注释掉,已经不需要主函数进行操作了;

●将深度优先搜索函数DFS()和dfs()的cout语句去掉,不需要也不能够使

用cout流实现输出;

●将graph类的所有成员改为公共的,方便给graph类的成员变量赋值

●在graph类中声明一个CString型的变量Dstr,用来保存函数输出结果的

字符串;

●在函数dfs内声明一个CString型变量temp,用来临时存储函数输出的

结果,并添加以下语句temp.Format("%d,",i+1);Dstr+=temp;

③在对话框类的实现文件CDFS_MFCDlg.cpp中加入#include "DFS.h",以

实现在该文件中可使用graph类。

④在对话框类的实现文件CDFS_MFCDlg.cpp中加入graph g(5,6);,构造一

个5顶点的无向图;

⑤编写邻接矩阵按钮的消息处理函数,实现图的邻接矩阵在界面上的显示,

具体代码如下:

V oidCDFS_MFCDlg::OnButtonLj()

{

// TODO: Add your control notification handler code here

CStringstr[10][10];

UpdateData();

g.e[0][1]=m_e12;g.e[1][0]=m_e12;

g.e[0][2]=m_e13;g.e[2][0]=m_e13;

g.e[0][3]=m_e14;g.e[3][0]=m_e14;

g.e[0][4]=m_e15;g.e[4][0]=m_e15;

g.e[1][2]=m_e23;g.e[2][1]=m_e23;

g.e[1][3]=m_e24;g.e[3][1]=m_e24;

g.e[1][4]=m_e25;g.e[4][1]=m_e25;

g.e[2][3]=m_e34;g.e[3][2]=m_e34;

g.e[2][4]=m_e35;g.e[4][2]=m_e35;

g.e[3][4]=m_e45;g.e[4][3]=m_e45;

m_LJ="";

UpdateData(0);

for (int i=0;i<5;i++)

{

for (int j=0;j<5;j++)

{

str[i][j].Format("%i,",g.e[i][j]);

m_LJ+=str[i][j];

}

m_LJ+="\r\n";

}

UpdateData(0);

}

⑥编写深度优先遍历按钮的消息处理函数,实现对图的深度遍历,并显示

到界面上,具体代码如下:

voidCDFS_MFCDlg::OnButtonSd()

{

// TODO: Add your control notification handler code here

CStringstr[10][10];

UpdateData();

g.e[0][1]=m_e12;g.e[1][0]=m_e12;

g.e[0][2]=m_e13;g.e[2][0]=m_e13;

g.e[0][3]=m_e14;g.e[3][0]=m_e14;

g.e[0][4]=m_e15;g.e[4][0]=m_e15;

g.e[1][2]=m_e23;g.e[2][1]=m_e23;

g.e[1][3]=m_e24;g.e[3][1]=m_e24;

g.e[1][4]=m_e25;g.e[4][1]=m_e25;

g.e[2][3]=m_e34;g.e[3][2]=m_e34;

g.e[2][4]=m_e35;g.e[4][2]=m_e35;

g.e[3][4]=m_e45;g.e[4][3]=m_e45;

g.Dstr="";

g.DFS();

m_SD="";

UpdateData(0);

m_SD=g.Dstr;

UpdateData(0);

}

⑦退出按钮代码如下:

voidCGuassLineGUIDlg::OnBUTTONExit()

{

// TODO: Add your control notification handler code here

OnOK();

}

6.2程序测试

运行程序后,首先出现的界面如图8所示。

图8程序初始运行界面

在编辑框输入邻接矩阵的权值后,单击邻接矩阵按钮,可将这个5顶点的无向图邻接矩阵在界面上显示出来,如图9所示。

图9读入数据后的界面

单击深度优先遍历按钮,实现对图的深度优先搜索并显示出搜索结果,如图10所示。

图10求解方程组后的界面

单击退出按钮后,程序能够正常实现退出。

7结论

MFC为Windows应用程序开发者提供了一种快速开发的工具,尤其是MFC中提供的多种标准控件,使得开发者不再将过多的心思花在界面代码编写上,而将更多的精力投入到应用程序的逻辑功能上,在很大程度上减轻了程序员的负担。由于MFC是通用框架,没有很好的针对性,当然也就丧失了一些灵活性和效率,但是MFC的封装很浅,所以在效率上损失不大,灵活性也很好,虽然也有很多缺陷,但还是一个比较好的编程环境。

此次课程设计让我体会到了真正的结合C++图形界面开发,也有像VB那样非常简单图形设计,同样也有C++面向对象程序设计的特点,这样编出来的程序也利于我们更加深入了解C++的编程。虽然程序可以成功的编译运行,但是仍然有很多的缺点和不足:

(1)graph类的设计有悖于数据结构存储的方式,并且类的成员函数全部为public,不利于信息的安全,应该将他们归于private,再设计一

个成员函数对其赋值。

(2)程序的界面设计并不完美,只能输入5个顶点的无向图图,应该设计为动态的输入界面,满足用户的不同需求。

(3)主程序没有设计输入顶点信息的函数,所以在深度优先遍历的时候不能输出顶点信息。

8参考文献

[1]姜学军,朱筠数据结构(C语言描述).中国轻工业出版社.2008

[2]郑莉,董渊,张瑞丰. C++语言程序设计(第3版). 北京:清华大学出版社,2007

[3]杨喜林,杨亮,可视化程序设计教程Visual C++. 北京:理工大学出版社,2010

[4]陈志泊,王春玲. 面向对象的程序设计语言—C++. 北京:人民邮电出版社,2002

[5]李庆扬,王能超,易大义. 数值分析. 湖北:华中理工大学出版社,1986

图的优先遍历算法(C语言版)

#include #define MAX_VERTEX_NUM 20 #define ERROR -1 #define TRUE 1 #define FALSE 0 typedef struct ArcNode{ int adjvex; struct ArcNode *nextarc; }ArcNode; typedef struct VNode{ char data; ArcNode *firstarc; }VNode,AdjList[MAX_VERTEX_NUM]; typedef struct { AdjList vertices; int vexnum,arcnum; }ALGraph; void CreateAL(ALGraph *G); int LocateVex(ALGraph G,char u); void DFSTraverse(ALGraph G,void (*Visit)(ALGraph G,int v)); void PrintElem(ALGraph G,int v); void DFS(ALGraph G,int v); int FirstAdjVex(ALGraph G,int v); int NextAdjVex(ALGraph G,int v,int w); int visited[MAX_VERTEX_NUM]; void (*VisitFunc)(ALGraph G,int v); int main(){ ALGraph G; CreateAL(&G); printf("The Graph is:\n"); DFSTraverse(G,PrintElem); getch(); } void CreateAL(ALGraph *T){ int i,j,m; ArcNode *p,*s; char ch[100]; printf("Please input the vexnum and arcnumm:\n"); scanf("%d%d",&(T->vexnum),&(T->arcnum)); printf("Please input the vertexs:\n"); for(i=0;i<(T->vexnum);++i){ scanf(" %c",&(T->vertices[i].data)); T->vertices[i].firstarc=NULL; }

贪心算法经典例题

贪心算法经典例题 发布日期:2009-1-8 浏览次数:1180 本资料需要注册并登录后才能下载! ·用户名密码验证码找回密码·您还未注册?请注册 您的账户余额为元,余额已不足,请充值。 您的账户余额为元。此购买将从您的账户中扣除费用0.0元。 内容介绍>> 贪心算法经典例题 在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。 从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。 我们看看下面的例子 例1 均分纸牌(NOIP2002tg) [问题描述] 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如 N=4,4 堆纸牌数分别为: ①9 ②8 ③17 ④ 6 移动3次可达到目的: 从③取 4 张牌放到④(9 8 13 10) -> 从③取 3 张牌放到②(9 11 10 10)-> 从②取 1 张牌放到①(10 10 10 10)。 [输入]:键盘输入文件名。 文件格式:N(N 堆纸牌,1 <= N <= 100) A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000) [输出]:输出至屏幕。格式为:所有堆均达到相等时的最少移动次数。 [输入输出样例] a.in: 4 9 8 17 6 屏慕显示:3 算法分析:设a[i]为第i堆纸牌的张数(0<=i<=n),v为均分后每堆纸牌的张数,s为最小移到次数。 我们用贪心法,按照从左到右的顺序移动纸牌。如第i堆(0

创建一个二叉树并输出三种遍历结果

实验报告 课程名称数据结构 实验项目实验三--创建一个二叉树并输出三种遍历结果 系别■计算机学院 _________________ 专业_______________ 班级/学号_____________ 学生姓名___________ 实验日期— 成绩______________________________ 指导 教师

实验题目:实验三创建一个二叉树并输出三种遍历结果 实验目的 1)掌握二叉树存储结构; 2)掌握并实现二叉树遍历的递归算法和非递归算法; 3)理解树及森林对二叉树的转换; 4)理解二叉树的应用一哈夫曼编码及WPL计算。 实验内容 1)以广义表或遍历序列形式创建一个二叉树,存储结构自选; 2)输出先序、中序、后序遍历序列; 3)二选一应用题:1)树和森林向二叉树转换;2)哈夫曼编码的应用问题。 题目可替换上述前两项实验内容) 设计与编码 1)程序结构基本设计框架 (提示:请根据所选定题目,描述程序的基本框架,可以用流程图、界面描述图、 框图等来表示) 2)本实验用到的理论知识遍历二叉树,递归和非递归的方法 (应用型

(提示:总结本实验用到的理论知识,实现理论与实践相结合。总结尽量简明扼要,并与本次实验密切相关,要求结合自己的题目并阐述自己的理解和想法) 3) 具体算法设计 1) 首先,定义二叉树的存储结构为二叉链表存储,每个元素的数 据类型Elemtype,定义一棵二叉树,只需定义其根指针。 2) 然后以递归的先序遍历方法创建二叉树,函数为CreateTree(),在输 入字符时要注意,当节点的左孩子或者右孩子为空的时候,应当输入一 个特殊的字符(本算法为“ #”),表示左孩子或者右孩子为空。 3) 下一步,创建利用递归方法先序遍历二叉树的函数,函数为 PreOrderTreeQ,创建非递归方法中序遍历二叉树的函数,函数为 InOrderTree(),中序遍历过程是:从二叉树的根节点开始,沿左子树 向下搜索,在搜索过程将所遇到的节点进栈;左子树遍历完毕后,从 栈顶退出栈中的节点并访问;然后再用上述过程遍历右子树,依次类 推,指导整棵二叉树全部访问完毕。创建递归方法后序遍历二叉树的 函数,函数为LaOrderTree()。 (提示:该部分主要是利用C、C++ 等完成数据结构定义、设计算法实现各种操作,可以用列表分步形式的自然语言描述,也可以利用流程图等描述) 4) 编码 #include #include #include typedef char DataType; #define MaxSize 100 typedef struct Node { DataType data; struct Node *lchild; struct Node *rchild; } *BiTree,BitNode;

树与图的简单遍历算法

树与图的简单遍历算法 发表时间:2019-01-14T09:56:22.797Z 来源:《科技新时代》2018年11期作者:闵俊齐 [导读] 树与图是两种重要的数据结构,而树可以说是一种特殊的图,它的两两结点之间存在唯一简单路径。 重庆第二外国语学校重庆 400065 摘要:树与图是两种重要的数据结构,而树可以说是一种特殊的图,它的两两结点之间存在唯一简单路径。利用其特殊性质,人们创造了许多算法来处理数据结构问题和程序调用问题。而树与图的遍历算法也是数据结构中重要的算法之一。本文从树与图的概念出发,简单的介绍了树与图的主要存储方式,并重点对二叉树的简单遍历算法、哈夫曼树的生成和图的深度优先遍历及广度优先遍历做出了介绍。 关键词:数据结构;二叉树;图;遍历算法 1.树与图的概念 树是一种数据结构,是由n(n≥0)个结点构成的具有明显层次关系的有限集合。一棵树一般由一个根节点和若干个子结点构成。结点与结点之间具有明显的并列或层次关系,这种层次关系称为父子关系。在一棵树中,没有父结点的结点被称为根结点。树有几个重要的概念,以下做出简单的介绍——树的度:某个结点拥有的子树的数量称为这个结点的度,度为零的结点也叫做叶结点,而度不为零的结点叫做分支结点。树的深度:一棵树的根结点的层次为1,其他结点的层次是其父结点的层次加1。一棵树里最大的层次的值被称为这棵树的深度。树有无序树,有序树,二叉树等。其中二叉树是每个结点最多有两个子结点的树,每个结点的子树通常被称为“左子树”和“右子树”,故二叉树中每个结点的度的最大值为2,而又有左右之分,二叉树中结点的次序不能任意颠倒。除最后一层的叶结点没有子结点外,其余每一层的每个结点都具有两个子结点的二叉树称为满二叉树。如果存在一个深度为h的二叉树,它的除h层外其余各层(1~h-1)的结点数都达到了最大值,并且它的第h层的结点全部集中在树的左边,这种二叉树就被称为完全二叉树。完全二叉树是由满二叉树引申出来的,它是一种效率很高的数据结构。本文后部分将会介绍二叉树的简单遍历算法。 图由若干个顶点组成的有限非空集合和各个顶点的边构成,通常表示为G(V,E),其中G表示一个图,V是图G中顶点的集合,E是图G中边的集合。图数据结构主要研究形状和图形数据元素之间的关系。它必须反映数据所对应的元素之间的几何关系和拓扑关系。图依照边的方向可分为有向图和无向图。有向图由顶点和弧构成。弧有弧尾和弧头,带箭头的一边称为弧头。图结构与树结构相比较,图中的任意两个元素都有可能相关。而对某个结点而言,树下层可能有多个元素,上层只有能一个元素,复杂度比树大[1]。 2二叉树与图的储存方式 2.1二叉树的储存方式 二叉树有两种储存方式:顺序存储和链式存储。 顺序储存就是按照完全二叉树的结点层次顺序存储的一种只适用于完全二叉树的储存方式,且在最坏的情况下,k个结点的单支数却只需要长度的 -1的一维数据。这种储存需要一个完全连续地址,所以会占用许多的储存空间。 在二叉树中,每个结点信息一般都由一下几个部分构成:该结点的数据元素(Data)、指向左子树的指针(L child)和指向右子树的指针(R child)。利用指针,我们可以很好的存储二叉树。若使用二叉链表,每个结点的结构如图1(a)所示。一般可以(L,D,R)来表示。在三叉链表中,可表示每个结点的父结点,结构如图1(b)所示。一般可以(L,D,P,R)来表示[5]。链式储存不需要完全连续地址,节约储存空间[2]。 图2 3.二叉树的遍历算法及哈夫曼树的生成 3.1二叉树的遍历算法 遍历,是指用某种方法沿着某条路对每一个元素做一且仅一次访问,它是二叉树的重要运算之一。二叉树的主要有三种访问方式:先序遍历、中序遍历、后序遍历。具体实现过程如下:

算法习题

算法设计与分析试卷 一、填空题(20分,每空2分) 1、算法的性质包括输入、输出、确定性、有限性。 2、动态规划算法的基本思想就将待求问题分解成若干个子问题、先求解子问题,然后 从这些子问题的解得到原问题的解。 3、设计动态规划算法的4个步骤: (1)找出最优解的性质,并刻画其结构特征。 (2)递归地定义最优值。 (3)以自底向上的方式计算出最优值。 (4)根据计算最优值得到的信息,构造最优解。 4、流水作业调度问题的johnson算法: (1)令N1={i|ai=bj}; (2)将N1中作业依ai的ai的非减序排序;将N2中作业依bi的非增序排序。 5、对于流水作业高度问题,必存在一个最优调度π,使得作业π(i)和π(i+1)满足Johnson不等式min{bπ(i),aπ(i+1)}≥min{bπ(i+1),aπ(i)}。 6、最优二叉搜索树即是最小平均查找长度的二叉搜索树。 二、综合题(50分) 1、当(a1,a2,a3,a4,a5,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为∑ak(2<=k<=4)=20(5分) 2、由流水作业调度问题的最优子结构性质可知,T(N,0)=min{ai+T(N-{i},bi)}(1=sum){ sum=thissum; besti=i; bestj=j;} } return sum; } 4、设计最优二叉搜索树问题的动态规划算法OptimalBinarysearchTree? (15分) Void OptimalBinarysearchTree(int a,int n,int * * m, int * * w) { for(int i=0;i<=n;i++) {w[i+1][i]=a[i]; m[i+1][i]= 0;} for(int r=0;r

树的遍历算法(完美C语言)

二叉树的先序遍历: 递归算法: void PreorderTraverse(BTNode *T) { if (T!=NULL) { visit(T->data) ; /* 访问根结点*/ PreorderTraverse(T->Lchild) ; PreorderTraverse(T->Rchild) ; } } 非递归遍历: 设T是指向二叉树根结点的指针变量,非递归算法是: 若二叉树为空,则返回;否则,令p=T; ⑴访问p所指向的结点; ⑵q=p->Rchild ,若q不为空,则q进栈; ⑶p=p->Lchild ,若p不为空,转(1),否则转(4); ⑷退栈到p ,转(1),直到栈空为止。 ---------------------------------------------------------------------------------------------------------------------- #define MAX_NODE 50 void PreorderTraverse( BTNode *T) { BTNode *Stack[MAX_NODE] ,*p=T, *q ; int top=0 ; if (T==NULL) printf(“Binary Tree is Empty!\n”) ; else { do { visit( p-> data ) ; q=p->Rchild ; if ( q!=NULL ) stack[++top]=q ; p=p->Lchild ; if (p==NULL) { p=stack[top] ; top-- ; } } while (p!=NULL) ; } }

图的深度优先遍历算法课程设计报告

合肥学院 计算机科学与技术系 课程设计报告 2013~2014学年第二学期 课程数据结构与算法 课程设计名称图的深度优先遍历算法的实现 学生姓名陈琳 学号1204091022 专业班级软件工程 指导教师何立新 2014 年9 月 一:问题分析和任务定义 涉及到数据结构遍会涉及到对应存储方法的遍历问题。本次程序采用邻接表的存储方法,并且以深度优先实现遍历的过程得到其遍历序列。

深度优先遍历图的方法是,从图中某顶点v 出发: (1)访问顶点v ; (2)依次从v 的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v 有路径相通的顶点都被访问; (3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。 二:数据结构的选择和概要设计 设计流程如图: 图1 设计流程 利用一维数组创建邻接表,同时还需要一个一维数组来存储顶点信息。之后利用创建的邻接表来创建图,最后用深度优先的方法来实现遍历。 图 2 原始图 1.从0开始,首先找到0的关联顶点3 2.由3出发,找到1;由1出发,没有关联的顶点。 3.回到3,从3出发,找到2;由2出发,没有关联的顶点。 4.回到4,出4出发,找到1,因为1已经被访问过了,所以不访问。

所以最后顺序是0,3,1,2,4 三:详细设计和编码 1.创建邻接表和图 void CreateALGraph (ALGraph* G) //建立邻接表函数. { int i,j,k,s; char y; EdgeNode* p; //工作指针. printf("请输入图的顶点数n与边数e(以逗号做分隔符):\n"); scanf("%d,%d",&(G->n),&(G->e)); scanf("%c",&y); //用y来接收回车符. for(s=0;sn;s++) { printf("请输入下标为%d的顶点的元素:\n",s); scanf("%c",&(G->adjlist[s].vertex)); scanf("%c",&y); //用y来接收回车符.当后面要输入的是和单个字符有关的数据时候要存贮回车符,以免回车符被误接收。 G->adjlist[s].firstedge=NULL; } printf("请分别输入该图的%d条弧\n",G->e); for(k=0;ke;k++) { printf("请输入第%d条弧的起点和终点(起点下标,终点下标):\n",(k+1)); scanf("%d,%d",&i,&j); p=(EdgeNode*)malloc(sizeof(EdgeNode)); p->adjvex=j; p->next=G->adjlist[i].firstedge; G->adjlist[i].firstedge=p; } } 2.深度优先遍历 void DFS(ALGraph* G,int v) //深度优先遍历 { EdgeNode* p;

图的生成、图的遍历

数据结构B实验报告 一、实验内容 图的生成、图的遍历 二、实验目的 掌握图的基本存储结构 掌握图的相关算法 掌握图的两种遍历方法 三、功能 本实验要求实现以下功能: 1.以邻接矩阵或者邻接表作为存储结构建立一个无向图。 2.深度优先搜索该无向图,输出遍历序列。 3.广度优先搜索该无向图,输出遍历序列。

四、主要代码 #include #include using namespace std; enum Status{UNVISITED,VISITED,SUCCESS,OVER_FLOW, RANGE_ERROR, NOT_PRESENT, ENTRY_FOUND, UNDER_FLOW}; const int DEFAULT_SIZE = 30; const int DEFAULT_INFAULTY =99999; const int MaxSize = 50; template struct Node { ElemType data; Node*next; Node();//普通构造函数 Node(ElemType e, Node*link = NULL);//带形参的构造函数 }; template Node::Node() { next = NULL; } template Node::Node(ElemType e, Node*link) { data = e; next = link; } template class LinkQueue { protected: Node *front, *rear; // 队头队尾指针 public: LinkQueue(); virtual ~LinkQueue(); int GetLength() const; bool IsEmpty() const; void Clear(); Status DelQueue(ElemType &e); Status GetHead(ElemType &e) const; Status EnQueue(const ElemType e); };

贪心算法概论

贪心算法概论 贪心算法一般来说是解决“最优问题”,具有编程简单、运行效率高、空间 复杂度低等特点。是信息学竞赛中的一个有为武器,受到广大同学们的青睐。本 讲就贪心算法的特点作些概念上的总结。 一、贪心算法与简单枚举和动态规划的运行方式比较 贪心算法一般是求“最优解”这类问题的。最优解问题可描述为:有n个输入,它的解是由这n 个输入的某个子集组成,并且这个子集必须满足事先给定的条 件。这个条件称为约束条件。而把满足约束条件的子集称为该问题的可行解。这 些可行解可能有多个。为了衡量可行解的优劣,事先给了一个关于可行解的函数,称为目标函数。目标函数最大(或最小)的可行解,称为最优解。 a)求“最优解”最原始的方法为搜索枚举方案法(一般为回溯法)。 除了极简单的问题,一般用深度优先搜索或宽度优先搜索。通常优化方法为利用约束条件进行可行性判断剪枝;或利用目标函数下界(或上界),根据当前最 优解进行分枝定界。 b)其次现今竞赛中用的比较普遍的动态规划(需要满足阶段无后效性原则)。 动态规划主要是利用最最优子问题的确定性,从后向前(即从小规模向大规模)得到当前最优策略,从而避免了重复的搜索。 举例说明:求多段图的最短路径。

在图(1)中,我们省略了各线段的长度。 如果用回溯法,搜索树大致如下: 显然,上面的搜索有大量重复性工作。比如节点8、9、10到11的最短路分别被调用了9次,从节点5、6、7到节点11也分别搜索了3次。 如果先算出节点8、9、10到11的最短路,由于它与前面的点无关,因此最优值确定下来,再用它们求定节点5、6、7 到节点11 的最短路径。同理,再用节 点5、6、7 的最优值,来求节点2、3、4 优值。最后从节点2、3、4 推出1 到 11的最优值。显然复杂度大为降低。 当然,如果本题把简单搜索改为搜索+记忆化的方法,则就是得能动态规划的原理,本质上就是动态规划,只是实现的方法不同与传统的表格操作法。搜索+记忆化算法有其特有的特点,以后再讨论。 c)贪心算法则不同,它不是建立在枚举方案的基础上的。它从前向后,根据当前情况,“贪心地”决定出下一步,从而一步一步直接走下去,最终得到解。 假如上面的例子中,我们定下这样的贪心策略:节点号k%3= =1。则有图3:

算法分析与设计期末模拟试题

安徽大学2010-2011学年第1学期《算法分析与设计》 期末试题 押宝 (内部交流,非考试试题,学生自发交流创作,版权归作者testfudan@https://www.doczj.com/doc/ea5364681.html, 所有) 一、选择题(单选)(10*2’=20’) 1. 选择正确的组合对于 2112n +=( ) ①2()o n ② 2()O n ③2()n θ ④2()n Ω ⑤ 2()n ω A. ①③④ B. ②③④ C.③④⑤ D. ①⑤ 2. ①21()()n i i O n O n ==∑ ②2()()n O n O n = ③(log )()O n O n ? ④ 2.99993 ()n O n = ⑤2/lo g ()n n n ω=其中正确的有( ) A .5组 B.4组 C.3组 D.没有正确的 3. 2/102n n +=( ) A. 2()O n B.(2)n O C.2(2)n n O + D.2 ()o n 4. 211/n += ( )(我认为是比较不错的一道题,考试可能会出现相同的方法,用极限定义来做,最后一节课老师也讲过类似的方法) A. ()O n B.()o n C.()n Ω D.(1)O 5. 310lo g n = ( ) A.(log )O n n B. (log )O n C. 3()O n D. lo g ()n O n 6. 认真完成课后习题P5面的算法分析题1-6,里面也有我不会做的,可是有谁愿意讨论? 如果能够把以上的题目都能做对,应该就是掌握了。给自己一个奖励吧!答案(如有问题,联系我吧):1-5:BBBDB 6.做出来对对答案吧。 二、填空题 1.()2(/2)T n T n n =+????的一个渐进上界为 (答案:(log )O n n ,用迭代法) 2.()(/3)(2/3)()T n T n T n O n =++的一个渐进上界为 (答案:(log )O n n ,用递归树求解,不会的赶快看) 3.()9(/3)T n T n n =+的一个渐进紧致界为 (答案:2 ()n θ,采用迭代法或者采用主方法,不会的赶快看)

实验报告:图的存储结构和遍历

武汉东湖学院 实验报告 学院:计算机科学学院—专业计算机科学与技术2016年11月18日 1.实验目的 (1)了解邻接矩阵存储法和邻接表存储法的实现过程。 (2)了解图的深度优先遍历和广度优先遍历的实现过程。 2.实验内容 1.采用图的邻接矩阵存储方法,实现下图的邻接矩阵存储,并输出该矩阵 2.设计一个将第1小题中的邻接矩阵转换为邻接表的算法,并设计一个在屏幕上显示邻接表的算法 3.实现基于第2小题中邻接表的深度优先遍历算法,并输出遍历序列 4.实现基于第2小题中邻接表的广度优先遍历算法,并输出遍历序列

3.实验环境Visual C++ 6.0

4 .实验方法和步骤(含设计) 我们通过二维数组中的值来表示图中节点与节点的关系。通过上图可 知, 其邻接矩阵示意图为如下: V0 v1 v2 v3 v4 v5 V0 1 0 1 0 1 V1 1 0 1 1 1 0 V2 0 1 0 0 1 0 V3 1 1 0 0 1 1 V4 0 1 1 1 0 0 V5 1 1 此时的 “1 ” 表示这两个节点有关系,“ 0”表示这两个节点无关系 我们通过邻接表来在计算机中存储图时,其邻接表存储图如下:

5.程序及测试结果 #include #include int visited [6]; typedef struct { int a[6][6]; int n; }mgraph; typedef struct ANode { int adjvex; struct ANode *nextarc; }ArcNode; typedef struct Vnode { ArcNode *firstarc; }VNode; typedef VNode AdjList [6]; typedef struct { AdjList adjlist; int n; }ALGraph; void mattolist (mgraph g,ALGraph *&G) { int i,j; ArcNode *p; G=(ALGraph*)malloc(sizeof(ALGraph)); for(i=0;iadjlist[i].firstarc=NULL; for(i=0;i=0;j--) if(g.a[i][j]!=0) { p=(ArcNode*)malloc(sizeof(ArcNode)); p->adjvex=j; p->nextarc=G->adjlist[i].firstarc; G->adjlist[i].firstarc=p; } G->n=g.n; } void dispadj(ALGraph *G) { int i; ArcNode *p;

贪心算法的应用

从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。 我们看看下面的例子 例1 均分纸牌(NOIP2002tg) [问题描述] 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如 N=4,4 堆纸牌数分别为: ①9 ②8 ③17 ④6 移动3次可达到目的: 从③取 4 张牌放到④(9 8 13 10) -> 从③取 3 张牌放到②(9 11 10 10)-> 从②取 1 张牌放到①(10 10 10 10)。 [输入]:键盘输入文件名。 文件格式:N(N 堆纸牌,1 <= N <= 100) A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000) [输出]:输出至屏幕。格式为:所有堆均达到相等时的最少移动次数。 [输入输出样例] : 4 9 8 17 6 屏慕显示:3 算法分析:设a[i]为第i堆纸牌的张数(0<=i<=n),v为均分后每堆纸牌的张数,s为最小移到次数。 我们用贪心法,按照从左到右的顺序移动纸牌。如第i堆(0v,则将a[i]-v张纸牌从第I堆移动到第I+1堆; (2)若a[i]

图的遍历实验报告

实验四:图的遍历 题目:图及其应用——图的遍历 班级:姓名:学号:完成日期: 一.需求分析 1.问题描述:很多涉及图上操作的算法都是以图的遍历操作为基础的。试写一个程序,演示在连通的无向图上访问全部结点的操作。 2.基本要求:以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。 3.测试数据:教科书图7.33。暂时忽略里程,起点为北京。 4.实现提示:设图的结点不超过30个,每个结点用一个编号表示(如果一个图有n个结点,则它们的编号分别为1,2,…,n)。通过输入图的全部边输入一个图,每个边为一个数对,可以对边的输入顺序作出某种限制,注意,生成树的边是有向边,端点顺序不能颠倒。 5.选作内容: (1).借助于栈类型(自己定义和实现),用非递归算法实现深度优先遍历。 (2).以邻接表为存储结构,建立深度优先生成树和广度优先生成树,再按凹入表或树形打印生成树。 二.概要设计 1.为实现上述功能,需要有一个图的抽象数据类型。该抽象数据类型的定义为: ADT Graph { 数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。 数据关系R: R={VR} VR={ | v,w v且P(v,w),表示从v到w得弧,谓词P(v,w)定义了弧的意义或信息} } ADT Graph 2.此抽象数据类型中的一些常量如下: #define TRUE 1 #define FALSE 0 #define OK 1 #define max_n 20 //最大顶点数 typedef char VertexType[20]; typedef enum{DG, DN, AG, AN} GraphKind; enum BOOL{False,True}; 3.树的结构体类型如下所示:

贪心算法经典问题:活动安排,背包问题,最优装载,单源最短路径 Dijiksra,找零钱问题,多机调度

活动安排 public static int greedySelector(int [] s, int [] f, boolean a[]) { //s[]开始时间f[]结束时间 int n=s.length-1; a[1]=true; int j=1; int count=1; for (int i=2;i<=n;i++) { if (s[i]>=f[j]) { a[i]=true; j=i; count++; } else a[i]=false; } return count; } 背包问题 void Knapsack(int n,float M,float v[],float w[],float x[]) { Sort(n,v,w); //以每种物品单位重量的价值Vi/Wi从大到小排序 int i; for (i=1;i<=n;i++) x[i]=0; float c=M; for (i=1;i<=n;i++) { if (w[i]>c) break; x[i]=1; c-=w[i]; } if (i<=n) x[i]=c/w[i]; //允许放入一个物品的一部分 } 最优装载 void Loading(int x[], T ype w[], T ype c, int n) { int *t = new int [n+1]; //t[i]要存的是w[j]中重量从小到大的数组下标Sort(w, t, n); //按货箱重量排序 for (int i = 1; i <= n; i++) x[i] = 0; //O(n) for (int i = 1; i <= n && w[t[i]] <= c; i++) {x[t[i]] = 1; c -= w[t[i]];} //调整剩余空间 } 单源最短路径Dijiksra template void Dijikstra(int n, int v, Type dist[], int prev[], Type **c) { //c[i][j]表示边(i,j)的权,dist[i]表示当前从源到顶点i的最短特殊路径bool s[maxint]; for(int i= 1;i<=n; i++) { dist[i]=c[v][i]; s[i]=false;

算法分析与设计选修课-贪心算法应用研究

武汉理工大学 算法设计与分析论文题目:贪心算法应用研究 姓名:吴兵 学院:信息工程 专业班级:电子133 学号: 1409721303131 任课教师:张小梅

目录 摘要 (1) 1.绪论 (2) 2贪心算法的基本知识概述 (3) 2.1 贪心算法定义 (3) 2.2 贪心算法的基本思路及实现过程 (3) 2.3贪心算法的核心 (3) 2.4贪心算法的基本要素 (4) 2.5 贪心算法的理论基础 (6) 2.6 贪心算法存在的问题 (7) 3贪心算法经典应用举例 (8) 3.1删数问题 (8) 3.2 汽车加油问题 (10) 3.3会场安排问题 (12) 4.总结 (16) 5.参考文献 (17)

摘要 在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。贪心算法所作的选择可以依赖于以往所作过的选择,但决不依赖于将来的选择,也不依赖于子问题的解,因此贪心算法与其它算法相比具有一定的速度优势。如果一个问题可以同时用几种方法解决,贪心算法应该是最好的选择之一。本文讲述了贪心算法的含义、基本思路及实现过程,贪心算法的核心、基本性质、特点及其存在的问题。并通过贪心算法的特点举例列出了以往研究过的几个经典问题,对于实际应用中的问题,也希望通过贪心算法的特点来解决。 关键词:贪心算法最小生成树多处最优服务次序问题删数问题

邻接矩阵表示图,深度,广度优先遍历

*问题描述: 建立图的存储结构(图的类型可以是有向图、无向图、有向网、无向网,学生可以任选两种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。 1、邻接矩阵表示法: 设G=(V,E)是一个图,其中V={V1,V2,V3…,Vn}。G的邻接矩阵是一个他有下述性质的n阶方阵: 1,若(Vi,Vj)∈E 或∈E; A[i,j]={ 0,反之 图5-2中有向图G1和无向图G2的邻接矩阵分别为M1和M2: M1=┌0 1 0 1 ┐ │ 1 0 1 0 │ │ 1 0 0 1 │ └0 0 0 0 ┘ M2=┌0 1 1 1 ┐ │ 1 0 1 0 │ │ 1 1 0 1 │ └ 1 0 1 0 ┘ 注意无向图的邻接是一个对称矩阵,例如M2。 用邻接矩阵表示法来表示一个具有n个顶点的图时,除了用邻接矩阵中的n*n个元素存储顶点间相邻关系外,往往还需要另设一个向量存储n个顶点的信息。因此其类型定义如下: VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量 AdjMatrix arcs; // 邻接矩阵 int vexnum, arcnum; // 图的当前顶点数和弧(边)数 GraphKind kind; // 图的种类标志

若图中每个顶点只含一个编号i(1≤i≤vnum),则只需一个二维数组表示图的邻接矩阵。此时存储结构可简单说明如下: type adjmatrix=array[1..vnum,1..vnum]of adj; 利用邻接矩阵很容易判定任意两个顶点之间是否有边(或弧)相联,并容易求得各个顶点的度。 对于无向图,顶点Vi的度是邻接矩阵中第i行元素之和,即 n n D(Vi)=∑A[i,j](或∑A[i,j]) j=1 i=1 对于有向图,顶点Vi的出度OD(Vi)为邻接矩阵第i行元素之和,顶点Vi 的入度ID(Vi)为第i列元素之和。即 n n OD(Vi)=∑A[i,j],OD(Vi)=∑A[j,i]) j=1j=1 用邻接矩阵也可以表示带权图,只要令 Wij, 若或(Vi,Vj) A[i,j]={ ∞, 否则。 其中Wij为或(Vi,Vj)上的权值。相应地,网的邻接矩阵表示的类型定义应作如下的修改:adj:weightype ; {weightype为权类型} 图5-6列出一个网和它的邻接矩阵。 ┌∞31∞∞┐ │∞∞51∞│ │∞∞∞∞∞│ │∞∞6∞∞│ └∞322∞┘ (a)网(b)邻接矩阵 图5-6 网及其邻接矩阵 对无向图或无向网络,由于其邻接矩阵是对称的,故可采用压缩存贮的方法,

图的遍历操作实验报告

实验三、图的遍历操作 一、目的 掌握有向图和无向图的概念;掌握邻接矩阵和邻接链表建立图的存储结构;掌握DFS及BFS对图的遍历操作;了解图结构在人工智能、工程等领域的广泛应用。 二、要求 采用邻接矩阵和邻接链表作为图的存储结构,完成有向图和无向图的DFS 和BFS操作。 三、DFS和BFS 的基本思想 深度优先搜索法DFS的基本思想:从图G中某个顶点Vo出发,首先访问Vo,然后选择一个与Vo相邻且没被访问过的顶点Vi访问,再从Vi出发选择一个与Vi相邻且没被访问过的顶点Vj访问,……依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则回退到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点W,从W出发按同样方法向前遍历。直到图中所有的顶点都被访问。 广度优先算法BFS的基本思想:从图G中某个顶点Vo出发,首先访问Vo,然后访问与Vo相邻的所有未被访问过的顶点V1,V2,……,Vt;再依次访问与V1,V2,……,Vt相邻的起且未被访问过的的所有顶点。如此继续,直到访问完图中的所有顶点。 四、示例程序 1.邻接矩阵作为存储结构的程序示例 #include"" #include"" ertex); irstedge; irstedge; } } }//endwhile } //==========主函数=========== void main() { ALGraph *G; G=(ALGraph *)malloc(sizeof(ALGraph));

CreatALGraph(G); printf("Print Graph DFS: "); DFS(G); printf("\n"); printf("Print Graph BFS: "); BFS(G,3); printf("\n"); } 五、实验内容 1调试程序。设计一个有向图和一个无向图,任选一种存储结构,完成有向图和无向图的DFS(深度优先遍历)和BFS(广度优先遍历)的操作。 邻接矩阵作为存储结构的运行结果: 邻接链表作为存储结构的运行结果: 六、实验报告要求 画出你所设计的图,写出两种方法的遍历序列。

五大常用算法

五大常用算法之一:分治算法 分治算法 一、基本概念 在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。 二、基本思想及策略 分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。 分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。 如果原问题可分割成k个子问题,1

相关主题
文本预览
相关文档 最新文档