排序

O(n²):   插入排序  ,  冒泡排序  , 选择排序.

O(nlgn):     快速排序,  堆排序   ,   归并排序

  高级排序:  希尔排序 ,   基数排序..


---------------------------------------------------------------------------------------------------------------------

插入排序<insert sort>(折半插入排序)

          [5 7 6 9 8 7 0 4]

[5]          7 6 9 8 7 0 4]

[5 7]          6 9 8 7 0 4]        拿出7,与有序逐一比较,插入

      ↘

[5 6 7]          9 8 7 0 4]       拿出6与有序逐一比较,插入

[5 6 7 9]          8 7 0 4]

            ↘

[5 6 7 8 9]          7 0 4]

            ↘↘

[5 6 7 7 8 9]          0 4]

   ↘↘↘↘↘

[4 5 6 7 7 8 9]          0 4]

[0 4 5 6 7 7 8 9]          4]

[0 4 4 5 6 7 7 8 9]                          

(折半插入排序,又称二分插入排序.跟插入排序一样,只不过比较插入的时候是用low,high的一半求middle来比较的


---------------------------------------------------------------------------------------------------------------------

希尔排序<shell>(插入排序优化版)

  [5 7 6 9 8 7 0 4]                   d=n/2=4   

  [4 4 0 5 7 6 9 8]                   a[0]的5与a[4]的8,a[8]的4成一组比较,a[1]与a[5]比较,a[2]与a[6]比较..

  [4 0 4 7 5 7 6 9 8]                   a[0]与a[2],a[4],a[6],a[8]成一组比较,a[1]与a[3],a[5],a[7].....

  [0 4 4 5 6 7 7 8 9]


---------------------------------------------------------------------------------------------------------------------

冒泡排序<bubble sort>(白色字体为加了监视哨的优化)

  [5 7 6 9 8 7 0 4]    

  0 [5 7 6 9 8 7 4 4]     最后交换的位置在a[1],下次得循环到下标1

  0 4 [5 7 6 9 8 7 4]     最后交换的位置在a[2],下次得循环到下标2

  0 4 4 [5 7 6 9 8 7]     最后交换的位置在a[3],下次得循环到下标3

  0 4 4 5 [6 7 7 9 8]     最后交换的位置在a[5],下次得循环到下标5

  0 4 4 5 6 [7 7 8 9]     最后交换的位置在a[8],下次得循环到下标8

 如果带有记录上一次交换的下标记录,这里可以结束了

  0 4 4 5 6 7 7 8 9

---------------------------------------------------------------------------------------------------------------------

快速排序<quick sort>

  [5 7 6 9 8 7 0 4]                       选出a[0]的5作为标准将数组分堆.

第一次分:

   4 [7 6 9 8 7 0 5]                      5和最后面比较,直到找到比自己小,就交换

   4 [5 6 9 8 7 0 ] 7                     5和最前面比较,直到找到比自己大,就交换

   4 0  [6 9 8 7 5] 7                     5和最后面比较,直到找到比自己小,就交换

   4 0  [5 9 8 7 4 ]6 7

   4 0 4 [9 8 7 5] 6 7

   4 04 [5 8 7] 9 6 7

  [4 0 4] 5 [ 8 7 9 6 7]                      以5分标准分两边

对5的前部分再来快速排序:

 0 4 4                                          以开头的4为标准分两边

对5的后部分再来快速排序:

7 [7 9 6 8]

7 7 [8 6] 9

7 7 6 [8] 9                                     以开头的8为标准分两边

         对8的前部分再快速排序:

                6 7 7                              以开头的7为标准

得到 0 4 4    6 7 7     8   9


感觉我这个序列对于快速排序来说还真是可惜了....在第一趟竟然没有碰头

---------------------------------------------------------------------------------------------------------------------

选择排序<select sort>

[5 7 6 9 8 7 0 4]  选出最小0,  a[0]的5与0位置交换

0 [7 6 9 8 7 5 4]  选出最小4,  a[1]的74位置交换

4 [6 9 8 7 7 5 4]   ...

4 4 [9 8 7 7 5 6]

4 4 5 [8 7 7 9 6]

4 4 5 6 [7 7 9 8]

4 4 5 6 7 [7 9 8]

4 4 5 6 7 7 [9 8]

4 4 5 6 7 7 8  9]


