一、快排
1.002
void quick_sort(int l, int r) {
if (l >= r)
return;
swap(a[l], a[l + rand() % (r - 1)]);
int i = l, j = r, mid = a[l];
while (i < j) {
while (i < j && a[j] >= mid) j--;
swap(a[i], a[j]);
while (i < j && a[i] < mid) i++;
swap(a[i], a[j]);
}
quick_sort(l, i - 1);
quick_sort(i + 1, r);
}
2.自有模板
void qsort(int l,int r)//应用二分思想
{
int mid=a[(l+r)/2];//中间数
int i=l,j=r;
do{
while(a[i]<mid) i++;//查找左半部分比中间数大的数
while(a[j]>mid) j--;//查找右半部分比中间数小的数
if(i<=j)//如果有一组不满足排序条件(左小右大)的数
{
swap(a[i],a[j]);//交换
i++;
j--;
}
}while(i<=j);//这里注意要有=
if(l<j) qsort(l,j);//递归搜索左半部分
if(i<r) qsort(i,r);//递归搜索右半部分
}
二、第K大数
1.STL
nth_element,这个函数主要用来将数组元素中第k小的整数排出来并在数组中就位,随时调用,可谓十分实用。
函数语句:nth_element(数组名,数组名+第k小元素,数组名+元素个数)
那求第k大时呢?我们可以转化成求第n-k+1小,此时下标应该是n - k。
lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。
在从小到大的排序数组中,
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。
通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。
通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
在从大到小的排序数组中,重载lower_bound()和upper_bound()
lower_bound( begin,end,num,greater() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。
通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num,greater() ):从数组的begin位置到end-1位置二分查找第一个小于>num的数字,找到返回该数字的地址,不存在则返回end。
通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
三、求逆序对
1.002归并排序
void merge_sort(int l, int r) {
if (l == r)
return;
int mid = (l + r) >> 1;
merge_sort(l, mid);
merge_sort(mid + 1, r);
int i = l, j = mid + 1, k = l;
while (k <= r) {
if (j <= r && (i > mid || a[j] < a[i])) {
ans = ans + mid - i + 1;
b[k++] = a[j++];
}
else
b[k++] = a[i++];
}
memcpy(a + l, b + l, sizeof(int) * (r - l + 1));
}
总结
提示:哪有什么总结,洗洗睡吧。