#include <vector>
#include <iostream>
using namespace std;
vector<int> nums{1,2,31,23,1,223,1,23,12,3,12};
int n = nums.size();
void bubble_sort() {
for (int i = n-1; i > 0; --i) {
for (int j = 0; j < i; ++j) {
if (nums[j] > nums[j+1]) {
swap(nums[j], nums[j+1]);
}
}
}
}
void select_sort() {
for (int i = n-1; i > 0; --i) {
int chg_idx = i;
for (int j = 0; j <= i; ++j) {
chg_idx = nums[chg_idx] < nums[j] ? j : chg_idx;
}
swap(nums[i], nums[chg_idx]);
}
}
void insert_sort() {
for (int i = 1; i < n; ++i) {
int tmp = nums[i];
int j = i-1;
while (nums[j] > tmp) {
nums[j+1] = nums[j];
--j;
}
nums[j+1] = tmp;
}
}
void quick_sort(int left, int right) {
if (left >= right) return;
int i = left, j = right;
int tmp = nums[left];
while (i < j) {
while (i < j && nums[j] >= tmp) { --j; }
while (i < j && nums[i] <= tmp) { ++i; }
if (i < j) { swap(nums[i], nums[j]); }
}
nums[left] = nums[j];
nums[j] = tmp;
quick_sort(left, j-1);
quick_sort(j+1, right);
}
void merge_sort(vector<int> &tmp, int left, int right) {
if (left >= right) return;
int mid = left + (right - left) / 2;
int left1 = left, right1 = mid, left2 = mid+1, right2 = right;
merge_sort(tmp, left1, right1);
merge_sort(tmp, left2, right2);
int k = left;
while (left1 <= right1 && left2 <= right2) {
tmp[k++] = nums[left1] < nums[left2] ? nums[left1++]:nums[left2++];
}
while (left1 <= right1) { tmp[k++] = nums[left1++]; }
while (left2 <= right2) { tmp[k++] = nums[left2++]; }
for(k = left; k <= right; ++k){
nums[k] = tmp[k];
}
}
void heapify(int root, int len) {
int left = root * 2 + 1, right = root * 2 + 2;
int tmp = root;
if (left <= len && nums[tmp] < nums[left]) { tmp = left; }
if (right <= len && nums[tmp] < nums[right]) { tmp = right; }
if (tmp != root) {
swap(nums[root], nums[tmp]);
heapify(tmp, len);
}
}
void heap_sort() {
for (int i = n / 2; i > -1; --i) {
heapify(i, n-1);
}
for (int i = n-1; i > 0; --i) {
swap(nums[i], nums[0]);
heapify(0, i-1);
}
}
//bucket
void count_sort() {
int n = nums.size();
if (n <= 1) { return; }
int min = INT32_MAX, max = INT32_MIN;
for (int i = 0; i < n; ++i) {
if (nums[i] > max) { max = nums[i]; }
if (nums[i] < min) { min = nums[i]; }
}
int k = max-min+1;
vector<int> count(k,0);
for (int i = 0; i < n; ++i) {
count[nums[i]-min] += 1;
}
int loc = 0;
for (int i = 0; i < k; ++i) {
while (count[i] > 0) {
nums[loc++] = i+min;
count[i] -= 1;
}
}
return ;
}
void bucket_sort() {
int n = nums.size();
if (n <= 1) return;
int min = INT32_MAX, max = INT32_MIN;
for (int i = 0; i < n; ++i) {
if (nums[i] > max) max = nums[i];
if (nums[i] < min) min = nums[i];
}
int bucketNum = (max - min) / n + 1;
vector<vector<int>> bucket(bucketNum);
for (int i = 0; i < n; ++i) {
int num = (nums[i] - min) / n;
bucket[num].push_back(nums[i]);
}
int count = 0;
for (int i = 0; i < bucketNum; ++i) {
if (!bucket[i].empty()) {
sort(bucket[i].begin(), bucket[i].end());
for (int j = 0; j < bucket[i].size(); ++j) {
nums[count++] = bucket[i][j];
}
}
}
return;
}
void radix_sort() {
int n = nums.size();
if (n <= 1) return;
int min = INT32_MAX, max = INT32_MIN;
for (int i = 0; i < n; ++i) {
if (nums[i] > max) max = nums[i];
if (nums[i] < min) min = nums[i];
}
max = max > (-min) ? max : -min;
int digit = 0;
while (max > 0) {
max /= 10;
++digit;
}
vector<vector<int>> bucket(19); // for negative number
int pos;
int cur;
for (int i = 0, mod = 1; i < digit; ++i, mod *= 10) {
for (int j = 0; j < n; ++j) {
pos = (nums[j] / mod) % 10;
bucket[pos + 9].push_back(nums[j]);
}
cur = 0;
for (int j = 0; j < 19; ++j) {
for (int k = 0; k < bucket[j].size(); ++k) {
nums[cur++] = bucket[j][k];
}
bucket[j].clear();
}
}
return;
}