快排
objectivec
复制代码
#include<stdio.h>
#include<stdlib.h>
void swap(int* a, int* b){
//地址传参
int tmp = *a;
*a = *b;
*b = tmp;
}
void quickSort(int* res, int l, int r){
//递归出口
if(l >= r){
return;
}
//找一个基准
int mid = l + ((r - l + 1) / 2);//上取整
int x = res[mid];
int i = l - 1; int j = r + 1;//循环一开始,先进行一次运算
//严格大小于,相等没意义
while(i < j){
do{
i++;
}while(res[i] < x);
do{
j--;
}while(res[j] > x);
if(i < j) swap(&res[i], &res[j]);
}
//分别递归处理两端
// quickSort(res, l, mid - 1);
// quickSort(res, mid, r);
//处理完之后,以i为分界!!!!!!!!!!!!
quickSort(res, l, i - 1);
quickSort(res, i, r);
}
int main(){
int n;
scanf("%d", &n);
int* res = malloc((n + 1) * sizeof(int));
int x;
for(int i = 0; i < n; i++){
scanf("%d", &x);
res[i] = x;
}
//直接快排
quickSort(res, 0, n - 1);//左闭右闭
for(int i = 0; i < n; i++){
printf("%d ", res[i]);
}
return 0;
}
objectivec
复制代码
#include<stdio.h>
#include<stdlib.h>
void swap(int* a, int* b){
int tmp = *a;
*a = *b;
*b = tmp;
}
void quickSort(int* res, int l , int r){
if(l >= r){
return;
}
int mid = l + ((r - l + 1) / 2);//上取整
int x = res[mid];
int i = l - 1; int j = r + 1;
while(i < j){
do{
i++;
}while(res[i] < x);
do{
j--;
}while(res[j] > x);
if(i < j) swap(&res[i], &res[j]);
}
quickSort(res, l, i - 1);
quickSort(res, i, r);
}
int main(){
int n, k;
scanf("%d %d", &n, &k);
int* res = malloc((n + 1) * sizeof(int));
int x;
for(int i = 0; i < n; i++){
scanf("%d", &x);
res[i] = x;
}
quickSort(res, 0, n - 1);
printf("%d", res[k - 1]);
return 0;
}
归并排序
objectivec
复制代码
#include<stdio.h>
#include<stdlib.h>
#define N 100010
int tmp[N];
void mergeSort(int* res, int l, int r){
if(l >= r){
return ;
}
int mid = l + ((r - l + 1) / 2);
//归并排序先变成最小粒度
mergeSort(res, l, mid - 1);
mergeSort(res, mid, r);
//递归合并
int p1 = l; int p2 = mid;
int p = 0;
while(p1 < mid && p2 <= r){
if(res[p1] < res[p2]){
tmp[p++] = res[p1++];
}else{
tmp[p++] = res[p2++];
}
}
while(p1 < mid){
tmp[p++] = res[p1++];
}
while(p2 <= r){
tmp[p++] = res[p2++];
}
//复制
for(int i = 0, j = l; i < p; i++, j++){
res[j] = tmp[i];
}
}
int main(){
int n;
scanf("%d", &n);
int* res = malloc((n + 1) * sizeof(int));
int x;
for(int i = 0; i < n; i++){
scanf("%d", &x);
res[i] = x;
}
mergeSort(res, 0, n - 1);
for(int i = 0; i < n; i++){
printf("%d ", res[i]);
}
return 0;
}
objectivec
复制代码
#include<stdio.h>
#include<stdlib.h>
#define N 100010
int tmp[N];
// int count = 0;
//数据最大量时,越界了
unsigned long long count = 0;
void mergeSort(int* res, int l, int r){
if(l >= r){
return;
}
int mid = l + ((r - l + 1) / 2);
mergeSort(res, l, mid - 1);
mergeSort(res, mid, r);
int p1 = l; int p2 = mid;
int p = 0;
while(p1 < mid && p2 <= r){
if(res[p1] <= res[p2]){
tmp[p++] = res[p1++];
}else{
// count += p2 - p1;
//应该是前半部分的P1后面都算,因为两半部分都是排好序的
count += (mid - p1);
tmp[p++] = res[p2++];
}
}
while(p1 < mid){
tmp[p++] = res[p1++];
}
while(p2 <= r){
tmp[p++] = res[p2++];
}
//复制
for(int i = 0, j = l; i < p; i++, j++){
res[j] = tmp[i];
}
}
int main(){
int n;
scanf("%d", &n);
int* res = malloc((n + 1) * sizeof(int));
int x;
for(int i = 0; i < n; i++){
scanf("%d", &x);
res[i] = x;
}
mergeSort(res, 0, n - 1);
// printf("%d", count);
printf("%llu", count);//数据类型变了之后,输入输出也需要改变
return 0;
}
堆排序
objectivec
复制代码
#include<stdio.h>
#include<stdlib.h>
int n, m;
void swap(int* a, int* b){
int tmp = *a;
*a = *b;
*b = tmp;
}
void down(int* res, int x){
int u = x; //记录下最小位置
if(2 * x <= n && res[2 * x] < res[x]) u = 2 * x;
if(2 * x + 1 <= n && res[2 * x + 1] < res[u]) u = 2 * x + 1;
if(u != x){
//需要调换
swap(&res[x], &res[u]);
//一旦有变化,就需要继续下沉
down(res, u);
}
}
int main(){
scanf("%d %d", &n, &m);
int* res = malloc((n + 1) * sizeof(int));
//堆排序中不用下标0!!!!!!!!记住
res[0] = 0;
int x;
for(int i = 1; i <= n; i++){
scanf("%d", &x);
res[i] = x;
}
//堆排序就是利用一维数组,存储完全二叉树,且保持性质,小根堆就要保持父节点不比子节点大
for(int i = n / 2; i >= 1; i--){
down(res, i);
}
//现在小根堆做好了,就只需要拿堆根节点
for(int i = 0; i < m; i++){
printf("%d ", res[1]);
swap(&res[1], &res[n]);
n--;
down(res, 1);
}
return 0;
}