update sort
This commit is contained in:
+29
-15
@@ -18,7 +18,7 @@
|
||||
* 桶排序
|
||||
|
||||
|
||||
## 交换排序算法
|
||||
# 交换排序算法
|
||||
|
||||
排序算法的复杂度由 `比较的次数` 和 `交换的次数` 一起决定。
|
||||
|
||||
@@ -77,14 +77,18 @@
|
||||
|
||||
递归一次,pivot 左边都比它小,右边都比它大。这是递归,分治的思想。
|
||||
|
||||
> 快速排序就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历
|
||||
|
||||
对 A[p...r] :
|
||||
1. 分解:A[p..q-1] A[q+1..r],使得 A[p...q-1]<A[q]<A[q+1..r]
|
||||
|
||||
0. 选择最后一个元素作为 pivot (基准)
|
||||
1. 分解:A[p..q-1] A[q+1..r],使得 A[p...q-1]< A[q] <A[q+1..r]
|
||||
2. 解决:递归调用 快排,,对子数组A[p..q-1],A[q+1..r]排序
|
||||
3. 合并(子问题相互独立的,因此用分治算法就可以了)
|
||||
|
||||
具体步骤:
|
||||
|
||||
1. 从数列中选择一个元素,作为基准 pivot。通常取分区的第一个或最后一个
|
||||
1. 从数列中选择一个元素,作为基准 pivot。通常取分区的最后一个
|
||||
2. 重排数列,比 pivot 小得排左边,比pivot大的排右边,相等的随便。 一句话就是`挖坑填数`
|
||||
3. 递归的,使用相同的方式,重排左右两边的子序列
|
||||
|
||||
@@ -107,14 +111,16 @@
|
||||
int i=start,j=end;
|
||||
int tmp = a[i]; // 这里要做越界检查
|
||||
while(i<j){
|
||||
|
||||
// 从后向前扫描,找到第一个小于tmp的值,来填a[i]
|
||||
while(i<j && a[j]>=tmp){
|
||||
while(i<j && a[j]>=tmp){
|
||||
j--;
|
||||
}
|
||||
if (i<j)//找到了,这时候a[j]为坑
|
||||
{
|
||||
a[i++] = a[j];
|
||||
}
|
||||
|
||||
// 从左向右扫描,找一个大于 tmp的 数, 去填坑a[j]
|
||||
while(i<j && a[i]<tmp){
|
||||
i++;
|
||||
@@ -124,6 +130,7 @@
|
||||
a[j++]=a[i];
|
||||
}
|
||||
}
|
||||
|
||||
//扫描完成后,i==j
|
||||
a[i]=tmp;
|
||||
return i;
|
||||
@@ -133,10 +140,9 @@
|
||||
|
||||
|
||||
|
||||
平均复杂度 O(n*logn)
|
||||
最坏O(n^2)
|
||||
平均复杂度 O(n * logn)
|
||||
最坏 O(n^2)
|
||||
空间复杂度
|
||||
|
||||
快速排序是对冒泡排序的改进,划分交换排序。
|
||||
|
||||
|
||||
@@ -154,13 +160,21 @@
|
||||
2. 解决。 将各个子数组都排好序,然后 merge 2个有序数组
|
||||
3. 合并
|
||||
|
||||
if (length>1)
|
||||
{
|
||||
merge_sort(a,length/2);
|
||||
merge_sort(a+length/2,length-length/2);
|
||||
merge_array(a,length/2,a+length/2,length-length/2);
|
||||
}
|
||||
|
||||
归并排序的代码框架如下:
|
||||
|
||||
```
|
||||
void sort(int[] nums, int lo, int hi) {
|
||||
int mid = (lo + hi) / 2;
|
||||
sort(nums, lo, mid);
|
||||
sort(nums, mid + 1, hi);
|
||||
|
||||
/****** 后序遍历位置 ******/
|
||||
// 合并两个排好序的子数组
|
||||
merge(nums, lo, mid, hi);
|
||||
/************************/
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -239,7 +253,7 @@
|
||||
国外也有人通过舞蹈的方式编排了几种基本的排序算法,非常有趣。[点这里去看看](http://v.youku.com/v_show/id_XMzMyODk4NTQ4.html?from=s1.8-1-1.2)
|
||||
|
||||
|
||||
## 线性排序算法
|
||||
# 线性排序算法
|
||||
|
||||
上面的算法都是基于比较的排序,时间复杂度最好也是 NlogN.而非基于比较的排序,可以突破NlogN的时间下限。当然,非比较的排序,也是需要有一些限定条件的。
|
||||
|
||||
@@ -252,7 +266,7 @@
|
||||
|
||||
|
||||
|
||||
### 小结
|
||||
# 小结
|
||||
|
||||
常见的排序算法都是比较排序,比较排序的时间复杂度通常为 O(n^2) 或 O(nlogn)
|
||||
但是如果带排序的数字有一些特俗性时,我们可以根据这来设计更加优化的排序算法。
|
||||
|
||||
Reference in New Issue
Block a user