当前位置: 首页 > news >正文

洛谷P1177【模板】排序:十种排序算法全解(1)

扯谈

之前我已经把十大排序算法全讲了一遍(具体详见专栏C++排序算法),今天我们来用一道简单的题目总结实战一下。


算法实现

一、桶排序(Bucket Sort)

适用场景‌:数据范围已知且较小(需根据测试数据调整偏移量)

// Java
import java.io.*;
public class Main {static final int OFFSET = 100000;public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));int n = Integer.parseInt(br.readLine());int[] cnt = new int[200001];String[] strs = br.readLine().split(" ");for (int i = 0; i < n; i++) cnt[Integer.parseInt(strs[i]) + OFFSET]++;StringBuilder sb = new StringBuilder();for (int i = 0; i <= 200000; i++) while (cnt[i]-- > 0) sb.append(i - OFFSET).append(" ");System.out.println(sb);}
}
# Python
n = int(input())
nums = list(map(int, input().split()))
offset = 10**5
cnt = [0] * (2*10**5 +1)
for num in nums:cnt[num + offset] +=1
res = []
for i in range(len(cnt)):while cnt[i] >0:res.append(str(i - offset))cnt[i] -=1
print(' '.join(res))
// C
#include <stdio.h>
#define OFFSET 100000
int cnt[200001];
int main() {int n, x;scanf("%d", &n);for(int i=0; i<n; ++i) {scanf("%d", &x);cnt[x + OFFSET]++;}for(int i=0; i<=200000; ++i)while(cnt[i]--) printf("%d ", i - OFFSET);return 0;
}
// C++
#include <iostream>
using namespace std;
const int OFFSET = 1e5;
int cnt[200001];
int main() {ios::sync_with_stdio(false);int n, x;cin >> n;for(int i=0; i<n; ++i) {cin >> x;cnt[x + OFFSET]++;}for(int i=0; i<=200000; ++i)while(cnt[i]--) cout << i - OFFSET << " ";return 0;
}

二、基数排序(Radix Sort)

支持正负数处理

