哈夫曼数据压缩算法的实现及性能分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
不同排序算法的实现和性能比较
学院信息学院
专业计算机系统结构
姓名张凯歌
学号1201001179
指导教师岳昆(副教授)
一、引言 (3)
二、排序算法 (3)
三、算法实现及性能比较 (4)
附录 (9)
参考文献 (16)
一、引言
排序是日常生活和工作中的一个常见问题,其目的是将一组原本无序的数据元素(或记录)序列,按照人们所需要的顺序,排列成有规律的按关键字有序的序列。
在现实生活中,人们要用到排序。如:学生成绩往往需要按照成绩高低或按学号从前到后排序;在图书馆众多的图书中,需要按照各个学科将书籍归类;排队时从高到低的顺序排队等问题。同样,排序也是计算机程序设计中的一个非常重要的操作,在计算机软件设计中占有极其重要的地位。本文将对排序算法中直接插入排序、快速排序和简单选择排序三种算法的实现做一些研究。
二、排序算法
排序是计算机内部经常进行的一种操作,其目的是将一组无序的记录序列调整为有序的记录序列,其可分为内部排序和外部排序(这里我们所说的排序只指前者)。下面我们将对这五中算法进行简单介绍和分析,然后通过实验数据给出五种中算法的性能比较。
(1) 插入排序(insertion sort):插入排序的思想是将一组无序的元素(这里我们用正整数来代替)分别插入一个已经有序的的数组里,并保证插入后的数组也是有序的。当所有无序组的元素都插入完毕时,一个有序数组构造完成。数组n[1…r]为初始的一个无序数组(为了直观起见,我们这里设定数组从1开始,而不是0),则n[1]默认为只有一个元素的有序数组,n[2]插入只有n[1]构成的有序数组中,则此时有序数组的元素数量变为2。以此类推,到第i个元素时,前i-1个元素已经是有序的,此时只需将第i个元素插入到有序数组中并使之保持有序。如此直至最后一个元素插入完毕,整个插入排序完成。
(2) 冒泡排序(bubble sort):冒泡排序每遍历一次数组,便将最大的元素放到数组最后边。下次遍历将次大的元素放到数组倒数第二位,依次类推,直至将最小的元素放到最前边,此时冒泡排序完成。
(3) 堆排序(heap sort):堆排序与其他排序算法最大的区别是它依靠一种特殊的数据结构——堆来进行排序。堆是一种完全二叉树,并且根节点不大于左右子树中的所有节点(这里描述的是小根堆,大根堆的话情况恰好相反),n[i]<=n[2*i]&&n[i]<=n[2*i+1]。因此堆排序算法首先要将给出的无序数组构造成一个堆,然后输出根节点(最小元素),将剩余元素重新恢复成堆,再次输出根节点。依次类推,直至最后一个节点输出,此时堆排序完成。
(4) 合并排序(merge sort):这里的合并排序和下边要描述的快速排序都采用了分而治之的思想,但两者仍然有很大差异。合并排序是将一个无序数组n[1…r]分成两个数组n[1…r/2]与n[r/2+1…r],分别对这两个小数组进行合并排序,然后再将这两个数组合并成一个大数组。由此我们看出合并排序时一个递归过程(非递归合并排序这里不做讨论)。合并排序的主要工作便是“合并”,两个小规模数组合并成大的,两个大的再合并成更大的,当然元素比较式在合并的过程中进行的。
(5) 快速排序(quick sort):如上所述,快速排序也是采用了分而治之的思想,但与合并排序有所不同的是快速排序先“工作”(这里是分割或partition),再递归。快速排序的主要思想是保证数组前半部分小于后半部分的元素,然后分别对前半部分和后半部分再分别进行排序,直至所有元素有序。
三、算法实现及性能比较
这里我们通过c++语言来实现各种排序算法(源码见附录),程序运行环境为windows xp,所用编译器为vc++ 6.0。如图1所示
图1 windows xp操作系统
在程序中我们根据数据规模的不同产生不同的随机整型数组,然后分别让不同
的排序算法来进行从小到大的排序。这里需要注意的是:每种排序算法在相同的输入规模中原始无序数据都是一样的。例如五种排序算法要对长度为100的无序数组进行排序,它们所要排序的无序数组都是一样的,我们以此来保证实验的公正性。在这里我们认为比较次数是排序算法的主要操作,因此我们在每个排序算法中加入计数器来记录排序过程中的比较次数,以此来作为对算法性能分析的主要参数(排序时间作为辅助参数)。表1为在输入规模分别为100,1000,2000,5000,10000,100000时各个算法的元素比较次数。
表1 排序算法比较次数性能比较
为了直观起见,我们根据实验数据画出各种排序算法在不同输入规模下比较次数的变化趋势图如图2所示:
图2排序算法性能趋势图
由上图我们基本上看出插入排序和冒泡排序的比较次数随输入规模的呈非线性增长,而后三种排序方法——堆排序,合并排序,快速排序的比较次数随输入规模的增长基本呈线性变化趋势。因此我们在这里暂且将前两种排序归类为低效排序算法,而将后三种归类为高效排序算法。图3和图4更加清楚地显示了这两类算法的变化趋势。
图4插入与冒泡排序性能比较图
图5高效排序算法性能分析图
实验结果与我们对这五种算法的性能理论分析基本吻合:插入排序与冒泡排序的时间复杂度为O(n*n),而后三种排序算法的时间复杂度为O(nlogn)。图4还显示出虽然冒泡排序和插入排序的时间复杂度相同,但插入排序的性能仍然比冒泡排序好。
关于图5我们仍有一点要说明,就是从比较次数上看合并排序似乎是最高效
的算法,但我们知道快速排序才是排序算法中最快的算法,这里理论似乎和实验结果出现了矛盾。下面我们以算法执行的时间来进行辅助说明,如表2所示:
次数计数排序基数排序堆排序快速排序希尔排序直接插入排序冒泡排序
1 0.0000 0.0310 0.0470 0.0470 0.0310 14.7970 58.0930
2 0.0000 0.0470 0.0310 0.0470 0.0470 16.2500 53.3280
3 0.0000 0.0310 0.0310 0.0310 0.0310 14.4850 62.4380
4 0.0000 0.0320 0.0320 0.0470 0.0310 17.1090 61.8440
5 0.0000 0.0310 0.0470 0.0470 0.0310 16.9380 62.3280
6 0.0000 0.0310 0.0310 0.0470 0.0310 16.9380 57.7030
7 0.0000 0.0310 0.0470 0.0310 0.0310 16.8750 61.9380
8 0.0150 0.0470 0.0310 0.0470 0.0320 17.3910 62.8600
9 0.0000 0.0320 0.0470 0.0460 0.0310 16.9530 62.2660
10 0.0000 0.0470 0.0310 0.0470 0.0310 17.0160 60.1410
11 0.0000 0.0930 0.0780 0.0320 0.0310 14.6090 54.6570
12 0.0000 0.0310 0.0320 0.0310 0.0310 15.0940 62.3430
13 0.0000 0.0310 0.0310 0.0470 0.0310 17.2340 61.9530
14 0.0000 0.0320 0.0470 0.0470 0.0310 16.9060 61.0620
15 0.0000 0.0320 0.0320 0.0460 0.0320 16.7810 62.5310
16 0.0000 0.0470 0.0470 0.0620 0.0310 17.2350 57.1720
17 0.0150 0.0160 0.0320 0.0470 0.0310 14.1400 52.0320
18 0.0150 0.0160 0.0310 0.0310 0.0310 14.1100 52.3590
19 0.0000 0.0310 0.0320 0.0460 0.0320 14.1090 51.8750
20 0.0000 0.0310 0.0320 0.0460 0.0320 14.0780 52.4840
21 0.0150 0.0780 0.0470 0.0470 0.0310 16.3750 59.5150
22 0.0000 0.0310 0.0310 0.0470 0.0320 16.8900 60.3440
23 0.0000 0.0310 0.0310 0.0310 0.0310 16.3440 60.0930
24 0.0000 0.0310 0.0310 0.0470 0.0310 16.3440 60.5780
25 0.0000 0.0320 0.0470 0.0470 0.0470 16.3590 59.7810
26 0.0160 0.0470 0.0310 0.0470 0.0310 16.1250 61.0620
27 0.0000 0.0310 0.0470 0.0470 0.0310 16.7810 59.6100
28 0.0150 0.0320 0.0320 0.0470 0.0310 16.9220 56.8130
29 0.0000 0.0310 0.0310 0.0310 0.0310 15.0790 57.8120
30 0.0000 0.0310 0.0320 0.0460 0.0320 14.7810 58.8280
31 0.0000 0.0310 0.0310 0.0470 0.0310 15.8590 59.1400
32 0.0000 0.0470 0.0320 0.0310 0.0310 16.0940 59.1560
33 0.0000 0.0470 0.0310 0.0310 0.0310 15.9850 59.1400
34 0.0000 0.0310 0.0310 0.0470 0.0320 16.0150 59.2500
35 0.0000 0.0310 0.0470 0.0470 0.0310 16.7660 57.9840
36 0.0000 0.0310 0.0320 0.0470 0.0310 15.3750 59.0470
37 0.0000 0.0320 0.0460 0.0470 0.0320 16.0310 58.9060
38 0.0000 0.0310 0.0310 0.0470 0.0310 15.9530 57.2650
39 0.0160 0.0310 0.0470 0.0470 0.0310 15.9530 57.5160
40 0.0150 0.0310 0.0320 0.0470 0.0310 14.7030 56.6710