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;
}
相关推荐
土司大王3 分钟前
LeetCode hot100——34.在排序数组中查找元素的第一个和最后一个位置:Java 二分模板、边界分析
java·算法·leetcode
Logic10134 分钟前
C语言/数据结构位运算题解:异或XOR找出飞行棋中的“独特颜色棋子“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
爱吃苹果的日记本1 小时前
数据结构第三课(时间复杂度)
数据结构·学习
罗西的思考1 小时前
机器人模型(WM / WAM / VLA)综合分析与对比:从「看」到「想」再到「做」
人工智能·算法·机器学习
Logic1012 小时前
C语言/数据动态规划题解:翻转一次子数组后的最大子数组和——四状态DP(O(n)时间O(1)空间)
c语言·数据结构·动态规划·时间复杂度·算法题·状态机dp·最大子数组和
小哈里3 小时前
【知识】从学科到实践:自然・工程・社科・人文|算法・研发・产品・品牌设计
程序人生·算法·产品·设计·工程
小π军3 小时前
最大重叠区间数量
数据结构·算法
镜像视界(浙江)科技有限公司3 小时前
《视频孪生之上:二维展示终结,三维空间计算重构城市逻辑》——跨摄像连续表达 × 三角测量厘米级定位 × 动态轨迹建模,构建新一代城市空间
大数据·人工智能·算法·矩阵·音视频·空间计算
a187927218314 小时前
【算法】双指针与滑动窗口(二):滑动窗口——吃进、判定、吐出
算法·leetcode·双指针·滑动窗口·原理·模板·算法讲解
铭哥的编程日记4 小时前
从一道 LeetCode Hard 到吃透一类题:加权区间调度「排序 + 二分 + DP」
算法·leetcode·职场和发展