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;
}
相关推荐
MM_MS2 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
独自破碎E2 小时前
【二分法】寻找峰值
算法
mit6.8243 小时前
位运算|拆分贪心
算法
ghie90903 小时前
基于MATLAB的TLBO算法优化实现与改进
开发语言·算法·matlab
恋爱绝缘体13 小时前
2020重学C++重构你的C++知识体系
java·开发语言·c++·算法·junit
wuk9983 小时前
VSC优化算法MATLAB实现
开发语言·算法·matlab
Z1Jxxx4 小时前
加密算法加密算法
开发语言·c++·算法
乌萨奇也要立志学C++4 小时前
【洛谷】递归初阶 三道经典递归算法题(汉诺塔 / 占卜 DIY/FBI 树)详解
数据结构·c++·算法
vyuvyucd4 小时前
C++引用:高效编程的别名利器
算法
鱼跃鹰飞5 小时前
Leetcode1891:割绳子
数据结构·算法