排序
快速排序
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
if (arr.empty()) {
return arr;
}
quick_sort(arr, 0, arr.size()-1);
return arr;
}
private:
void quick_sort(std::vector<int> &arr, int low, int high) {
if (low < high) {
int key = partition(arr, low, high);
quick_sort(arr, low, key-1);
quick_sort(arr, key+1, high);
}
}
int partition(std::vector<int> &arr, int low, int high) {
int base = low; // 第一个元素作为基准
while (low < high) {
while (arr[high] > arr[base] && low < high) --high;
while (arr[low] <= arr[base] && low < high) ++low;
std::swap(arr[low], arr[high]);
}
if (arr[base] >= arr[low]) { // 这里使用等于判断,防止首元素进行交换时产生越界
std::swap(arr[base], arr[low]);
return low;
} else {
std::swap(arr[base], arr[low-1]);
return low-1;
}
}
};
归并排序
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
if (arr.empty()) {
return arr;
}
merge_sort(arr, 0 , arr.size()-1);
return arr;
}
private:
void merge_elem(std::vector<int> &arr, int low, int mid, int high) {
std::vector<int> temp;
int i = low, j = mid + 1;
// 排序插入
while (i <= mid && j <= high) {
if (arr[i] <= arr[j]) {
temp.push_back(arr[i++]);
} else {
temp.push_back(arr[j++]);
}
}
// 遍历剩下部分
while (i <= mid) {
temp.push_back(arr[i++]);
}
while (j <= high) {
temp.push_back(arr[j++]);
}
// 拷贝回原数组
for (int i = low, j = 0; i <= high; i++) {
arr[i] = temp[j++];
}
}
void merge_sort(std::vector<int> &arr, int low, int high) {
if (low < high) { // 分割到两个元素
int mid = (low+high) / 2;
merge_sort(arr, low, mid);
merge_sort(arr, mid+1, high);
merge_elem(arr, low, mid, high); // 递归到两个元素后合并回退
}
}
};
堆排序
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
if (arr.empty()) {
return arr;
}
heap_sort(arr, 0, arr.size()-1);
return arr;
}
private:
void sink(std::vector<int> &arr, int node, int size) {
while (2*node + 1 <= size) {
int max_node = 2*node + 1;
if (max_node < size && arr[max_node] < arr[max_node+1]) { // 找到最大孩子
max_node++;
}
if (arr[node] >= arr[max_node]) {
break;
} else {
std::swap(arr[node], arr[max_node]);
}
node = max_node; // 持续下沉到叶子结点或满足条件
}
}
// 从零开始,使用(n-1)/2
void heap_sort(std::vector<int> &arr, int low, int high) {
for (int i = (high-1) / 2; i >= 0; i--) { // 构建最大堆
sink(arr, i, high);
}
while (high > 0) { // 交换-下沉 完成排序
std::swap(arr[high--], arr[0]); // 最大元素挪到末尾,再调整堆
sink(arr, 0, high);
}
}
};
冒泡排序
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
if (arr.empty()) {
return arr;
}
bubble_sort(arr, arr.size()-1);
return arr;
}
private:
void bubble_sort(std::vector<int> &arr, int size) {
for (int i = 0; i < size; i++) { // n个元素循环n-1次
for (int j = 0; j < size; j++) { // 每次取出最大元素到最尾
if (arr[j] > arr[j+1]) {
std::swap(arr[j], arr[j+1]);
}
}
}
}
};
选择排序
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
if (arr.empty()) {
return arr;
}
selection_sort(arr, arr.size()-1);
return arr;
}
private:
void selection_sort(std::vector<int> &arr, int size) {
// 第一层循环选中n-1个元素
// 从选中元素后面 挑选出最小的元素与当前元素交换
// 选中元素最小则不交换
for (int i = 0; i < size; i++) {
int min = arr[i];
int index = i;
for (int j = i+1; j <= size; j++) {
if (arr[j] < min) {
min = arr[j];
index = j;
}
}
if (index != i) {
std::swap(arr[i], arr[index]);
}
}
}
};
插入排序
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
if (arr.empty()) {
return arr;
}
insertion_sort(arr, arr.size()-1);
return arr;
}
private:
void insertion_sort(std::vector<int> &arr, int size) {
for (int i = 1; i <= size; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}
};
计数排序(适合数据集在小区间范围)
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
if (arr.empty()) {
return arr;
}
counting_sort(arr, arr.size()-1);
return arr;
}
private:
void counting_sort(std::vector<int> &arr, int size) {
int max = arr[0];
std::vector<int> copy_arr(arr); // 辅助数组
for (int i = 0; i <= size; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
std::vector<int> temp(max+1, 0); // 大小为数据区间
for (int i = 0; i <= size; i++) {
temp[arr[i]]++; // 统计每个值出现的次数,存放在对应下标
}
// 计数累加
for (int i = 1; i < temp.size(); i++) {
temp[i] += temp[i-1]; // 记录当前值排的位数
}
// 反向填充数组
for (int i = size; i >= 0 ; i--) {
arr[--temp[copy_arr[i]]] = copy_arr[i]; // 索引比计数值小1,先自减
}
}
};
桶排序 基数排序 希尔排序暂无