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;
}
相关推荐
GGBondlctrl12 分钟前
【leetcode】递归,回溯思想 + 巧妙解法-解决“N皇后”,以及“解数独”题目
算法·leetcode·n皇后·有效的数独·解数独·映射思想·数学思想
武子康24 分钟前
大数据-276 Spark MLib - 基础介绍 机器学习算法 Bagging和Boosting区别 GBDT梯度提升树
大数据·人工智能·算法·机器学习·语言模型·spark-ml·boosting
武子康27 分钟前
大数据-277 Spark MLib - 基础介绍 机器学习算法 Gradient Boosting GBDT算法原理 高效实现
大数据·人工智能·算法·机器学习·ai·spark-ml·boosting
CodeOfCC31 分钟前
c语言 封装跨平台线程头文件
linux·c语言·windows
Andrew_Xzw1 小时前
数据结构与算法(快速基础C++版)
开发语言·数据结构·c++·python·深度学习·算法
momo卡1 小时前
MinGW-w64的安装详细步骤(c_c++的编译器gcc、g++的windows版,win10、win11真实可用)
c语言·c++·windows
超的小宝贝2 小时前
数据结构算法(C语言)
c语言·数据结构·算法
凤年徐4 小时前
【数据结构初阶】单链表
c语言·开发语言·数据结构·c++·经验分享·笔记·链表
木子.李3478 小时前
排序算法总结(C++)
c++·算法·排序算法