稳定性:
冒泡: 稳定
直接选择排序: 不稳定
直接插入排序: 稳定
希尔排序: 不稳定
归并排序: 稳定
快速排序: 不稳定
堆排序: 不稳定
冒泡排序
#include<iostream>
#include<vector>
using namespace std;
void bubble_sort(vector<int> &arr)
{
for (int i = 0; i < arr.size() - 1; i++) //排序n-1趟 n为元素个数
{
for (int j = 0; j < arr.size() - i - 1; j++)
{
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j+1]);
}
}
}
int main()
{
vector<int> arr{3,38,5,44,15,36,26,27,2,46,4,19,47,48,50,26};
bubble_sort(arr);
for (auto num : arr)
cout << num << " ";
cout << endl;
return 0;
}
直接插入排序
// 直接插入排序
void insert_sort(vector<int>& nums)
{
int n = nums.size();
for(int i = 1; i < n; i++)
{
int tmp = nums[i];
int j = i-1;
while(j >= 0 && nums[j] > tmp)
{
nums[j+1] = nums[j];
j--;
}
nums[j+1] = tmp;
}
}
选择排序
#include<iostream>
#include<vector>
using namespace std;
void select_sort(vector<int>& arr)
{
for (int i = 0; i < arr.size() - 1; i++)
{
int min_index = i;
for (int j = i + 1; j < arr.size(); j++)
{
if (arr[j] < arr[min_index]) //找到最小元素的下标
min_index = j;
}
swap(arr[i],arr[min_index]); //交换,每趟排序都确定最前面元素的位置
}
}
int main()
{
vector<int> arr{ 3,38,5,44,15,36,26,27,2,46,4,19,47,48,50,26 };
select_sort(arr);
for (auto num : arr)
cout << num << " ";
cout << endl;
return 0;
}
希尔排序
#include<iostream>
#include<vector>
using namespace std;
void shell_sort(vector<int>& arr)
{
for (int gap = arr.size() / 2; gap > 0; gap /= 2)
{
for (int i = gap; i < arr.size(); i++) //i从gap开始到最后一个元素
{
int j = i;
while (j - gap >= 0 && arr[j] < arr[j-gap])
{
swap(arr[j], arr[j - gap]);
j -= gap;
}
}
}
}
int main()
{
vector<int> arr{ 3,38,5,44,15,36,26,27,2,46,4,19,47,48,50,26 };
shell_sort(arr);
for (auto num : arr)
cout << num << " ";
cout << endl;
return 0;
}
归并排序
#include<iostream>
#include<vector>
using namespace std;
void merge(vector<int>& arr, int left, int mid, int right)
{
int i = left, j = mid + 1, t = 0; //i为左边数组的左边界,j为右边数组的左边界
vector<int> temp(right-left+1,0);
while (i <= mid && j <= right)
{
if (arr[i] < arr[j])
temp[t++] = arr[i++];
else
temp[t++] = arr[j++];
}
while (i <= mid) //拷贝左边剩余元素
temp[t++] = arr[i++];
while (j <= right) //拷贝右边剩余元素
temp[t++] = arr[j++];
t = 0;
while (left <= right)
arr[left++] = temp[t++];
}
void merge_sort(vector<int>& arr, int left, int right)
{
if (left < right)
{
int mid = (left + right) / 2;
merge_sort(arr,left,mid);
merge_sort(arr,mid+1,right);
merge(arr,left,mid,right);
}
}
int main()
{
vector<int> arr{ 3,38,5,44,15,36,26,27,2,46,4,19,47,48,50,26 };
merge_sort(arr,0,arr.size()-1);
for (auto num : arr)
cout << num << " ";
cout << endl;
return 0;
}
快速排序
class Solution {
public:
int partition(vector<int>& nums, int left, int right)
{
// //方法一:随机选择一个点
// int random_index = rand()%(right-left+1)+left;
// swap(nums[right], nums[random_index]);
// int pivot = nums[right]; //基准点
// int i = left-1;
// for(int j = left; j <= right-1; j++)
// {
// if(nums[j] <= pivot)
// {
// i++;
// swap(nums[j], nums[i]);
// }
// }
// swap(nums[i+1], nums[right]);
// return i+1;
//方法二:选择第一个值为基准点
int pivot = nums[left];
swap(nums[left], nums[right]);//将基准点和最后一个值交换
int i = left-1;
for(int j = left; j <= right-1; j++)
{
if(nums[j] <= pivot) //将小于等于基准点的值全都排在前面
{
i++;
swap(nums[i], nums[j]);
}
}
swap(nums[i+1], nums[right]); //将原值换回
return i+1; //返回当前已经排序好的点
}
void quick_sort(vector<int>& nums, int left, int right)
{
if(left < right)
{
int pos = partition(nums, left, right);
quick_sort(nums, left, pos-1);
quick_sort(nums, pos+1, right);
}
}
vector<int> sortArray(vector<int>& nums) {
//随机选点
srand((unsigned)time(NULL));
quick_sort(nums, 0, nums.size()-1);
return nums;
}
};
/*
#include<iostream>
#include<vector>
using namespace std;
int partition(vector<int>& arr, int low, int high)
{
//int key = arr[low]; //基准点
//while (low < high)
//{
// while (low < high && arr[high] >= key) //从后往前找第一个比基准点小的元素 注意!!!等号不能少,否则陷入死循环,因为当存在相同元素时,low和high一直不会移动
// high--;
// //swap(arr[low], arr[high]); //交换
// arr[low] = arr[high];
// while (low < high && arr[low] <= key) //从前往后找第一个比基准点大的元素
// low++;
// //swap(arr[low], arr[high]); //交换
// arr[high] = arr[low];
//}
//arr[low] = key; //复原当前的元素
//return low; //返回划分点的索引
//第二种方法
int tmp = arr[high];
int i = low;
for (int j = low; j < high; j++) {
if (arr[j] < tmp) swap(arr[i++], arr[j]);
}
swap(arr[i], arr[high]);
return i;
}
void quick_sort(vector<int>& arr, int low, int high)
{
if (low < high)
{
int pivot = partition(arr, low, high);
quick_sort(arr, low, pivot - 1);
quick_sort(arr, pivot + 1, high);
}
}
int main()
{
vector<int> arr{ 3,38,5,44,15,36,26,27,2,46,4,19,47,48,50,26 };
quick_sort(arr,0,arr.size()-1);
for (auto num : arr)
cout << num << " ";
cout << endl;
return 0;
}
*/
堆排序
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
void adjust_heap(vector<int>& num, int cur_index, int length)
{
for(int i = cur_index * 2 + 1; i < length; i = i * 2 + 1) //每次向下调整堆
{
if(i+1 < length && num[i] < num[i+1]) //右子树结点值比左子树大则切换到右子树
i++;
if(i < length && num[i] > num[cur_index]) //孩子结点比父节点值大则交换,继续递归向下调整
{
swap(num[i], num[cur_index]);
cur_index = i;
}
else //满足了大顶堆的要求 跳出
break;
}
}
void heap_sort(vector<int>& num)
{
//构建初始大顶堆
for(int i = num.size()/2-1; i >= 0; i--)
adjust_heap(num, i, num.size());
for(int i = num.size()-1; i > 0; i--) //共调整堆n-1趟
{
swap(num[0], num[i]); //交换堆顶元素和末尾元素
adjust_heap(num, 0, i);
}
}
int main()
{
vector<int> vec{3,38,5,44,15,36,26,27,2,46,4,19,47,48,50,26};
heap_sort(vec);
for(auto num: vec)
cout << num << " ";
cout << endl;
return 0;
}