`

[转][心得] 对比一下数组排序算法效率

阅读更多
http://bbs.9ria.com/viewthread.php?tid=70573&extra=

一个让很多人纠结的问题--用什么排序算法好。还有什么稳定,非稳定的一堆问题。
今天闲着,拿几个算法测了一下,报个结果给大家。

首先先放出测试主文件代码,里面包括有冒泡、快速、插入、鸡W酒等排序
package
{
        import flash.display.Sprite;
        import flash.utils.getTimer;

        /**
         * 测试排序效率
         * @author pelephone
         */       
        public class SortTest extends Sprite
        {
                public function SortTest()
                {
                        var arr:Array = new Array(),i:int,j:int,t:Object,gt:Number;
                        for(i=0;i<9999;i++){
                                arr.push(int(Math.random()*9999));
                        }
                       
                        gt = getTimer();
//                        quickSort(arr,0,9999);
//                        arr.sort();
//                        bubbleSort(arr);
//                        cocktailSortArr(arr);
//                        insertionSortArr(arr);
                        trace("算法用时:",(getTimer()-gt),"毫秒");
                }
               
                /**
                 * 普通的冒泡排序
                 * @param arr
                 */
                private function bubbleSort(arr:Array):void
                {
                        var len:int = arr.length;
                        for (var i:int = 0; i < len; i++)
                        {
                                for (var j:int = i + 1; j < len; j++)
                                {
                                        if (arr[i] < arr[j])
                                        {
                                                var t:* = arr[i];
                                                arr[i] = arr[j];
                                                arr[j] = t;
                                        }
                                }
                        }
                }
               
                /**
                 * 冒泡排序优化
                 * @param arr
                 */
                private function bubblesSortPlus(arr:Array):void
                {
                        var end:int = arr.length -1;
                        while (end > 0)
                        {
                                var k:int = 0;
                                for (var i:int = 0; i < end; i++)
                                {
                                        if (arr[i] < arr[i + 1])
                                        {
                                                var t:* = arr[i];
                                                arr[i] = arr[i + 1];
                                                arr[i + 1] = t;
                                                k = i;
                                        }
                                }
                                end = k;
                        }
                }
               
                /**
                 * 插入排序
                 * @param arr
                 */
                private function insertionSortArr(arr:Array):void
                {
                        var i:int = 1;
                        var n:int = arr.length;
                       
                        for(i=1;i<n;i++) {
                                var temp:Number = arr[i];
                                var j:int = i - 1;
                               
                                while((j>=0) && (arr[j] > temp)) {
                                        arr[j+1] = arr[j]; 
                                        j--;
                                }
                               
                                arr[j+1] = temp;
                        }
                }
               
                /**
                快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。 
               
                步骤为: 
               
                1. 从数列中挑出一个元素,称为 "基准"(pivot), 
                2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分割之后,该基准是它的最后位置。这个称为分割(partition)操作。 
                3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 
               
                递回的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递回下去,但是这个演算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。 
                */                
                private function quickSort(arr:Array,low:int,high:int):void {
                        var i:int;
                        var j:int;
                        var x:int;
                       
                        if (low < high) { //这个条件用来结束递归
                               
                                i = low;
                                j = high;
                                x = arr[i];
                               
                                while (i < j) {
                                        while (i < j && arr[j] > x) {
                                                j--; //从右向左找第一个小于x的数
                                        }
                                        if (i < j) {
                                                arr[i] = arr[j];
                                                i++;
                                        }
                                       
                                        while (i < j && arr[i] < x) {
                                                i++; //从左向右找第一个大于x的数
                                        }
                                       
                                        if (i < j) {
                                                arr[j] = arr[i];
                                                j--;
                                        }
                                }
                               
                                arr[i] = x;
                                quickSort(arr, low, i - 1);
                                quickSort(arr, i + 1, high);
                        }
                }
                /** 
                选择排序是这样实现的: 
                1.首先在未排序序列中找到最小元素,存放到排序序列的起始位置 
                2.然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。 
                3.以此类推,直到所有元素均排序完毕。 
                */ 
                public function selectionSort(result:Array):Array {
                        var i:int = 0;
                        var j:int = 0;
                        var n:int = result.length;
                       
                        for (i = 0; i < n - 1; i++) {
                                var min:int = i;
                                for (j = i+1; j < n; j++) {
                                        if (result[j] < result[min]) {
                                                min = j;
                                        }
                                }
                                /* swap data[i] and data[min] */ 
                                var temp:Number = result[i];
                                result[i] = result[min];
                                result[min] = temp;
                        }
                       
                        return result;
                } 
               
                /**
                鸡尾酒排序,也就是定向冒泡排序, 鸡尾酒搅拌排序, 搅拌排序 (也可以视作选择排序的一种变形), 涟漪排序, 来回排序 or 快乐小时排序,
                是冒泡排序的一种变形。此算法与冒泡排序的不同处在于排序时是以双向在序列中进行排序。 
                */    
                public function cocktailSortArr(result:Array):Array {
                        var i:int = 0;
                        var n:int = result.length;
                        var top:int = n - 1;
                        var bottom:int = 0;
                        var swapped:Boolean = true;
                       
                        while(swapped) { // if no elements have been swapped, then the list is sorted
                                swapped = false;
                                var temp:Number;
                                for(i = bottom; i < top;i++) {
                                        if(result[i] > result[i + 1]) {  // test whether the two elements are in the correct order
                                                temp = result[i];// let the two elements change places
                                                result[i] = result[i + 1];
                                                result[i + 1] = temp;
                                                swapped = true;
                                        }
                                }
                                // decreases top the because the element with the largest value in the unsorted
                                // part of the list is now on the position top
                                top = top - 1;
                                for(i = top; i > bottom;i--) {
                                        if(result[i] < result[i - 1]) {
                                                temp = result[i];
                                                result[i] = result[i - 1];
                                                result[i - 1] = temp;
                                                swapped = true;
                                        }
                                }
                                // increases bottom because the element with the smallest value in the unsorted
                                // part of the list is now on the position bottom
                                bottom = bottom + 1; 
                        }
                       
                        return result;
                } 
        }
}
复制代码
为了让结果准些,我随机生成了9999长度的大数组进行排序
gt = getTimer();
//quickSort(arr,0,9999);     // 算法用时: 36 毫秒
//arr.sort();                        // 算法用时: 188 毫秒
//bubbleSort(arr);              // 算法用时: 8933 毫秒
//bubblesSortPlus(arr);      // 算法用时: 12382 毫秒
//cocktailSortArr(arr);         // 算法用时: 11150 毫秒
//insertionSortArr(arr);       // 算法用时: 4677 毫秒
trace(getTimer()-gt);


从结果看出,快速排序最快,比官方算法快四五倍,不过麻烦的是要输入两个参数。估计sort的内核也是快速排序。
对比一下,快速排序麻烦的是还要带两参数,而且快速排序只排数字数组。sort还可以排字符数组。对我而言,那100左右毫秒的差别肉眼没感觉~~我更多情况会选择sort
不过sort排序非稳定,这也让人纠结,需要稳定时还是得用快速排序。
其它的冒泡排序、插入排序不给力,一排序就等个十秒八秒的,谁受得了。不过冒泡易读,常用在一些简单的小数组,方便在中间做些特殊算法修改。

其它排序不测先了,没这么多时间,看到快速排序我效率我已眼亮。呵呵,待其它高人测吧。
分享到:
评论

相关推荐

    【排序结构5】 基于比较的内部排序总结

    冒泡排序是最简单的排序算法之一,它通过不断交换相邻的逆序对来逐步将大元素“冒泡”到数组的一端。时间复杂度为O(n²),不适合大规模数据排序。 2. 插入排序(Insertion Sort) 插入排序将每个元素插入到已排序的...

    分治算法合并排序.docx

    合并排序是一种基于分治策略的排序算法,它将数组分解成多个小数组,然后将这些小数组合并成有序的数组。 算法设计思想 该算法的设计思想是:首先将数组分解成多个小数组,然后将这些小数组合并成有序的数组。合并...

    算法设计实验报告堆排序代码

    【堆排序算法详解】 堆排序是一种高效的比较排序算法,其主要思想是利用堆这种数据结构进行数据的排序。堆是一个近似完全二叉树的结构,同时满足堆的性质:即父节点的键值总是大于或等于(在最大堆中)或小于或等于...

    2022年大一c语言数组实验心得.docx

    * 驾驭与数组有关的算法特殊是排序算法 二、试验内容 教材习题 P1527.2 三、算法流程图 四、程序清单 ```c include void main { int i, j, min, s, a[11]; printf("请输入数组"); for(i=1; i; i++) { ...

    数据结构快速排序算法实现

    ### 数据结构快速排序算法实现详解 #### 实验目标与背景 快速排序算法是计算机科学领域中一种非常高效且常用的排序算法,由英国计算机科学家托尼·霍尔(Tony Hoare)于1959年提出。它采用分治法策略来实现对数据...

    排序算法实验报告

    3. **未来方向**:可以在实验基础上进一步探索其他排序算法(如希尔排序、基数排序等)的性能表现,或者研究如何优化现有算法以提高效率。 通过本次实验,不仅巩固了理论知识,也锻炼了编程能力,对今后的学习和...

    分治算法实验(用分治法实现快速排序算法).pdf

    通过修改函数Partition,可以设计出采用随机选择策略的快速排序算法,实验结果表明,随机化的快速排序算法可以减少出现极端情况的次数,使得排序的效率提高了很多。 六、实验心得 本实验让我更深入地理解了快速...

    visual-c---6.0-各种排序的算法-报告及源程序.doc

    通过动态内存分配,利用指针避免了多次复制数组,确保了在相同的输入基础上进行不同排序算法的比较。同时,报告还引入了`clock()`函数来度量算法的运行时间,以及计数器来统计比较和交换的次数,以便评估各种算法的...

    算法心得 高效算法的奥秘原书第2版) .zip

    排序算法是计算机科学的基础,书中详细讲解了各种经典的排序算法,如冒泡排序、插入排序、选择排序、快速排序、归并排序和堆排序。它们各有优劣,在不同的场景下有不同的应用。例如,快速排序通常在平均情况下表现...

    算法导论、算法心得分析.zip

    算法心得分析则更偏重于实践应用和个人经验分享,通常会包含在实际编程中遇到的问题、解决策略以及对算法效率的深刻理解。 算法是计算机科学的灵魂,是解决问题的关键工具。在编程中,一个好的算法能够极大地提高...

    数据结构课程设计——排序

    在心得和总结部分,学生应分享自己在设计和实现过程中遇到的挑战、解决问题的策略以及对数据结构和排序算法更深层次的理解。 ### 五、源程序清单 最后,报告应附上所有实现排序算法的源代码,便于审阅者验证算法的...

    《算法设计与分析》实验报告:实验二(线性选择问题)

    本次实验旨在基于快速排序算法实现线性时间选择算法,并通过对比不同数据量的实验分析算法的时间复杂性。线性选择问题要求在给定的n个元素中找出第k小的元素,其中1≤k≤n。该问题的基本思想是对快速排序的改进,...

    实验八 排序技术的编程实现

    此外,熟练掌握不同排序算法的效率分析,有助于在实际问题中选择最适合的排序方法。 【实验代码分析】 提供的代码示例中包含了冒泡排序和快速排序的函数定义。冒泡排序使用了两层嵌套循环实现,快速排序则展示了...

    数据结构实验:排序实验

    - **三向切分快速排序**:实验中提到了`ThreeSortLeft`和`ThreeSortRight`,这可能是指三向切分快速排序,这种排序算法在处理有大量重复元素的数组时效率较高,它可以将数组分为小于、等于和大于基准元素的三个部分...

    算法心得:高效算法的奥秘

    1. **排序算法**:书中详细讲解了各种排序算法,如快速排序、归并排序、堆排序等。快速排序以其平均时间复杂度为O(n log n)而广受欢迎,而归并排序则在稳定性上有优势。了解这些算法的优缺点有助于我们在不同情境下...

    《编程之法:面试和算法心得2》算法心得

    ### 《编程之法:面试和算法心得2》算法心得 #### 第四章 查找匹配 本章节主要探讨了两种常见的查找技术:有序数组的查找和行列递增矩阵的查找。这两种查找方法不仅在面试中频繁出现,而且在实际开发过程中也具有...

    数据结构-排序-实验报告.doc

    掌握不同的排序算法可以帮助程序员根据特定场景选择最合适的排序方法,提高程序的运行效率。 5. 进一步学习: 除了插入排序和快速排序,还有许多其他排序算法,如冒泡排序、归并排序、堆排序等,它们各有优缺点。...

    堆排序总结 堆排序总结

    3. **重复上述步骤**:不断重复上述步骤,直到整个数组排序完成。 具体来说,堆排序的核心在于两个基本操作: - **初始化操作**:将数组 R[1..n] 构造成初始堆。 - **每趟排序操作**:将当前无序区的堆顶记录 R[1] ...

    C语言冒泡排序法心得

    冒泡排序是一种基础且经典的排序算法,尤其在C语言中被广泛用来教学和理解排序算法的基本原理。它的名字来源于在排序过程中,较小的元素如同气泡一样逐渐“浮”到数组的顶端。以下是对冒泡排序法的详细解析: 首先...

Global site tag (gtag.js) - Google Analytics