【数据结构第八周】排序(下)【快速排序】
步骤:
1、从数列中挑出一个元素,称为"基准"或者“主元”(pivot)
2、重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作
3、递归地把小于基准值元素的子数列和大于基准值元素的子数列排序
选主元的时候可以使用“取头、中、尾的中位数”这种方法。
如果你选取第一个元素作为主元,如果一个数列本身就是有序的,用这种办法产生的O(N^2)的复杂度显然是不能接受的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ElementType Median3( ElementType A[], int Left, int Right ) { int Center=(Left+Right)/2; if ( A[ Left ] > A[ Center ] ) { Swap( &A[ Left ], &A[ Center ] ); } if (A[ Left ] > A[ Right ]) { Swap( &A[ Left ], &A[ Right ] ); } if (A[ Center ] > A[ Right ] ) { Swap( &A[ Center ], &A[ Right ] ); } /* A[ Left ] <= A[ Center ] <= A[ Right ] */ Swap( &A[ Center ], &A[ Right-1 ] ); /* 将pivot藏到右边 */ /* 只需要考虑 A[ Left+1 ] ... A[ Right–2 ] */ return &A[ Right-1 ]; } |
对小规模的数据(例如N不到100)可能还不如插入排序快 。
解决方案:
当递归的数据规模充分小,则停止递归,直接调用简单排序(例如插入排序)
在程序中定义一个Cutoff的阈值
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 | void Quicksort( ElementType A[], int Left, int Right ) { if ( Cutoff <= Right-Left ) { Pivot = Median3( A, Left, Right ); i=Left; j=Right–1; for ( ; ; ) { while ( A[ ++i ] < Pivot ) { } while ( A[ ––j ] > Pivot ) { } if ( i < j ) { Swap( &A[i], &A[j] ); } else { break ; } Swap( &A[i], &A[ Right-1 ] ); Quicksort( A, Left, i-1 ); Quicksort( A, i+1, Right ); } } else { Insertion_Sort( A+Left, Right-Left+1 ); } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步