1. 快速排序
https://blog.youkuaiyun.com/yang_yi520/article/details/124967724
#include<iostream>
using namespace std;
void quickSort(int arr[], int begin, int end) {
if (begin >= end) return;
int left = begin;
int right = end;
int temp = arr[left];
while (left < right) {
//从后往前找比他小的放前面,从前往后找比它大的放后面
//以第一个数为基准,必须先从后往前走,再从前往后走
while (left < right && arr[right] >= temp) {
right--;
} //跳出此循环,代表right找到了比temp小的数字,所以此时arr[left]=arr[right]
if (left < right) {
arr[left] = arr[right];
}
while (left < right && arr[left] <= temp) {
left++;
}//同理
if (left < right) {
arr[right] = arr[left];
}
if (left == right) {
arr[left] = temp;
}
}
quickSort(arr, begin, left - 1);
quickSort(arr, left + 1, end);
}
int main() {
int arr[11] = { 5,6,3,2,7,8,9,1,4,0,0 };
quickSort(arr, 0, 10);
for (auto x : arr) {
cout << x << " ";
}
return 0;
}
2. 冒泡排序
void BubbleSort(vector<int>& v) {
int len = v.size();
for (int i = 0; i < len - 1; ++i)
for (int j = 0; j < len - 1 - i; ++j)
if (v[j] > v[j + 1])
swap(v[j], v[j + 1]);
}
改进
void BubbleSort_orderly(vector<int>& v) {
int len = v.size();
bool orderly = false;
for (int i = 0; i < len - 1 && !orderly; ++i) {
orderly = true;
for (int j = 0; j < len - 1 - i; ++j) {
if (v[j] > v[j + 1]) { // 从小到大
orderly = false; // 发生交换则仍非有序
swap(v[j], v[j + 1]);
}
}
}
}
3. 选择排序
void SelectionSort(vector<int>& v) {
int min, len = v.size();
for (int i = 0; i < len - 1; ++i) {
min = i;
for (int j = i + 1; j < len; ++j) {
if (v[j] < v[min]) { // 标记最小的
min = j;
}
}
if (i != min) // 交换到前面
swap(v[i], v[min]);
}
}
4. 插入排序
void InsertSort(vector<int>& v)
{
int len = v.size();
for (int i = 1; i < len; ++i) {
int temp = v[i];
for(int j = i - 1; j >= 0; --j)
{
if(v[j] > temp)
{
v[j + 1] = v[j];
v[j] = temp;
}
else
break;
}
}
}
5. 希尔排序
template<typename T>
void shell_sort(T array[], int length) {
int h = 1;
while (h < length / 3) {
h = 3 * h + 1;
}
while (h >= 1) {
for (int i = h; i < length; i++) {
for (int j = i; j >= h && array[j] < array[j - h]; j -= h) {
std::swap(array[j], array[j - h]);
}
}
h = h / 3;
}
}
6. 归并排序
排序算法:归并排序【图解+代码】
7. 堆排序
排序算法:堆排序【图解+代码】
#include<iostream>
using namespace std;
void sw(int &a,int &b) {
int temp = a;
a = b;
b = temp;
}
// arr[]为完全二叉树层序遍历得到的数组
// n为完全二叉树的节点,即数组长度
// i为待维护的节点
void heapify(int arr[], int n, int i) { //把这个二叉树先堆化
//递归出口
if (i >= n) return;
int largest = i;
int lson = i * 2 + 1;
int rson = i * 2 + 2;
if (lson < n && arr[largest] < arr[lson]) { //和左孩子数值比较,找到最大节点,赋值下标
largest = lson;
}
if (rson < n && arr[largest] < arr[rson]) { //和右孩子数值比较,找到最大节点,赋值下标
largest = rson;
}
if (largest != i) { //如果现在的最大值下标和之前的不一样,那么交换二者的数值
//sw(arr[largest], arr[i]);
swap(arr[largest], arr[i]);
heapify(arr, n, largest); //进行一个递归,因为在上一层的节点交换完之后,无法保证下边父节点大于孩子节点
}
}
void heap_sort(int arr[], int n) {
//建堆
int lastNode = n - 1; //从后往前建堆
int parent = (lastNode - 1) / 2;
for (int i = parent; i >= 0; i--) {
heapify(arr, n, i);
}
//堆排序
for (int i = n - 1; i >= 0; i--) {
sw(arr[i], arr[0]);
heapify(arr, i, 0);
}
}
int main() {
int arr[5] = { 5,4,3,2,1 };
heap_sort(arr, sizeof(arr) / sizeof(arr[0]));
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
cout << arr[i] << endl;
}
return 0;
}
8 计数排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 计数排序
void CountSort(vector<int>& vecRaw, vector<int>& vecObj)
{
// 确保待排序容器非空
if (vecRaw.size() == 0)
return;
// 使用 vecRaw 的最大值 + 1 作为计数容器 countVec 的大小
int vecCountLength = (*max_element(begin(vecRaw), end(vecRaw))) + 1;
vector<int> vecCount(vecCountLength, 0);
// 统计每个键值出现的次数
for (int i = 0; i < vecRaw.size(); i++)
vecCount[vecRaw[i]]++;
// 后面的键值出现的位置为前面所有键值出现的次数之和
for (int i = 1; i < vecCountLength; i++)
vecCount[i] += vecCount[i - 1];
// 将键值放到目标位置
for (int i = vecRaw.size(); i > 0; i--) // 此处逆序是为了保持相同键值的稳定性
vecObj[--vecCount[vecRaw[i - 1]]] = vecRaw[i - 1];
}
int main()
{
vector<int> vecRaw = { 0,5,7,9,6,3,4,5,2,8,6,9,2,1 };
vector<int> vecObj(vecRaw.size(), 0);
CountSort(vecRaw, vecObj);
for (int i = 0; i < vecObj.size(); ++i)
cout << vecObj[i] << " ";
cout << endl;
return 0;
}
#include<iostream>
#include<vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int>arr(n);
int count[1000] = {0};
vector<int>result(n);
for (int i = 0; i < n; ++i) {
cin >> arr[i];
count[arr[i]]++;
}
for (int i = 1; i < 1000; ++i) {
count[i] = count[i - 1] + count[i];
}
for (int i = n - 1; i >= 0; --i) {
result[count[arr[i]] - 1] = arr[i];
count[arr[i]]--;
}
for (int i = 0; i < n; ++i)
cout << result[i] << " ";
return 0;
}
自己写的
#include<iostream>
#include<vector>
#include<algorithm>
#include<limits.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int>arr(n);
vector<int>result(n);
int max = INT_MIN;
int min = INT_MAX;
//输入并且记录最大值最小值
for (int i = 0; i < n; ++i) {
cin >> arr[i];
if(arr[i] < min) min = arr[i];
if(arr[i] > max) max=arr[i];
}
//创建数组
int len = max - min;
vector<int> count(len + 1, 0);
//记录个数
for (int i = 0; i < n; ++i) {
int index = arr[i] - min;
count[index]++;
}
//输出
int j = 0;
for (int i = 0; i < count.size();i++) {
while(count[i]!=0){
result[j] = i + min;
j++;
count[i]--;
}
}
for (int i = 0; i < n; ++i)
cout << result[i] << " ";
return 0;
}
9.桶排序
#include <bits/stdc++.h>
using namespace std;
// 打印数组
void print_array(int *arr, int n) {
if(n==0){
printf("ERROR: Array length is ZERO\n");
return;
}
printf("%d", arr[0]);
for (int i=1; i<n; i++)
printf(" %d", arr[i]);
printf("\n");
}
int* sort_array(int *arr, int n) {
int i;
int maxValue = arr[0];
for (i = 1; i < n; i++)
if (arr[i] > maxValue) // 输入数据的最大值
maxValue = arr[i];
// 设置10个桶,依次0,1,,,9
const int bucketCnt = 10;
vector<int> buckets[bucketCnt];
// 桶的大小bucketSize根据数组最大值确定:比如最大值99, 桶大小10
// 最大值999,桶大小100
// 根据最高位数字映射到相应的桶,映射函数为 arr[i]/bucketSize
int bucketSize = 1;
while (maxValue) { //求最大尺寸
maxValue /= 10;
bucketSize *= 10;
}
bucketSize /= 10; //桶的个数
// 入桶
for (int i=0; i<n; i++) {
int idx = arr[i]/bucketSize; //放入对应的桶
buckets[idx].push_back(arr[i]);
// 对该桶使用插入排序(因为数据过少,插入排序即可),维持该桶的有序性
for (int j=int(buckets[idx].size())-1; j>0; j--) {
if (buckets[idx][j]<buckets[idx][j-1]) {
swap(buckets[idx][j], buckets[idx][j-1]);
}
}
}
// 顺序访问桶,得到有序数组
for (int i=0, k=0; i<bucketCnt; i++) {
for (int j=0; j<int(buckets[i].size()); j++) {
arr[k++] = buckets[i][j];
}
}
return arr;
}
int main() {
int n;
scanf("%d", &n);
int *arr;
arr = (int*)malloc(sizeof(int)*n);
for (int i=0; i<n; i++) scanf("%d", &arr[i]);
arr = sort_array(arr, n);
print_array(arr, n);
system("pause");
return 0;
}
自己写的(牛客网)
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型vector
* @return int整型vector
*/
vector<int> bucketSort(vector<int>& nums) {
// write code here
// 计入输入的最大值
int maxValue = nums[0];
for (int i = 1; i < nums.size(); i++)
if (nums[i] > maxValue) // 输入数据的最大值
maxValue = nums[i];
// 全是零的数组
if(maxValue == 0){
return nums;
}
// 设置10个桶,依次0,1,,,9
const int bucketCnt = 10;
vector<int> buckets[bucketCnt];
// 桶的大小bucketSize根据数组最大值确定:比如最大值99, 桶大小10
// 最大值999,桶大小100
// 根据最高位数字映射到相应的桶,映射函数为 arr[i]/bucketSize
int bucketSize = 1;
while (maxValue) { //求最大尺寸
maxValue /= 10;
bucketSize *= 10;
}
bucketSize /= 10; //桶的个数
// 入桶
for (int i = 0; i < nums.size(); i++) {
int idx = nums[i] / bucketSize; //放入对应的桶
buckets[idx].push_back(nums[i]);
// 对该桶使用插入排序(因为数据过少,插入排序即可),维持该桶的有序性
for (int j = int(buckets[idx].size()) - 1; j > 0; j--) {
if (buckets[idx][j] < buckets[idx][j - 1]) {
swap(buckets[idx][j], buckets[idx][j - 1]);
}
}
}
// 顺序访问桶,得到有序数组
for (int i = 0, k = 0; i < bucketCnt; i++) {
for (int j = 0; j < int(buckets[i].size()); j++) {
nums[k++] = buckets[i][j];
}
}
return nums;
}
};
10.基数排序
#include <iostream>
#include <vector>
using namespace std;
int MaxBit(vector<int> input) //求出数组中最大数的位数
{
int max_num = input[0]; //默认最大数为第一个数字
for (int i = 0; i < input.size(); i++) //找出数组中的最大数
{
if (input[i] > max_num)
{
max_num = input[i];
}
}
int p = 0;
while (max_num > 0)
{
p++;
max_num /= 10; //每次除以10取整,即可去掉最低位
}
return p;
}
int GetNum(int num, int d) //取出所给数字的第d位数字
{
int p = 1;
while (d - 1 > 0)
{
p *= 10;
d--;
}
return num / p % 10;
}
vector<int> RadixSort(vector<int> input, int length) //基数排序
{
vector<int> bucket(length); //创建临时存放排序过程中的数据
vector<int> count(10); //创建按位计数的技术容器,即记录排序中按个位、十位...各个数的位置的个数
for (int d = 1; d <= MaxBit(input); d++) {
// 计数器清0
for (int i = 0; i < 10; i++) {
count[i] = 0;
}
// 统计各个桶中的个数
for (int i = 0; i < length; i++) {
count[GetNum(input[i], d)]++;
}
for (int i = 1; i < 10; i++) { //得到每个数应该放入bucket中的位置
count[i] += count[i - 1];
}
for (int i = length - 1; i >= 0; i--) { //采用倒序进行排序是为了不打乱已经排好的顺序
int k = GetNum(input[i], d);
bucket[count[k] - 1] = input[i];
count[k]--;
}
for (int j = 0; j < length; j++) // 临时数组复制到 input 中
{
input[j] = bucket[j];
}
}
return input;
}
int main()
{
int arr[] = { 50, 123, 543, 187, 49, 30, 0, 2, 11, 100 };
vector<int> test(arr, arr + sizeof(arr) / sizeof(arr[0]));
cout << "排序前:";
for (int i = 0; i < test.size(); i++) {
cout << test[i] << " ";
}
cout << endl;
vector<int> result = test;
result = RadixSort(result, result.size());
cout << "排序后:";
for (int i = 0; i < result.size(); i++) {
cout << result[i] << " ";
}
cout << endl;
system("pause");
}
牛客网
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int>nums(n);
vector<int>temp(n);
vector<int>bar(10);
vector<int>count(10);
int maxDigit = 1;
int pos = 10;
for (int i = 0; i < n; ++i)
{
cin >> nums[i];
while (nums[i] >= pos)
{
maxDigit++;
pos *= 10;
}
}
pos = 10;
for (int i = 0; i < maxDigit; ++i)
{
//全部元素装入桶里
for (int j = 0; j < n; ++j)
{
bar[(nums[j]/(pos/10)) % 10]++;
}
//计算count数组
count[0] = bar[0];
for (int j = 1; j < 10; ++j)
{
count[j] = bar[j] + count[j - 1];
}
//将按位排好的元素装入到一个临时容器中
for (int j = n - 1; j >= 0; --j)
{
temp[count[(nums[j] / (pos / 10)) % 10]-1] = nums[j];
count[(nums[j] / (pos / 10)) % 10]--;
}
nums.assign(temp.begin(),temp.end());
bar.assign(10, 0);
pos *= 10;
}
for (int i = 0; i < n; ++i)
{
cout << nums[i] << " ";
}
return 0;
}