十大排序算法
力扣题目链接:912. 排序数组 - 力扣(LeetCode)
原理:1.0 十大经典排序算法 | 菜鸟教程 (runoob.com)
代码
class Solution {
public:
//冒泡排序,时间O(n^2), 空间O(1)
void bubbleSort(vector<int>& nums) {
for (int i = 0; i < nums.size() - 1; ++i) {
for (int j = 0; j < nums.size() - i - 1; ++j) {
if (nums[j] > nums[j + 1]) {
int tem = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = tem;
}
}
}
}
//选择排序,时间O(n^2), 空间O(1)
void selectSort(vector<int>& nums) {
for (int i = 0; i < nums.size() - 1; ++i) {
int ind = i;
for (int j = i + 1; j < nums.size(); j++) {
if (nums[j] < nums[ind]) {
ind = j;
}
}
if (ind != i) {
std::swap(nums[i], nums[ind]);
}
}
}
//插入排序,时间O(n^2), 空间O(1)
void insertSort(vector<int>& nums) {
for (int i = 1; i < nums.size(); ++i) {
if (nums[i] >= nums[i -1]) continue;
int tem = nums[i];
int j = i - 1;
while (j >= 0 && nums[j] > tem) {
nums[j + 1] = nums[j];
j--;
}
nums[j + 1] = tem;
}
}
//希尔排序,时间O(nlog(n)), 空间O(1)
void shellSort(vector<int>& nums) {
int gap = nums.size();
while (gap > 1) {
gap = gap / 3 + 1;
for (int i = gap; i < nums.size(); i++) {
if (nums[i] >= nums[i - gap]) continue;
int tem = nums[i];
int j = i - gap;
while (j >= 0 && nums[j] > tem) {
nums[j + gap] = nums[j];
j -= gap;
}
nums[j + gap] = tem;
}
}
}
void merge(vector<int>& nums, int ibegin, int mid, int iend) {
vector<int> leftNums(nums.begin() + ibegin, nums.begin() + mid + 1);
vector<int> rightNums(nums.begin() + mid + 1, nums.begin() + iend + 1);
int idxLeft = 0, idxRight = 0;
// leftNums[leftNums.size() - 1] = INT_MAX;
// rightNums[rightNums.size() - 1] = INT_MAX;
leftNums.insert(leftNums.end(), INT_MAX);
rightNums.insert(rightNums.end(), INT_MAX);
for (int i = ibegin; i <= iend; ++i) {
if (leftNums[idxLeft] < rightNums[idxRight]) {
nums[i] = leftNums[idxLeft];
idxLeft++;
}
else {
nums[i] = rightNums[idxRight];
idxRight++;
}
}
}
//归并排序,时间O(nlog(n)), 空间O(n)
void merge_sort(vector<int>& nums, int ibegin, int iend) {
if (ibegin < iend) {
int mid = (ibegin + iend) / 2;
merge_sort(nums, ibegin, mid);
merge_sort(nums, mid + 1, iend);
merge(nums, ibegin, mid, iend);
}
}
// 随机快排,双指针,时间O(nlog(n)),空间O(log(n))
void quick_sort(vector<int>& nums, int ibegin, int iend) {
if (ibegin >= iend) {
return;
}
int index = rand() % (iend - ibegin + 1) + ibegin;
swap(nums[iend], nums[index]);
int tem = nums[iend];
int left = ibegin;
int right = iend - 1;
while (left <= right) {
while (left <= right && nums[left] < tem) {
left++;
}
while (left <= right && nums[right] > tem) {
right--;
}
if (left <= right) swap(nums[left++], nums[right--]);
}
// nums[iend] = nums[left];
// nums[left] = tem;
swap(nums[iend], nums[left]);
quick_sort(nums, ibegin, left - 1);
quick_sort(nums, left + 1, iend);
}
int partition(vector<int>& nums, int l, int r) {
int pivot = nums[r];
int i = l - 1;
for (int j = l; j <= r - 1; ++j) {
if (nums[j] <= pivot) {
i = i + 1;
swap(nums[i], nums[j]);
}
}
swap(nums[i + 1], nums[r]);
return i + 1;
}
int randomized_partition(vector<int>& nums, int l, int r) {
int i = rand() % (r - l + 1) + l; // 随机选一个作为我们的主元
swap(nums[r], nums[i]);
return partition(nums, l, r);
}
// 官方随机快排
void randomized_quicksort(vector<int>& nums, int l, int r) {
if (l < r) {
int pos = randomized_partition(nums, l, r);
randomized_quicksort(nums, l, pos - 1);
randomized_quicksort(nums, pos + 1, r);
}
}
void maxHeapify(vector<int>& nums, int i, int len) {
while ((i << 1) + 1 <= len) {
int lson = (i << 1) + 1;
int rson = (i << 1) + 2;
int large = i;
if (lson <= len && nums[lson] > nums[i]) large = lson;
if (rson <= len && nums[rson] > nums[large]) large = rson;
if (large != i) {
swap(nums[i], nums[large]);
i = large;
} else {
break;
}
}
}
void buildMaxHeap(vector<int>& nums, int len) {
for (int i = (len - 1) / 2; i >= 0; --i) {
maxHeapify(nums, i, len);
}
}
// 堆排序,时间O(nlog(n)),空间O(1)
void heap_sort(vector<int>& nums) {
int len = nums.size() - 1;
buildMaxHeap(nums, len);
for(int i = len; i > 0; --i) {
swap(nums[0], nums[i]);
--len;
maxHeapify(nums, 0, len);
}
}
// 计数排序,时间O(n+k),空间O(n+k)
vector<int> count_sort(vector<int>& nums) {
int len = nums.size();
vector<int> newNums(len);
int min = INT_MAX, max = INT_MIN;
for (auto n : nums) {
if (n < min) min = n;
if (n > max) max = n;
}
int k = max - min + 1;
vector<int> countNums(k);
for (auto n : nums) {
countNums[n - min]++;
}
for (int i = 1; i < countNums.size(); ++i) {
countNums[i] += countNums[i - 1];
}
for (int i = 0; i < nums.size(); ++i) {
newNums[--countNums[nums[i] - min]] = nums[i];
}
return newNums;
}
// 桶排序,时间O(n+k),空间O(n+k)
void bucket_sort(vector<int>& nums) {
int len = nums.size();
int bucketNum = sqrt(len);
// int bucketNum = len / 2 + 1;
vector<vector<int>> bucket(bucketNum);
int min = INT_MAX, max = INT_MIN;
for (auto n : nums) {
if (n < min) min = n;
if (n > max) max = n;
}
int cu = ceil(float(max - min + 1) / bucketNum);
for (auto n : nums) {
bucket[(n - min) / cu].push_back(n);
}
for (int i = 0; i < bucketNum; ++i) {
quick_sort(bucket[i], 0, bucket[i].size() - 1);
}
int ind = 0;
for (int i = 0; i < bucketNum; ++i) {
for (int j = 0; j < bucket[i].size(); ++j) {
nums[ind++] = bucket[i][j];
}
}
}
// 基数排序,时间O(n*k),空间O(n+k)
void radix_sort(vector<int>& nums) {
int maxNum = INT_MIN;
int minNum = INT_MAX;
for (auto n : nums) {
if (n < minNum) minNum = n;
if (n > maxNum) maxNum = n;
}
if (minNum < 0) {
for (auto& n : nums) {
n -= minNum;
}
maxNum -= minNum;
}
int nbit = 0;
while (maxNum > 0) {
maxNum /= 10;
nbit++;
}
vector<int> countNums(10); // 计数排序
vector<int> tem(nums.size());
int radix = 1;
// cout << nbit;
for (int i = 0; i < nbit; ++i) {
for (int j = 0; j < 10; ++j) {
countNums[j] = 0;
}
for (auto n : nums) {
int ind = (n / radix) % 10;
countNums[ind]++;
}
for (int j = 1; j < 10; ++j) {
countNums[j] += countNums[j - 1];
}
for (int j = nums.size() - 1; j >= 0; --j) {
tem[--countNums[(nums[j] / radix) % 10]] = nums[j];
}
for (int j = 0; j < nums.size(); ++j) {
nums[j] = tem[j];
}
radix *= 10;
}
if (minNum < 0) {
for (auto& n : nums) {
n += minNum;
}
}
}
vector<int> sortArray(vector<int>& nums) {
radix_sort(nums);
return nums;
// return count_sort(nums);
}
};