排序算法的动画演示程序设计

来源:互联网 发布:加油站hse矩阵培训表 编辑:程序博客网 时间:2024/04/30 11:43



(1)节点类

对于一个个独立的对象来说,它只知道自己本身的内容、属性,是没有顺序这个概念的。但是,当多个对象放在一起进行考察时,它们之间可能会形成一种结构,可以有位置关系,也就可以引入顺序的概念了。

所谓位置,在这个动画程序中我们用二维空间中的一个坐标点来表示。每一个对象都存在于这个二维空间中,因此也就都有一个坐标来表示它的位置属性。而且对于动画演示来说,所有的对象都必须是可视化的,因此,它们都应该有一个draw方法,每一个对象都知道该如何可视化它自己。

接下来,在引入顺序的概念后,我们需要明确什么叫顺序、什么叫有序?注意,这里的顺序和有序是两个不同的概念。顺序指的是空间位置的先后关系。只要对象处于空间中(这里指的是像上图所示的空间,就是对象排成一排的情况),它们之间就肯定有顺序,如上图所示。而有序指的是在空间位置上相邻的两个对象符合一定的排序标准(也就是排序后的顺序),比如,前一个位置的对象的值比后一个位置对象的值大,这时候我们就说这两个对象是有序的。

那么,如何判断对象之间是否有序呢?这就需要用到对象的“值”,每一个对象都应该有自己的“值”属性,一般用数字来表示,“值”可以表示不同的语义,如身高、年龄等等。有了“值”之后,就可以根据对象间值的大小来判断它们是否有序了。

先总结一下,一个对象需要有位置属性,也就是一个二维坐标点,同时,它还需要有一个“值”,用于比较大小,判定是否有序。另外,考虑到动画的需要,比如要移动一个对象的位置,这时,我们需要一个MoveTo方法来移动对象,同时,移动某个对象时,希望它有不同的显示,因此,可以用一个属性来描述对象是否被选中。如下图:



(2)算法类

当我们有了一个对象的数组Node[],其中下标可以表示对象间的空间位置关系,比如,01是位置相邻的。如下图:



在这里,有一点需要注意。对象数组中的每一个元素(如368231有两种位置关系:一个是根据它们的实际坐标决定的实际位置关系;另一个是根据Node[]数组下标表示。辨析好这两者的区别很重要(一个是给人看的顺序,一个是程序员眼中的顺序)。

首先,我们能看得到的是根据对象实际坐标决定的位置关系。这是对象的实际空间关系。但是,对于程序来说,根据坐标不能很方便地知道对象的顺序,因此我们的程序使用的是数组的下标来保存对象的位置顺序。如下图:



也就是说,当我们的程序要寻找两个位置相邻的对象时,它不是根据对象的实际坐标来决定的,而是根据数组的下标顺序来决定的。因此,我们必须要保证对象的实际位置关系和数组下标的对应关系是对应的。不能够出现在下标中是有序的而实际坐标位置却不是有序的情况。为了保证这种对应关系,在我们移动对象时(也就是改变对象的坐标),必须同时改变数组当中的对象指针。比如,当8236互换位置时,下标0的指针应该指向82,而下标1的指针应该指向36.

总的来说,对象是实际存在于空间中的,而数组的下标是对对象之间顺序的描述,当对象的空间位置改变时,对应的描述必须跟着修改。物理世界和信息世界必须是对应的,物理世界的运动改变会反应到信息世界当中。

接下来谈算法类。当我们有了一个对象数组之后,我们要做的就是要对它们进行排序。排序算法有很多种,这里只讨论不需要额外空间的in-place方法,就是只通过互换两个元素的位置这一种简单的操作来实现排序,可以执行多次互换操作。这里,一定要注意的是,在互换两个元素的过程中一定要注意前面所说的对应。在互换对象的坐标时,一定也要互换相应数组下标的对象引用。

In-place的排序算法的操作可以简单描述为:根据算法寻找到需要互换的两个对象然后交换这两个对象的位置。本来可以把它当作一个操作,但是因为要做的是一个动画演示,动画演示要求的是要用动画的方式来演示对象的位置互换。因此,将这个操作分解成两步:第一步是根据算法找到需要互换的两个对象;第二步是互换两个对象的位置。我们可以在这两步之间插入动画演示。算法类应该能提供以上两个操作。

算法类必须包含一个描述对象位置信息的数组,同时,它还必须提供两个操作:一个是给出需要互换的两个对象;而是交换给定位置的两个对象。算法类如下图:



其中,isDone是判断是否已经完成排序的询问函数。

(3)动画类

前面提到过在互换两个对象的位置时需要动画演示交换的过程。这里,我们单独设计一个类来负责动画的过程,所有与动画有关的策略都被封装在这个类当中。

这个类需要知道互换的两个对象,这可以从前面的算法类当中获得,所有决定需要互换两个对象的策略都包含在算法类当中,动画类不需要知道具体的过程。有了两个互换的对象之后,动画类就需要解决如何实现动画的问题。所谓动画可以理解为对象的位置缓慢的变化,可以用定时来实现,每一次定时都更新对象的位置坐标,当对象的坐标达到指定位置后就结束该过程。而定时的功能我们可以用线程的睡眠来实现,每隔一段时间唤醒一次进程,在更新一次对象位置后进行继续睡眠。 算法类如下图:



其中,isDone用来判断是否已经结束动画。Step函数用来执行一次位置更新。

(4)结尾

以上是三个设计的核心类,完整的uml类图如下:

但是上面的uml类图我是还没有实现的,我实现的是下图的类结构,它把算法策略放到了sort类当中。



其中sort类用于协调ArrayToBeSortedSwapAnimation两个类。上面的uml我已经用java具体实现了,用的是javaapplet

 

代码已经上传到资源,免费下载。

http://download.csdn.net/detail/apple0407/4899273

原创粉丝点击