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;
}
相关推荐
2401_838472514 分钟前
C++中的访问者模式
开发语言·c++·算法
老鼠只爱大米10 分钟前
LeetCode经典算法面试题 #108:将有序数组转换为二叉搜索树(递归分治、迭代法等多种实现方案详解)
算法·leetcode·二叉树·二叉搜索树·平衡树·分治法
独自破碎E39 分钟前
【前缀和+哈希】LCR_011_连续数组
算法·哈希算法
一条大祥脚1 小时前
26.1.26 扫描线+数论|因子反演+子序列计数|树套树优化最短路
数据结构·算法
m0_561359671 小时前
基于C++的机器学习库开发
开发语言·c++·算法
星空露珠1 小时前
速算24点所有题库公式
开发语言·数据库·算法·游戏·lua
2401_832402751 小时前
C++中的类型擦除技术
开发语言·c++·算法
努力学习的小廉1 小时前
我爱学算法之—— 递归回溯综合(二)
开发语言·算法
sheji52611 小时前
JSP基于信息安全的读书网站79f9s--程序+源码+数据库+调试部署+开发环境
java·开发语言·数据库·算法
2301_763472461 小时前
C++网络编程(Boost.Asio)
开发语言·c++·算法