快面试了,回顾一下基础知识。。。。名字乱取的。不对的地方请指正,有问题请提出。Many 3KS

【排序分类】:

      交换排序: 包括冒泡排序,快速排序。

      选择排序: 包括直接选择排序,堆排序。

      插入排序: 包括直接插入排序,希尔排序。

      合并排序: 合并排序。

【冒泡排序VS快排】

image要达到冒泡的效果,我们就要把一组数字竖起来看,数字大的往下沉。

第一步:  我们拿40跟20比,不用交换。

第二步:  然后向前推一步,就是拿20跟30比,交换。

第三步:拿交换后的20跟10比,不用交换。

第四步:拿10跟50比,进行交换。

最后,我们经过一次遍历,把数组中最小的数字送上去了,看看,我们向目标又迈进了一步。

写个代码来测试下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i < 5; i++)
            {
                List list = new List();
                for (int j = 0; j < 2000; j++)
                {
                    Thread.Sleep(1);
                    list.Add(new Random((int)DateTime.Now.Ticks).Next(0, 10000));
                }
                Console.WriteLine("\n第" + i + "次比较:");
                Stopwatch watch = new Stopwatch();
                watch.Start();
                var result = list.OrderBy(single => single).ToList();
                watch.Stop();
                Console.WriteLine("\n快速排序耗费时间:" + watch.ElapsedMilliseconds);
                Console.WriteLine("输出前是十个数:" + string.Join(",", result.Take(10).ToList()));
                watch.Start();
                 result = BubbleSort(list);
                 watch.Stop();
                 Console.WriteLine("冒泡排序耗费时间:" + watch.ElapsedMilliseconds);
                 Console.WriteLine("输出前是十个数:" + string.Join(",", result.Take(10).ToList()));
                 Console.WriteLine("----------------------------------------------------------");
            }
            Console.Read();
        }

        static List BubbleSort(List list)
        {
            for (int i = 0; i < list.Count-1; i++)
            {
                for (int j = list.Count - 1; j>i ; j--)
                {
                    if(list[j-1]>list[j])
                    {
                        list[j - 1] = list[j - 1] ^ list[j];
                        list[j] = list[j - 1] ^ list[j];
                        list[j - 1] = list[j - 1] ^ list[j];
                    }
                }
            }
            return list;
        }
    }
}

image

冒泡的速度灰常不给力。


【快速排序】

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

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为分界线,重复上面的操作,即迭代。

 

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 list = new List();
                for (int j = 0; j < 200; j++)
                {
                    Thread.Sleep(1);
                    list.Add(new Random((int)DateTime.Now.Ticks).Next(0, 10000));
                }
                Console.WriteLine("\n第" + i + "次比较:");
                Stopwatch watch = new Stopwatch();
                watch.Start();
                var result = list.OrderBy(single => single).ToList();
                watch.Stop();
                Console.WriteLine("\n自带快速排序耗费时间:" + watch.ElapsedMilliseconds);
                Console.WriteLine("输出前是十个数:" + string.Join(",", result.Take(10).ToList()));
                watch.Start();
                result = QuickSort(list.ToArray(),0,list.Count-1);
                watch.Stop();
                Console.WriteLine("我的快速排序耗费时间:" + watch.ElapsedMilliseconds);
                Console.WriteLine("输出前是十个数:" + string.Join(",", result.Take(10).ToList()));
                Console.WriteLine("----------------------------------------------------------");
            }
            Console.Read();
        }

        static List 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();
        }
    }
}
image

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

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

快排的时间复杂度为:

    平均复杂度: N(logN)

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