分治就是从全局变成局部,逐渐缩小问题的规模,更加高效的解决问题的一种算法。
应用实例:
(1)快速排序:O(nlogn)
步骤:
1.找轴值
2.序列重新排列,小于轴值的放在前面,轴值放在中间,大于轴值的放在右边.
3.两边分别递归即可
inline void quick_sort(int left,int right){ int i=left,j=right,mid=a[(left+right)/2]; while(i<=j){ while(a[i]<mid) i++; while(a[j]>mid) j--; if(i<=j){ swap(a[i],a[j]); i++,j--; } } if(left<j) quick_sort(left,j); if(i<right) quick_sort(i,right); }
(2)归并排序:O(nlogn)
步骤:
1.把序列等分为两部分,分别递归
2.然后把它们归并起来
inline void merge_sort(int left,int right){ if(left==right) return; int mid=(left+right)/2,i,j,tmp=1; merge_sort(left,mid); merge_sort(mid+1,right); for(i=1,j=mid+1;i<=mid&&j<=right;){ if(a[i]>a[j]) c[tmp++]=a[j++]; else c[tmp++]=a[i++]; } if(i<=mid){ for(;i<mid;) c[tmp++]=a[i++]; } if(j<=right){ for(;j<=right;) c[tmp++]=a[j++]; } for(i=left;i<=right;i++) a[i]=c[i]; }
(3)求逆序对
逆序对定义:i<j但a[i]>a[j]
分析:暴力显然时间不允许,当我们在进行Merge_sort(归并排序)时,已经默认组成了多组逆序对。
分治把整个序列分成两部分,我们要的总逆序对数量=左半的+右半的。这两项可以慢慢递归求解,这就完成了大部分。最后合并,O(n)解决