微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

快速排序算法的改进

快速排序在大量数据,数据随机分布,并且重复数据较少时,性能较好。

 

主要作了如下改进:

1、非递归实现,防止数据量大时栈溢出。

2、对于数据是全部相等时候的改进。

3、如果数据小于一定的数目,采用插入排序。

4、中间值的选择。

 

测试结果:

1、1000万个随机数据,各不相同。 

List<T>类的Sort()方法:1.3秒

List<T>类的Sort(Comparison<T> comparison)方法:6.2秒

自己写的算法:3.7秒

 

2、1000万个随机数据,有少量相同的元素。

List<T>类的Sort()方法:1.1秒

List<T>类的Sort(Comparison<T> comparison)方法:5.7秒

自己写的算法:2.7秒

 

3、1000万个随机数据,有大量相同的元素。

List<T>类的Sort()方法:0.8秒

List<T>类的Sort(Comparison<T> comparison)方法:5.3秒

自己写的算法:1.7秒

 

4、1000万个全部相同的数据。

List<T>类的Sort()方法:0.59秒

List<T>类的Sort(Comparison<T> comparison)方法:4.7秒

自己写的算法:0.42秒

 

非递归实现的快速排序算法:

namespace Sort
{
    /// <summary>
    /// 快速排序(非递归实现)
     2013年12月25日
    </summary>
    public class QuickSort
    {
        <summary>
         快速排序的非递归实现
        </summary>
        <param name="array">排序数组</param>
        static void Sort(int[] array)
        {
            int start = 0;
            int end = array.Length - 1int[] stackLeft = new [array.Length];
            int[] stackRight =  left;
             right;
            int index = ;

            SortUnit(array,start,end,out left,out right);

            if (left > start)
            {
                stackLeft[index] = start;
                stackRight[index] = left;
                index++;
            }

            if (right < end)
            {
                stackLeft[index] = right;
                stackRight[index] = end;
                index++while (index > )
            {
                index--;
                start = stackLeft[index];
                end = stackRight[index];

                if (end - start < 5)//排序算法执行到一定深度时,数组整体有序,局部无序,这时停止快速排序,后面将改用插入排序
                {
                    continue;
                }

                SortUnit(array,1)"> right);

                 start)
                {
                    stackLeft[index] = start;
                    stackRight[index] = left;
                    index++;
                }

                 end)
                {
                    stackLeft[index] = right;
                    stackRight[index] = end;
                    index++;
                }
            }

            InsertionSort(array);
        }end of Sort

         一次排序单元,完成此方法,数组分成三部分,左边的比key小,右边的比key大,中间的和key相等
        </param>
        <param name="start">排序起始位置<param name="end">排序结束位置<param name="left">当key存在相同元素时,完成排序后,中间部分的左边缘<param name="right">当key存在相同元素时,完成排序后,中间部分的右边缘private void SortUnit(int[] array,1)">int start,1)">int end,1)">out int left,1)"> right)
        {
            int mid = (start + end) / 2int _temp = array[start];
            array[start] = array[mid];
            array[mid] = _temp;
            int key = array[start];
            int[end - start + 1];存放原始数组中key右边的与key相等的元素的下标
            存放原始数组中key左边的与key相等的元素的下标
            int stackRightCount = int stackLeftCount = ;

            while (start < end)
            {
                while (start < end && array[end] >= key)
                {
                    if (array[end] == key)
                    {
                        stackRight[stackRightCount++] = end;把与key相等的元素的下标记录下来
                    }
                    end--;
                }
                if (start != end) array[start] = array[end];

                while (start < end && array[start] <=if (array[start] == key)
                    {
                        stackLeft[stackLeftCount++] = start;                    }
                    start++if (start != end) array[end] = array[start];
            }
            array[start] = key;

            把key右边的与key相等的元素放在key的右侧
             i;
            for (i = start + 1; i <= start + stackRightCount; i++)
            {
                if (array[i] !=int temp = array[i];
                    array[i] = array[stackRight[index]];
                    array[stackRight[index]] = temp;
                    index++;
                }
            }

            把key左边的与key相等的元素放在key的左侧
            index = for (i = start - 1; i >= start - stackLeftCount; i-- array[stackLeft[index]];
                    array[stackLeft[index]] =;
                }
            }

            right = start + stackRightCount + ;
            left = start - stackLeftCount - ;
        }end of SortUnit

         插入排序
        </summary>
        void InsertionSort( i,j;
             temp;
            for (i = 1; i < array.Length; i++)
            {
                temp = array[i];
                j = i - ;
                与已排序的数逐一比较,大于temp时,该数移后
                while (j >= 0 && array[j] > temp)
                {
                    array[j + 1] = array[j];
                    j--;
                }
                array[j +  temp;
            }
        }
    }
}

 

测试代码

using System;
 System.Collections.Generic;
 System.Linq;
 System.Windows.Forms;

 Sort
{
    partial  Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [] m_data;

         产生测试数据
        [] GetData()
        {
            if (m_data == null)
            {
                Random rnd = new Random();
                int count = 10000000int __max = 1000000;
                m_data = [count];
                for (int i = 0; i < count; i++)
                {
                    m_data[i] = rnd.Next(1,__max + );
                }
                return m_data.ToArray<int>();
            }
            else
            {
                ();
            }
        }

        void button1_Click(object sender,EventArgs e)
        {
            DateTime dt1 = DateTime.Now;
            =======================================================
            int[] array = GetData();
            List<int> list = array.ToList<();
            list.sort();
            =======================================================

            DateTime dt2 ========================================================
            array = GetData();
            list = array.ToList<();
            list.sort((a,b) => a - b);
            
            DateTime dt3 = GetData();
            QuickSort.sort(array);
            
            DateTime dt4 = DateTime.Now;

            判断排序前的数组和排序后的数组的元素是否匹配
            bool bl = ArrayComparison.compare(array,GetData());

            string t1 = dt2.Subtract(dt1).TotalMilliseconds.ToString();
            string t2 = dt3.Subtract(dt2).TotalMilliseconds.ToString();
            string t3 = dt4.Subtract(dt3).TotalMilliseconds.ToString();

            MessageBox.Show(t1 + "" + t2 + " + t3);
        }
    }
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