以元素的比较为基本运算的排序算法
算法 | 最坏情况 | 平均情况 |
---|---|---|
插入排序 | O(n^2) | O(n^2) |
冒泡排序 | O(n^2) | O(n^2) |
快速排序 | O(n^2) | O(nlogn) |
堆排序 | O(nlogn) | O(nlogn) |
二分归并排序 | O(nlogn) | O(nlogn) |
1. 插入排序
序列 : 5 7 1 3 6 2 4
将其从小到大排列
从第二个元素开始,将指针指向的当前元素与前一个元素比较,如果前一个元素小于指针指向的当前元素,则将前一个元素向后移一位
代码:
#include<iostream>
#include<vector>
using namespace std;
void insert_sort(vector<int>&nums){
int n = nums.size();
for(int i = 0;i<n;i++){
int value = nums[i];
int j = i-1;
while(j>=0&&value<nums[j]){
nums[j+1] = nums[j];
j--;
}
nums[j+1] = value;
}
}
int main(){
vector<int>nums = {4,2,1,6,3,8,9,3,10,5,5};
insert_sort(nums);
for(auto x:nums){
cout<<x<<" ";
}
system("pause");
return 0;
}
2. 冒泡排序
作巡回的比较
例如从小到达排列一组元素:5 7 1 3 6 2 4
第一次巡回,从前第1,2个元素开始,两两比较,前一个较大则作交换,如此重复,一次巡回即可将未排序的部分序列中的最大值排到部分序列的最右侧
#include<iostream>
#include<vector>
using namespace std;
void insert_sort(vector<int>&nums){
int n = nums.size();
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
if(nums[i]<nums[j]){
swap(nums[i],nums[j]);
}
}
}
}
int main(){
vector<int>nums = {4,2,1,6,3,8,9,3,10,5,5};
insert_sort(nums);
for(auto x:nums){
cout<<x<<" ";
}
system("pause");
return 0;
}
3. 快速排序
快速排序是原地排序算法,它将一个数组分成两个子数组,将两部分分别排序,当子数组有序则总数组也有序,
快速排序的要点在于切分,应使得数组满足,对于某个j:a[j]已排定,a[lo]到a[j-1]都小于a[j],a[j+1]到a[hi]都大于a[j]
通过递归地调用切分来排序
一般将a[lo]作为切分元素
从数组左端i扫描直到扫描到一个大于等于a[lo]的元素,右端j扫描直到找到一个大于等于a[lo]的元素,交换这两个元素
两个指针相遇时,将a[lo]与a[j]交换
#include<iostream>
#include<vector>
using namespace std;
int partation(vector<int>&nums,int lo,int hi){
int i = lo,j =hi+1;
int value = nums[lo];
while(true){
while(nums[++i]<value){
}
while(nums[--j]>value){
}
if(i>=j){
break;
}
swap(nums[i],nums[j]);
}
swap(nums[lo],nums[j]);
return j;
}
void quick_sort(vector<int>&nums,int lo,int hi){
if(hi<=lo){
return;
}
int j = partation(nums,lo,hi);
quick_sort(nums,lo,j-1);
quick_sort(nums,j+1,hi);
}
int main(){
vector<int>nums = {4,2,1,6,3,8,9,3,10,5,5};
quick_sort(nums,0,nums.size()-1);
for(auto x:nums){
cout<<x<<" ";
}
system("pause");
return 0;
}
排序小数组时切换为插入排序,效率比快速排序更高
4. 选择排序
//找到数组中最小的元素,其次将其与数组第一个元素交换位置
//再将剩下的元素中最小的元素与数组第二个元素交换位置,如此重复,直到整个数组排序完成
//交换的总次数为n,运行时间和输入无关
//数据移动最少
#include<iostream>
using namespace std;
void select_sort(vector<int>&nums){
int n = nums.size();
for(int i = 0;i<n;i++){
int min = i;//最小元素的位置
//将a[i]和a[i+1....n-1]中最小元素交换
//找出从a[i+1]最小值的位置(a[i]以及之前已经排好)
for(int j = i+1;j<n;j++){
if(a[j]<a[min]) min = j;
}
//交换位置
swap(i,min);
}
}
int main()
{
vector<int>nums = {4,2,1,6,3,8,9,3,10,5,5};
select_sort(nums,0,nums.size()-1);
for(auto x:nums){
cout<<x<<" ";
}
}