数据结构实训总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
五、程序总结
通过此次实验,使我明白编程序就像盖房子,有两件事非常重要:一、根据客户的要求、客户对房子的定位设计好房子该如何建,这该有什么,那该有什么,即设计好房子的图纸,既要简洁美观又要实用;二,把图纸变成实实在在的房子。这需要点什么材料,先做什么,后做什么。反映到编程就是,给一个项目或客户需求,如何把它编程具有可操作性的系统说明书,如何从理论上实现这个项目,这需要较高的系统分析能力。然后具体的编写程序,这就要求较高的算法能力。
JLabel label=null;
Cursor c1=null,c2=null;
F(String s){//构造函数
super(s);
c1=Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);//默认指针
c2=Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);//手型指针
import java.util.Vector;
import javax.swing.*;
class F extends JFrame implements ActionListener,MouseListener,MouseMotionListener,ItemListener{
/**
*
*/
private static final long serialVersionUID = 1L;
2)东边的面板类
该类只是利用面板的布局作用,故不用单独定义。用户画无向图时需要的辅助信息有:结点的位置坐标,一个结点相对于另一个结点的距离、角度,连线的起点、终点。
于是,我们需要一个文本框供用户输入节点名称,记录节点个数,一个下拉列表供用户选择参照点,两个文本框显示未选点到参照点的距离和角度,两个下拉列表供用户选择起点和终点。
五、程序总结
这个算法给我的最大启发就是我们要充分利用已有的信息。比如对已经排好序的数据进行查找,如果只是平淡的顺序查找,就比二分查找的效率低很多。为什么?因为二分查找考虑并利用了这些信息。同样的理论还可以用来解释为什么快排就比冒泡来得快,排序说白了就是为每一个数找到一个它应该呆的位置。假如为1~10排序,冒泡排序说白了就是一开始先找最大值移到最上边,这没错,关键是次小值又从底部开始找,使以前做的许多移动又有一部分重复了。快排则是,我不管以前怎么着,8碰到5就得放5的右边这总没错吧,以后碰到合适的再移动,但8和5的相对移动不会再重复了。由此观之,消除程序中的重复工作是提高效率的关键,不过高效率的算法可不是长在树上的(说有就有的),比如二分搜索排序,即使看起来很简单,能想起来这么做却是非常不简单的。
box[2].add(Box.createHorizontalStrut(20));
数据结构实训
院(系):软件学院
专业年级:软件工程2009级
姓 名:李乾坤
学 号:091530108
指导教师:刘高原 讲师
2011年06月18日
查找排序
一、需求分析
对一组无序数据进行排序,找出排序后某一数据所在的位置。
二、概要设计略
三、详细设计略
四、算法分析
简单地说,冒泡法就是先找最小值,再找次小值……,快排则是在一次循环中使它们局部有序,多次循环,直至全部有序为止。二分查找充分利用了有序序列的特性,从某种意义上讲,二分查找侧重的不是比较两个数是不是相等,而是确定要查找的数的范围。
四、算法分析
本算法的关键是建立递归公式:m[i][j],m[n][j]
m(i,j)= max{m(i+1,j),m(i+1,j-wi)+vi} j>=wi
m[i][j]=
m(i+1,j) 0=<j<wn
m(n,j)=vnj>wi
m[i][j]=
0=<j<wi
算法的主要思路就是将这个公式程序化,所以说数学建模很重要。在这里我觉得最精华的倒不是算法实现,最重要的有两点:一、动态规划法的思维方式,这种解题方式可以说是递归迭代,也可以认为是建了一个表去记录已经完成的运算成果以方便后边使用,避免重复运算。二、是用一种间接的方式保存被选中的物品,也就是这个表(m(i,j)),没有这个表就没有这个算法。
}
Box basebox=Box.createVerticalBox();
Box box[]=new Box[11];
for(int i=0;i<11;i++){
box[i]=Box.createHorizontalBox();
}
list=new JComboBox[5];
for(int i=0;i<5;i++){
vector1=new Vector<Node>();
vector2=new Vector<Edge>();
recode=new Vector<Integer>();
text=new JTextField[5];
for(int i=0;i<5;i++){
text[i]=new JTextField(8);
center=new Center();
center.addMouseListener(this);
center.addMouseMotionListener(this);
con.add(center,BorderLayout.CENTER);
label=new JLabel("第1个结点名称:");

Main类程序入口
package LI;
public class Main {
public static void main(String args[]){
new F("最短路径问题");
}
}
主窗口F类
package LI;
import java.awt.*;
import java.awt.event.*;
JPanel east=null,south=null;
Center center=null;
JTextField text[]=null;
JComboBox list[]=null;
JButton edge=null,button=null,reset=null;
//int x,y,nodeNumber=0,edgeNumber=1000,
1)中间的面板类Center
因为有用户画图的需要,所以必须重写该类的paint方法。该类有两个任务:画结点(要标明结点名称)、画结点之间的连线(要标明结点距离)。因此该类对象在执行repaint方法前应该明确任务类型(画点还是画线),明确需要标明的串值,明确结点坐标,这也就明确了该类应具有的属性值和方法。
list[i]=new JComboBox();
}
list[0].addItem("原点(0,0)");
list[0].addItemListener(this);
Container con=getContentPane();
//color=பைடு நூலகம்on.getBackground();
con.setBackground(Color.cyan);//种花得柳,这样center显示出来了
我们在用户输入界面中建立两个向量对象,分别是结点类型和边类型,当新建一个结点和边时,添加到相应的向量中。
2.用户输入界面(F)
用户界面需要提供一个面板供用户画无向图,一个面板为用户提供画图时的结点坐标、距离、角度等辅助信息,一个面板供用户输入出发点和目的地。由此将主界面设计成中、东、南的BorderLayout布局。
int x,y, cx=0,cy=0;//参照点坐标
String string=null;
Vector<Node> vector1=null;//存储点类型的向量
Vector<Edge> vector2=null;//存储边类型的向量
Vector<Integer> recode=null;//取消上一步中存储点或边的序号
box[0].add(label);
box[0].add(Box.createHorizontalStrut(8));
box[0].add(text[0]);
box[1].add(new JLabel("结点位置:"));//
box[1].add(Box.createHorizontalStrut(130));
0-1背包问题(Bag)
一、需求分析
从若干个具有一定价值和质量的物品挑出一些放入具有容量限制的背包,使背包的所容纳物品的价值最大。
二、概要设计
三个面板类,用card布局依次显示
三、详细设计
1)第一个card负责设置背包容量和最大物品个数
2)第二个card负责输入物品名称、重量、价格
3)第三个card显示结果
此次试验,如果单纯的借鉴已有的弗洛伊德算法,那么最复杂的就不是算法实现,而是如何规范并获取用户输入的信息并将这些信息转换成算法需要的邻接矩阵。这实际上是一个更困难的问题,因为这直接影响了整个程序的结构。而算法反而居于次要的位置了,因为不管程序结构如何,你只要将弗洛伊德算法弄一个类放在那里即可。
经济学和历史上都认为,商品交换是现代文明的基础之一而不是商品生产。如何进行信息的交换也是编程的重要问题。很多时候是数据交换决定了该程序的架构,如何更好的表示信息、组织信息、处理信息实际上成为了程序的核心工作,也是编程人员应该培养的核心能力。算法设计对这样的能力要求也很高,如果你明白背包问题中如何表示已经选中的物品,你基本就了解了解决背包问题算法的一切。
五、程序总结
通过完成此次试验,对动态规划法感慨良多。0-1背包问题的本质就是判断一个物品该不该放到背包里,然而这种判断还依赖于其他物品的选择,比较方便的方法就是穷举法,判断所有可能的状况,但这样的效率就太低了。解决一问题总有一个量来衡量解决这个问题所需要做的最少工作,编程的一个目标就是如何是计算机的效率更好的逼近这个量。研究穷举法我们会发现有很多重复的运算,优化穷举法的重要思路就是利用动态规划法的思想:利用已有的成果以避免重复运算,未进行的运算可以以已进行的运算为基础。因此我们必须有一种信息的表示方式来说明这个运算已经进行过了,反映到数学上就是发现运算之间的迭代关系。
最短路径问题(LJ)
一、需求分析
为用户提供一种输入手段获得一个无向图(或邻接矩阵),出发点和目的地,通过一定算法得到出发点到目的地的最短路径,显示给用户。
二、概要设计
三、详细设计
1.数据类
1)结点类Node
此类负责记录结点信息:坐标(x,y),结点名称,结点序号
2)边类
此类负责记录结点之间连线的信息:起点序号,终点序号,起点和终点的距离
这就需要Center对象监听鼠标事件获取鼠标指针的位置,获取用户选择的参照点的位置坐标,由此得到未选点到参照点的距离和角度。获取用户选择的起点坐标和终点坐标,以此得到边的长度。
3)南边的面板类
该类只是利用面板的布局作用,故不用单独定义。我们需要两个下拉列表供用户选择最短路径的起点和终点,单击按钮获取最短路径。为了更加的人性化,我们提供取消上一步的功能。取消上一步的功能实现:程序中准备一个专门存储结点和边对象的序号的向量类,取消上一步时,获取最后一个序号,判断边类型和节点类型,根据该序号搜索节点向量和边向量,得到相应的属性,再用Center类对象的背景色将该对象重画一遍,覆盖原来的图形,即可得到取消上一步的效果。同时,在结点向量和边向量中去掉取消的结点对象或边对象。
3、算法类
我们从界面类获得了一个结点类型向量,一个边类型向量,最短路径的起点和终点。在该类的构造函数中我们边向量中的数据转换成一个邻接矩阵供Floyd算法使用
四、算法分析
假设有向图用邻接矩阵存储,另外设置一个二维数组A用于存放当前顶点之间的最短路径长度,分量A[i][j]表示当前顶点vi到顶点vj的最短路径长度。弗洛伊德的基本思想是递归产生一个矩阵序列A0,A1……Ak……An,其中Ak[i][j]表示从vi到顶点vj的路径上所经过的顶点编号不大于k的最短路径。换句话说Ak[i][j]表示,考虑过点K之后,点i到点j的最短距离。
我们再从另一个角度去理解。吃饭要一口一口的吃,解决问题的一个重要方法就是缩小问题规模。如何缩小问题规模是个大学问,我们解决问题一般都有两种方法论——递推和递归,递推在这里很明显需要大量的回溯,或者直接就是低效率的穷举法。如果从递归方面看,我们先假设一个最优的结果,然后再看背包容量减少后的最优结果,这样一直迭代。算法的设计是最费脑筋的,但是查看一个优秀的算法非常有助于培养人们灵活的思维方式。
相关文档
最新文档