【转载】史上最简单明了的快排算法讲解,感谢石世特

原文:http://www.cnblogs.com/TivonStone/archive/2011/12/01/2270800.html

太简单明了了!复制只为收藏

【快速排序】

快排的速度咋就这么快捏?查点资料看看~

image

基本思想是:通过一趟排序将要排序的书记局分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据小,然后递归。

soga。。再参考下别人的例子,这也叫挖坑填数+分治法

1.先挖出来一个数字作为base基准

2.从后向前找一个比这个数字小的数,填到这个坑里。j--

3.这个数字被挖走,留坑。再从前向后找一个比base大的数,填到这个坑。i++

4.重复2,3直到i,j重合

比如下面的例子,7个数字【初始条件 base=5; i=1; j=7】

5 3 1 2 7 9 4

=>【条件 base=5; i=1; j=7】

从j向i找<base的数字4,得到

4 3 1 2 7 9

=>【条件 base=5; i++=2; j=7】

从i向j找>base的数字7,得到

4 3 1 2 9 7

=>【条件 base=5; i=2; j--=6】

从j向i找<base的数字2

4 3 1 2 9 7

=>【条件 base=5; i++=3; j=6】

从i向j找>base的数字,木有=>【条件 base=5; i=3; j--=5】

从j向i找<base的数字2

4 3 1 2 9 7

这样,ij就重合了,于是坑=5,坑左边的比5小,坑右边的比5大

最后,以5为分界线,重复上面的操作,即迭代。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
 
namespace 快速排序算法
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i < 5; i++)
            {
                List<int> list = new List<int>();
                for (int j = 0; j < 200; j++)
                {
                    Thread.Sleep(1);
                    list.Add(new Random((int)DateTime.Now.Ticks).Next(0, 10000));
                }
                Console.WriteLine(" 第" + i + "次比较:");
                Stopwatch watch = new Stopwatch();
                watch.Start();
                var result = list.OrderBy(single => single).ToList();
                watch.Stop();
                Console.WriteLine(" 自带快速排序耗费时间:" + watch.ElapsedMilliseconds);
                Console.WriteLine("输出前是十个数:" + string.Join(",", result.Take(10).ToList()));
                watch.Start();
                result = QuickSort(list.ToArray<int>(),0,list.Count-1);
                watch.Stop();
                Console.WriteLine("我的快速排序耗费时间:" + watch.ElapsedMilliseconds);
                Console.WriteLine("输出前是十个数:" + string.Join(",", result.Take(10).ToList()));
                Console.WriteLine("----------------------------------------------------------");
            }
            Console.Read();
        }
 
        static List<int> QuickSort(int[] list, int left, int right)
        {
            if (left < right)
            {
                //Swap(list[left], list[(left + right) / 2]); //将中间的这个数和第一个数交换 参见注1
                int i = left, j = right, x = list[left];
                while (i < j)
                {
                    while (i < j && list[j] >= x) // 从右向左找第一个小于x的数
                        j--;
                    if (i < j)
                        list[i++] = list[j];
                    while (i < j && list[i] < x) // 从左向右找第一个大于等于x的数
                        i++;
                    if (i < j)
                        list[j--] = list[i];
                }
                list[i] = x;
                QuickSort(list, left, i - 1); // 递归调用
                QuickSort(list, i + 1, right);
            }
            return list.ToList<int>();
        }
    }
}</int></int></int></int></int>

image

则是结果。发现差不多,但是如果将list弄的再长点,又会有差距了。

冒泡的时间复杂度为: 0(n) - 0(n^2)

快排的时间复杂度为:

    平均复杂度: N(logN)

    最坏复杂度:  0(n^2)

原文地址:https://www.cnblogs.com/yanyuge/p/3543831.html