// Java
import java.io.*;
public class Main {static final int RADIX = 10;public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));int n = Integer.parseInt(br.readLine());String[] strs = br.readLine().split(" ");int[] arr = new int[n];for (int i = 0; i < n; i++) arr[i] = Integer.parseInt(strs[i]);// 分离正负数int posCount = 0;for (int num : arr) if (num >= 0) posCount++;int[] negs = new int[n - posCount];int[] poss = new int[posCount];int ni = 0, pi = 0;for (int num : arr) {if (num < 0) negs[ni++] = -num;else poss[pi++] = num;}// 排序负数if (negs.length > 0) radixSort(negs);// 排序正数if (poss.length > 0) radixSort(poss);// 合并结果StringBuilder sb = new StringBuilder();for (int i = negs.length - 1; i >= 0; i--) sb.append(-negs[i]).append(" ");for (int num : poss) sb.append(num).append(" ");System.out.println(sb);}static void radixSort(int[] arr) {int max = 0;for (int num : arr) if (num > max) max = num;for (exp = 1; max / exp > 0; exp *= 10) countingSort(arr, exp);}static void countingSort(int[] arr, int exp) {int[] output = new int[arr.length];int[] count = new int[RADIX];for (int num : arr) count[(num / exp) % RADIX]++;for (int i = 1; i < RADIX; i++) count[i] += count[i - 1];for (int i = arr.length - 1; i >= 0; i--) {int digit = (arr[i] / exp) % RADIX;output[--count[digit]] = arr[i];}System.arraycopy(output, 0, arr, 0, arr.length);}
}
# Python
def radix_sort(arr):if not arr:return []max_num = max(map(abs, arr))exp = 1while max_num // exp > 0:counting_sort(arr, exp)exp *= 10return arrdef counting_sort(arr, exp):output = [0] * len(arr)count = [0] * 19  # 处理负数偏移for num in arr:index = (num // exp) % 10 + 9count[index] += 1for i in range(1, 19):count[i] += count[i - 1]for i in range(len(arr)-1, -1, -1):index = (arr[i] // exp) % 10 + 9output[count[index]-1] = arr[i]count[index] -= 1arr[:] = outputn = int(input())
arr = list(map(int, input().split()))
neg = [x for x in arr if x < 0]
pos = [x for x in arr if x >= 0]
radix_sort(neg)
radix_sort(pos)
neg = [-x for x in reversed(neg)]
print(' '.join(map(str, neg + pos)))
// C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RADIX 10void counting_sort(int arr[], int n, int exp) {int* output = (int*)malloc(n * sizeof(int));int count[19] = {0}; // 处理负数偏移for (int i = 0; i < n; i++) {int digit = (arr[i] / exp) % RADIX + 9;count[digit]++;}for (int i = 1; i < 19; i++) count[i] += count[i-1];for (int i = n-1; i >= 0; i--) {int digit = (arr[i] / exp) % RADIX + 9;output[--count[digit]] = arr[i];}memcpy(arr, output, n * sizeof(int));free(output);
}void radix_sort(int arr[], int n) {if (n == 0) return;int max_val = 0;for (int i = 0; i < n; i++) {int abs_val = abs(arr[i]);if (abs_val > max_val) max_val = abs_val;}for (int exp = 1; max_val/exp > 0; exp *= 10)counting_sort(arr, n, exp);
}int main() {int n;scanf("%d", &n);int* arr = malloc(n * sizeof(int));for (int i = 0; i < n; i++) scanf("%d", &arr[i]);// 分离正负数int neg_count = 0;for (int i = 0; i < n; i++) if (arr[i] < 0) neg_count++;int* negs = malloc(neg_count * sizeof(int));int* poss = malloc((n - neg_count) * sizeof(int));int ni = 0, pi = 0;for (int i = 0; i < n; i++) {if (arr[i] < 0) negs[ni++] = -arr[i];else poss[pi++] = arr[i];}radix_sort(negs, neg_count);radix_sort(poss, n - neg_count);// 合并结果for (int i = neg_count-1; i >= 0; i--) printf("%d ", -negs[i]);for (int i = 0; i < n - neg_count; i++) printf("%d ", poss[i]);return 0;
}
// C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;void counting_sort(vector<int>& arr, int exp) {vector<int> output(arr.size());int count[19] = {0}; // 负数偏移处理for (int num : arr) count[(num / exp) % 10 + 9]++;for (int i = 1; i < 19; i++) count[i] += count[i-1];for (int i = arr.size()-1; i >= 0; i--) {int digit = (arr[i] / exp) % 10 + 9;output[--count[digit]] = arr[i];}arr = output;
}void radix_sort(vector<int>& arr) {if (arr.empty()) return;int max_val = 0;for (int num : arr) max_val = max(max_val, abs(num));for (int exp = 1; max_val/exp > 0; exp *= 10)counting_sort(arr, exp);
}int main() {ios::sync_with_stdio(false);int n; cin >> n;vector<int> arr(n), negs, poss;for (int i = 0; i < n; i++) {cin >> arr[i];if (arr[i] < 0) negs.push_back(-arr[i]);else poss.push_back(arr[i]);}radix_sort(negs);radix_sort(poss);reverse(negs.begin(), negs.end());for (int num : negs) cout << -num << " ";for (int num : poss) cout << num << " ";return 0;
}

由于篇幅限制,剩余请详见洛谷P1177【模板】排序:十种排序算法全解(2),求关

相关文章:

  • 【java实现+4种变体完整例子】排序算法中【基数排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
  • Jsp技术入门指南【七】JSP动作讲解
  • Tracepoints for the VFS?
  • 通过docker create与export来分析诊断故障镜像
  • 8 编程笔记全攻略:Markdown 语法精讲、Typora 编辑器全指南(含安装激活、基础配置、快捷键详解、使用技巧)
  • day46——两数之和-输入有序数组(LeetCode-167)
  • PHP怎样连接MySQL数据库?
  • python函数之间嵌套使用yield
  • sqli-labs之Less-7 GET注入写shell
  • CPU与GPU之间的交互
  • 【C++】新手入门指南(上)
  • Linux-进度条小程序
  • webpack 中 chunks详解
  • 论文降重GPT指令-实侧有效从98%降低到8%
  • SQL注入相关知识
  • 【解决】torch引入过程中的ImportError: __nvJitLinkAddData_12_1, version libnvJitLink.so.12
  • 阿里云Clickhouse 冷热数据分层存储 实战记录
  • 递归下降 ll(1) 型文法 识别二元组文法分析
  • 从零开始学习 Lucene.Net:.NET Core 中的全文搜索与索引管理
  • [密码学基础]GMT 0002-2012 SM4分组密码算法 技术规范深度解析
  • 撤销逾千名留学生签证,特朗普政府面临集体诉讼
  • 白兰花香飘京城,上海文化体验项目点亮中华民族共同体之美
  • 抵制饭圈极端应援,发倡议书还不够
  • 工信部:加快推进6G技术研发等,前瞻布局和培育面向6G的应用产业生态
  • 融创中国披露二次境外债重组方案:总规模约95.5亿美元债全额转股权,孙宏斌部分受限股票6年内不得处置
  • 中国足协、中足联:对中超浙江队外援布彭扎不幸离世表示深切哀悼