#include <iostream>
#include <memory>
#include <functional>
#include <string.h>
#include <vector>
void print(int *data, int size)
{
for (int i = 0; i < size; i++) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
return;
}
//O(n^2) stable
void bubbleSort(int *data, int size)
{
for (int i = 0; i < size - 1; ++i) {
for (int j = 0; j < size - 1 - i; ++j) {
if (data[j] > data[j + 1]) { // must >, not >=
int tmp = data[j + 1];
data[j + 1] = data[j];
data[j] = tmp;
}
}
}
return;
}
//O(n^2) unstable
void selectSort(int *data, int size)
{
for (int i = 0; i < size - 1; ++i) {
int maxIndex = 0;
for (int j = 1; j < size - i; ++j) {
if (data[j] > data[maxIndex]) {
maxIndex = j;
}
}
int tmp = data[maxIndex];
data[maxIndex] = data[size - 1 - i];
data[size - 1 - i] = tmp;
}
return;
}
//O(n^2) stable
//构建有序的序列,将无序元素依次插入到有序序列中,从右向左遍历有序序列,直到找到合适位置进行插入
void insertSort(int *data, int size)
{
for (int i = 1; i < size; ++i) {
int tmp = data[i];
int j = i - 1;
while (j >= 0 && tmp < data[j]) { //must < , not <=
data[j + 1] = data[j];
j--;
}
data[j + 1] = tmp;
}
return;
}
//O(n(logn)^2) unstable optimize for insertSort
void shellSort(int *data, int size)
{
for (int gap = size /2; gap > 0; gap /= 2) {
for (int i = gap; i < size; ++i) {
int j = i;
int tmp = data[j];
while (j - gap >= 0 && tmp < data[j - gap]) {
data[j] = data[j - gap];
j -= gap;
}
data[j] = tmp;
}
}
return;
}
//O(nlogn) stable
void mergeSort(int *data, int size)
{
int *tmp = new int[size];
auto merge = [data, size, tmp](int left, int mid, int right) {
int i = left;
int j = mid + 1;
int t = 0;
while (i <= mid && j <= right) {
if (data[i] <= data[j]) {
tmp[t++] = data[i++];
} else {
tmp[t++] = data[j++];
}
}
while (i <= mid) {
tmp[t++] = data[i++];
}
while (j <= right) {
tmp[t++] = data[j++];
}
t = 0;
while (left <= right) {
data[left++] = tmp[t++];
}
return;
};
std::function<void(int, int)> sort = [&sort, &merge](int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
sort(left, mid);
sort(mid + 1, right);
merge(left, mid, right);
}
};
// const auto& sort = [&merge](int left, int right) {
// const auto& sortImpl = [&merge](auto &&self, int left, int right) ->void{ //c++14 must ->void, or compile error
// if (left < right) {
// int mid = (left + right) / 2;
// self(self, left, mid);
// self(self, mid + 1, right);
// merge(left, mid, right);
// }
// };
// sortImpl(sortImpl, left, right);
// };
sort(0, size - 1);
return;
}
//O(nlogn) unstable
//大根堆(大根树 + 完全二叉树)
void heapSort(int *data, int size)
{
//O(nlogn)
auto heapInitialize = [] (int *data, int size) {
// 从最后一个父节点开始建堆
for (int root = size / 2 - 1; root >= 0; root--) {
int rootElement = data[root];
int child = root * 2 + 1;
while (child <= size - 1) {
if (child < size - 1 && data[child] < data[child + 1]) {
child++;
}
if (rootElement >= data[child]) {
break;
}
data[(child - 1) / 2] = data[child];
child = child * 2 + 1;
}
data[(child - 1) / 2] = rootElement;
}
};
auto heapPop = [] (int *data, int size) {
int lastElement = data[size - 1];
int current = 0;
int child = 1;
while (child <= size - 1) {
if (child < size - 1 && data[child] < data[child + 1]) {
child++;
}
if (lastElement >= data[child]) {
break;
}
data[(child - 1) / 2] = data[child];
current = child;
child = child * 2 + 1;
}
data[current] = lastElement;
};
heapInitialize(data, size);
for (int i = 0; i < size - 1; i++) {
int tmp = data[0]; //第一个元素--最大元素
heapPop(data, size - i);
data[size - 1 - i] = tmp;
}
return;
}
//O(nlogn) unstable
void quickSort(int *data, int size)
{
//find pivot position
auto partition = [](int *data, int low, int high) {
int pivot = data[low];
while (low < high) {
while (low < high && data[high] >= pivot) { //从右开始找到第一个小于基准值的
high--;
}
data[low] = data[high];
while (low < high && data[low] <= pivot) {
low++;
}
data[high] = data[low];
}
data[low] = pivot;
return low;
};
std::function<void(int*, int, int)> quickSortImpl = [&partition, &quickSortImpl](int *data, int low, int high) {
if (low < high) {
int pivotPosition = partition(data, low, high);
quickSortImpl(data, low, pivotPosition - 1);
quickSortImpl(data, pivotPosition + 1, high);
}
};
quickSortImpl(data, 0, size - 1);
return;
}
//O(n + m) stable
void countSort(int *data, int size)
{
int maxValue = data[0];
int minValue = data[0];
for (int i = 1; i < size; i++) {
if (data[i] > maxValue) {
maxValue = data[i];
}
if (data[i] < minValue) {
minValue = data[i];
}
}
int bucketSize = maxValue - minValue + 1;
std::vector<int> count(bucketSize, 0);
for (int i = 0; i < size; i++) {
count[data[i] - minValue]++;
}
for (int i = 1; i < bucketSize; i++) {
count[i] = count[i - 1] + count[i];
}
std::vector<int> tmp(size, 0);
for (int i = size - 1; i >= 0; i--) {
int k = data[i] - minValue;
tmp[count[k] - 1] = data[i];
count[k]--;
}
memcpy(data, tmp.data(), size * sizeof(int));
return;
}
// O(n) stable
void bucketSort(int *data, int size)
{
const int BUCKET = 5;
int maxValue = data[0];
int minValue = data[0];
for (int i = 1; i < size; i++) {
if (data[i] > maxValue) {
maxValue = data[i];
}
if (data[i] < minValue) {
minValue = data[i];
}
}
//生成桶
int bucketNum = (maxValue - minValue) / BUCKET + 1;
std::vector<std::vector<int>> bucket(bucketNum); //每个桶里也是一个数组
//按范围进行入桶
for (int i = 0; i < size; i++) {
bucket[(data[i] - minValue) / BUCKET].push_back(data[i]);
}
//每个桶内进行插入排序
for (int i = 0; i < bucketNum; i++) {
insertSort(bucket[i].data(), bucket[i].size());
}
//桶合并
int index = 0;
for (int i = 0; i < bucketNum; i++) {
for (const auto &s : bucket[i]) {
data[index++] = s;
}
}
return;
}
//O(n * k) stable
//桶的个数确定:10个, 排序次数确定:最大元素位数
void radixSort(int *data, int size)
{
auto maxBit = [data, size]()->int {
int maxData = data[0];
for (int i = 0; i < size; i++) {
if (maxData < data[i]) {
maxData = data[i];
}
}
int bits = 1;
while (maxData /= 10) {
++bits;
}
return bits;
};
int radix = 1;
int maxbit = maxBit();
std::vector<int> tmp(size, 0); //临时数组,用于存储每次按某位排序的结果
for (int i = 0; i < maxbit; i++) {
std::vector<int> count(10, 0);
//统计每个桶里面的元素个数
for (int j = 0; j < size; j++) {
count[(data[j] / radix) % 10]++;
}
//累加桶的计数,用来确定每个元素的在数组中的位置
for (int j = 1; j < 10; j++) {
count[j] = count[j - 1] + count[j];
}
//根据count将数据进行排序收集到tmp
for (int j = size - 1; j >= 0; j--) {
int k = (data[j] / radix) % 10;
tmp[count[k] - 1] = data[j];
count[k]--;
}
//数据写会data, 为下一次排序作准备
memcpy(data, tmp.data(), size * sizeof(int));
// for (int j = 0; j < size; j++) {
// data[j] = tmp[j];
// }
radix *= 10;
}
return;
}
int main(void)
{
int data[] = {1, 4, 9, 2, 9, 24, 100, 3, 389, 22};
const int size = sizeof(data) / sizeof(int);
// bubbleSort(data, size);
// print(data, size);
// selectSort(data, size);
// print(data, size);
// insertSort(data, size);
// print(data, size);
// shellSort(data, size);
// print(data, size);
// mergeSort(data, size);
// print(data, size);
// heapSort(data, size);
// print(data, size);
// quickSort(data, size);
// print(data, size);
// countSort(data, size);
// print(data, size);
// bucketSort(data, size);
// print(data, size);
radixSort(data, size);
print(data, size);
return 0;
}
十大排序算法C++实现
最新推荐文章于 2023-01-04 10:43:33 发布