Written by Dylan chow
以下的8个排序是常用排序方式
**代表比较重要的
桶排序
int findMax(vector<int>&a)
{
int max= INT_MIN;
for(int i = 0; i <a.size(); i ++)
{
max = max> a [i]?max:a [i];
}
return max;
}
void bucketSort(vector<int>&a)
{
int max = findMax(a);
vector<int> bucket(max + 1,0); //bucket为一个数组,大小为max+1,所有值为0
for(int i = 0; i <a.size(); i ++)
{
bucket[a [i]] ++;
}
int index = 0;
for(int i = 0; i <bucket.size(); i ++)
{
while(bucket[i]> 0)
{
a [index++] = i;
bucket[i]--;
}
}
}
void printfVector(vector<int>&a)
{
for(int i = 0; i <a.size(); i ++)
{
cout << a [i] <<“ ”;
}
count << endl ;
}
注明:桶排序的缺陷在于比如就三个数字:1,2,1亿,此时则需要一亿个桶,这是十分麻烦的,当待排序为连续的如1,1,2,3,3,3,1,1,这时候只需要三个桶,则显得很便利了.
堆排序(**)
void adjustHeap(int a[],n,i)
{
int father=i;
int child=2*father+1;
while(child<n)
{
if(child<n-1&&a[child]<a[child+1])
{
child++;
}
if(a[child]>a[father])
{
swap(a[child],a[father]);
father=child;
child=2*father+1;
}
else
{
break;
}
}
}
void heapSort(int a[],int n)
{
for(int i=n/2-1;i>=0;i--)
{
adjustHeap(a,n,i);
}
for(int j=n-1;j>0;j--)
{
swap(a[0],a[j]);
adjustHeap(a,j,0);
}
}
递归实现快速排序(基于三色旗问题的解法)(**)
pair<int,int>quickHolanSort(int a[],int l,int r)
{
int i=l-1;int j=r+1;int index=l;
int tmp=a[index];
while(index<j)
{
if(a[index]<tmp)
{
swap(a[index++],a[++i]);
}
if(a[index]==tmp)
{
index++;
}
if(a[index]>tmp)
{
swap(a[index],a[--j]);
}
}
return make_pair(i,j);
}
void quickSort(int a[],int l,int r)
{
if(l>=r)
{
return;
}
pair<int,int> p=quickHolaSort(a,l,r);
quickSort(a,l,p.first);
quickSort(a,p.second,r);
}
非递归实现快速排序(**)
void quickSort(int a[],int n)
{
stack<pair<int,int>> stk;
stk.push(make_pair(0,n-1));
while(!stk.empty())
{
pair<int,int>p=stk.top();
stk.pop();
pair<int,int> part=quickHolandFlag(a,p.first,p.second);
if(a[p.first]<a[part.first])
{
stk.push(make_pair(p.first,part.first));
}
if(a[part.second]<a[p.second])
{
stk.push(make_pair(part.second,p.second));
}
}
}
归并排序(**)
void merge(int a[],int l,int mid,int r)
{
int *help=new int[r-l+1];
int i=l;int j=mid+1;int index=0;
while(i<=mid&&j<=r)
{
if(a[i]>a[j])
{
help[index++]=a[j++];
}
else
{
help[index++]=a[i++];
}
}
//处理尾部
while(i<=mid)
{
help[index++]=a[i++];
}
while(j<=r)
{
help[index++]=a[j++];
}
//将新申请空间的值赋给原数组
index=l;
for(int i=0;i<=r-l;i++)
{
a[index++]=help[i];
}
delete []help;
}
void mergeSort(int a[],int l,int r)
{
if(l>=r)
{
return;
}
int mid=(l+r)/2;
mergeSort(a,l,mid);
mergeSort(a,mid+1,r);
merge(a,l,mid,r);
}
直接插入排序
void insertSort(int a[],int n)
{
for(int j=0;j<n-1;j++)//j代表有序表最后一个元素
{
int i=j;
int tmp=a[i+1];
while(i>=0&&a[i]>tmp)
{
a[i+1]=a[i];
i--;
}
a[i+1]=tmp;
}
}
Sheel排序(直接插入的优化)
void shellInsertSort(int a[],int n,int start,int gap)
{
for(j=start,j<n-gap,j+=gap)
{
int i=j;
int tmp=a[i+gap];
while(i>=0&&a[i]>tmp)
{
a[i+gap]=a[i];
i-=gap;
}
a[i+gap]=tmp;
}
}
void sheelSort(int a[],int n)
{
for(int gap=n/2;gap>0;gap/=2)
{
for(int i=0;i<gap;i++)
sheelInsertSort(a,n,i,gap)
}
}
冒泡排序
void bubbleSort(int a[],int n)
{
for(int j=n-1;j>0;j--)//将第一个最大的数放在最后一位,第二个最大的数放在倒数第二位...
{
bool flag=true;[^1]
for(int i=0;i<j;i++)
{
if(a[i]>a[i+1])
{
swap(a[i],a[i+1]);
flag=false;
}
if(flag)
return;
}
}
}
[^1]: 设置flag优化了冒泡排序,当数组在整个遍历过程中,没有发生交换,说明待排序数组已经是有序的了,此时可以直接结束排序过程。
选择排序
void selectSort(int a[],int n)
{
for(int j=n-1;j>0;j--)
{
int maxindex=0;
for(int i=1;i<=j;i++)
{
if(a[i]>a[maxindex])
maxidex=i;
}
swap(a[maxindex],a[j]);
}
}
最后附上各个排序的时间复杂度,空间复杂度以及稳定性对比: