c语言闯算法--排序

快排

快速排序(模板)

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;
}

第k个数

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;
}
相关推荐
Mr.H01278 分钟前
快速排序的常见构思
数据结构·算法
mit6.82415 分钟前
背包dp|格雷码
算法
rit843249926 分钟前
基于MATLAB的PCA+SVM人脸识别系统实现
人工智能·算法
RTC老炮26 分钟前
webrtc降噪-NoiseEstimator类源码分析与算法原理
算法·webrtc
懒羊羊不懒@1 小时前
JavaSe—Stream流☆
java·开发语言·数据结构
不当菜鸡的程序媛2 小时前
Flow Matching|什么是“预测速度场 vt=ε−x”?
人工智能·算法·机器学习
sali-tec2 小时前
C# 基于halcon的视觉工作流-章58-输出点云图
开发语言·人工智能·算法·计算机视觉·c#
_OP_CHEN2 小时前
算法基础篇:(四)基础算法之前缀和
c++·算法·前缀和·蓝桥杯·acm·icpc·算法竞赛
_OP_CHEN2 小时前
算法基础篇:(五)基础算法之差分——以“空间”换“时间”
c++·算法·acm·icpc·算法竞赛·差分算法·差分与前缀和
DuHz2 小时前
霍夫变换和基于时频脊线的汽车FMCW雷达干扰抑制——论文阅读
论文阅读·物联网·算法·汽车·信息与通信·毫米波雷达