---------------------------------------------------------------------------------------------------------------------

堆排序<heap sort>

[5 7 6 9 8 7 0 4]...

建成小栈堆  这个堆的序列是[04 5 4 8 7 6 97]


取走0(顶元素),用最后一个替上,变成,失去小栈堆的平衡,再变:

取走4(顶元素),用最后一个替上,变成,失去小栈堆的平衡,再变:

取走4(顶元素),用最后一个替上,,失去小栈堆的平衡,再变:

取走5,用7替上......................................


最后得到序列[0 4 4 5 6 7 78 9]


---------------------------------------------------------------------------------------------------------------------

归并排序<merge sort>

[5 7 6 9 8 7 0 4]                                          

[5 7 6 9] [8 7 0 4]                                        对半分组

[5 7] [6 9] [8 7] [0 4]                                    对半分组

[5] [7] [6] [9] [8] [7] [4] [0] [4]                          对半分组

[5 7] [6 9] [7 8] [0 4]  [4]                                 5,7排序/6,9排序/8,7排序//4,0排序        

[5 6 7 9] [0 7 8] [4]                                      指针a指向第一组第一个指针,b指向第二组第一个.(例如a指向[5,7]的5,b指向[6,9]的6)然后两指针比较

[0 5 67 8 9] [4]                                         指针小的进组,然后指向下一个继续比较(5进组,a指向下一个.就是7,b还是指向6,比较,6进组,b指向9)

[0 44 5 6 7 8 9]                                           同上直到成为一个数组,就排好了.稳定的哦.


---------------------------------------------------------------------------------------------------------------------

基数排序<radix sort>

[576 984 704 544 601 435 104 348 343]

先按个位,将大家分到各个位置.

0|||   

1|||   601

2|||

3|||   343

4|||   984   704   544   104

5|||   435

6|||   576

7|||

8|||   348

9|||

得到[601 343 984 704 544 104 435 576 348]

按十位,

0|||   601   704   104

1|||   

2|||

3|||   435

4|||   343   544   348

5|||

6|||

7|||   576

8|||   984

9|||

得到[601 704 104 435 343 544 348 576 984]

按百位,

0|||

1|||   104

2|||

3|||   343   348

4|||   435

5|||   544   576

6|||   601

7|||   704

8|||

9|||   984

得到[104 343 348 435 544 576 601 704 984]


---------------------------------------------------------------------------------------------------------------------

时间复杂度:

插入排序:

最好时间O(n)...

[1 2 3 4 5 6 7 8 9]. 取出1,[1] 和[2 3 4 5 6 7 8 9].取出2,比较得[1 2]和[3 4 5 6 7 8 9].取出3,比较,插入得出[1 2 3]和[4 5 6 7 8 9]..............每次跟最后一个比较,比它大即插入,只要9次.


最坏时间O(n²)..

.[9 8 7 6 5 4 3 2 1] 取出9.....取出8,比较,9移位.得到[8 9][7 6 5 4 3 2 1]..取出7,比较9,比较8.然后移位.比较2次,移位2次...取出6,比较3次,移位3次//取出1,比较8次,移位8次.


平均时间O(n²)



希尔排序:

最好时间O(n(logn))

[1 2 3 4 5 6 7 8]          第一趟1和5,2和6,3和7,4和8....比较8次..第二趟1,3,5,7//2,4,6,8...比较8次. 第三趟[123456789] 8次~~其实具体要多少趟呢,反正最后一定是分到为1.假设为X趟吧.......

                                                                                              然后最好时间是有序,所以每趟最快为比较n次..所以总时间就是nlogn


最坏时间O(n的s次方)  s接近2.                    

希尔排序是比插入排序快的,所以时间复杂度<o(n²) .最坏情况第一趟也只是比较n +6次.第二趟因为有第一趟的基础已经初步有序了,最坏情况大于n次小于²次..第三趟有了第二趟的基础......

