排序算法
冒泡、插入、选择、快速、归并、希尔
冒泡排序:稳定 ,复杂度 O(n^2)
首先从数组的第一个元素开始到数组最后一个元素为止,对数组中相邻的两个元素进行比较,如果位于数组左端的元素大于数组右端的元素,则交换这两个元素在数组中的位置,此时数组最右端的元素即为该数组中所有元素的最大值。接着对该数组剩下的n-1个元素进行冒泡排序,直到整个数组有序排列。
void bubble_sort(vector<int> &a)
{
int n=a.size();
for(int i=1;i<n;i++)
for(int j=0;j<n-i;j++)
if(a[j]>a[j+1])
swap(a[j],a[j+1]);
}
插入排序:稳定 ,复杂度 O(n^2)
每步将一个待排序的记录,按其值的大小插入到前面已经排序的数组中的适当位置上,直到全部插入完为止
void insert_sort(vector<int> &a)
{
int n=a.size();
for (int i = 1; i < n; ++i) {
int temp=a[i];
int j=i;
while (j>=1&&temp<a[j-1]){
a[j]=a[j-1];
j--;
}
a[j]=temp;
}
}
选择排序: 不稳定,复杂度 O(n^2)
先从n个数字中找到最小值min1,将最小值min1和arr[0]交换,接着在剩下的n-1个数字中找到最小值min2,将最小值min2和arr[1]交换,依次类推,直到数组arr有序排列。
void select_sort(vector<int> &a)
{
int n=a.size();
for (int i = 0; i < n; ++i) {
int index=i;
for (int j = i; j < n; ++j) {
if(a[j]<a[index])
index=j;
}
if (index!=i)
swap(a[index],a[i]);
}
}
快速排序:不稳定, 复杂度 平均:O(nlogn) 最差:O(n^2)
递归思想,每次排序将数组分为左右两部分,左边部分均小于某记录值,右边部分均大于某记录值K。分别从头尾(i=0, j=size-1),同时向中间前进,左边遇到大于K时的 a[i],右边遇到小于K的 a[j] ,交换a[i]~a[j],直至i=j,交换K和i(j)位置的值;此时,左边均小于K,右边均大于K,以此分左右两段不断重复。
void quick_sort(vector<int> &a,int left,int right)
{
if(left>right)
return;
int i,j,temp;
i=left;
j=right;
temp=a[left];
while(i!=j){
while (a[i]<temp && i<j)
i++;
while (a[j]>temp && i<j)
j--;
swap(a[i],a[j]);
}
swap(temp,a[i]);
quick_sort(a,left,i-1);
quick_sort(a,i+1,right);
}
归并排序:稳定, 复杂度:O(nlogn)
分治思想,将数组不断两两分组比较大小,分至单元素,然后两两合并。
void merge(vector<int> &a,int left,int mi,int right)
{
int first=left;
int second=mi+1;
int index=left;
vector<int> B;
B.resize(right-left+1);
while ((first<=mi) && (second<=right)){
if(a[first]<=a[second])
{
B[index]=a[first];
first++;
index++;
}
else
{
B[index]=a[second];
second++;
index++;
}
}
while (first<=mi){
B[index]=a[first];
first++;
index++;
}
while (second<=right){
B[index]=a[second];
second++;
index++;
}
for (int i = left; i <= right; ++i)
a[i]=B[i];
}
void merge_sort(vector<int> &a,int left,int right)
{
if(right<=left)return;
int mi=(right+left)/2;
merge_sort(a,left,mi);
merge_sort(a,mi+1,right);
merge(a,left,mi,right);
}
希尔排序:不稳定 ,复杂度