平均时间                   经验所得



冒泡排序:

最好时间O(n)     

[1 2 3 4 5 6 7 8 9]     设置了记录最后一次交换的监视哨,扫了一遍,监视哨为末尾,即下一次直接可结束

 最坏时间O(n²)   

没有设置监视哨或者遇到这种情况[9 8 7 6 5 4 3 2 1] ...的确是n²呢


快速排序:

最好时间O(nlogn)

[4 1 3 2 6 5 7 8]→[2  1  3] 4 [ 6 5 7 8]

[2  1  3]→[1] 2 [3]

 [ 6 5 7 8]→[5] 6 [ 7 8 ]

第一次,取4,从最后往前扫描寻找比自己小的数来交换,扫描了4次(n/2)得到中间位置,然后从前面往后面扫面寻找比自己大的数交换,结果在中间碰头了,结束一轮排序.

第二轮,2取得中间位置.同时6也取得中间位置.也都是一下子碰头

排序完毕.... 1  2  3  4  5  6  7  8  

最快排序就是每次都成功将他分开各一半.

像上面的,8个数可以是,就是三轮就可以解决.每次扫描n次



最坏时间O(n²)      

 [66 6 6 66 6 6]   这样每个数为标准都得对其他数扫一次......第一次,对6比较,假如代码是小于才交换,即对666666 都要扫一次,发现没有,比起小,于是确认6一个.后面的同理,比较次数7+6+5+4+3+2+1

假如代码是小于等于就交换,第一次以6为标准,跟6比较,交换,然后跟6比较,又交换,然后跟6比较,交换....变成[6666]6 [666],第一趟就比较了7次,交换7次了..后面就不说了..


平均时间O(nlogn)                    

可以说快速排序是基本最快的排序方法~虽然不稳定


选择排序  

最好时间&最坏时间&平均时间:都是O(n²)   

就算是[1 2 3 4 5 6 7 8]..第一趟也要比较1,2,3,4,5,6,7,8里面谁最小,1最小,放在最前..第二趟比较2,3,4,5,6,7,8谁最小......最简单的排序方法


归并排序  

最好时间&最坏时间&平均时间:都是O(nlogn) 

就算是[8 7 6 5 4 3 2 1] 会分成[8 7 6 5] [4 3 2 1],再变成[8 7] [6 5] [4 3] [2 1]最后[8][7][6][5][4][3][2][1]

合成先是[7 8][5 6][3 4][1 2],然后[5 6 7 8][1 2 3 4]..最后[1 2 3 4 5 6 7 8]

 分解的次数是3次,就是2³=8啦,时间度是logn,插入的时间是O(n),因为已经基本有序,两个指针比较分别插入就OK了.所以总体是O(nlogn)


他的速度仅次于快速排序,但是优势是,它是稳定排序.

至于为啥说还是快速排序快点呢,它们不都是nlogn吗?这个很容易看的,logn大家基本是一样的吧,快速排序是把序列以头个数为标准分成前后两部分,直接到前后两部分为0或1....而归并排序则是不断无脑二分到为一为止.

但是n就不同了,归并排序的n,必须是n,因为要把两组数里面的数全插入去,比如[4 6][5 7],这里n是4,插入4次嘛~~~快速排序则只需要n-1哦,比如[8 7 6 9 5]这5个数以8为标准比较4次就OK了.


堆排序      

最好时间&最坏时间&平均时间:都是O(nlogn)    

n个数,那么作为二叉树来说,它的高度最多是log(2)n...比如3个节点,高度只能为1~对于根节点,他最多就移动到叶子的位置,也就是移动了logn次.对于第一层                             的两个节点,最多就移动logn-1次

                           

这个是初始建堆的时间,总之是O(n)就对了,初始堆已经是小(大)栈堆,然后调堆时最多只需要移动logn次就OK了,因为基本有序而且高度最多                                                            是logn..就这样循环n/2次就可以了

基数排序     

n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值