选择排序 :
原理:
- 在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
- 从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
- 重复第二步,直到所有元素均排序完毕。
例如:对 12 , 3 ,5 ,10 ,4 ,9 进行排序。
代码如下:
#include <iostream>
using namespace std;
int N=10;
int A[10];
int i,j,min_x;
void Select_Sort (int A[],int N)
{
for(i=0;i<N-1;i++)
{
min_x=i;
for(j=i+1;j<N;j++)
{
if(A[min_x] > A[j]) min_x=j;
}
swap(A[i],A[min_x]);
}
}
int main()
{
for(i=0;i<N;i++) cin >> A[i];
Select_Sort(A,10);
for(i=0;i<N;i++) cout << A[i]<<endl;
return 0;
}
Addition :
1. 时间复杂度 : O(n);
2. 稳定性:不稳定。
堆排序 :
原理:
堆排序可以说是一种利用堆的概念来排序的选择排序。
排序过程:
- 创建一个堆A[ 0 , 1 , ……,n] ;
- 将堆首设置为最大值;
- 再将堆尾与堆首进行交换;
- 把堆的尺寸缩小 1 ,即已有一位数字排好序(堆尾);
- 重复 2、3、4 步骤,直至堆的尺寸为1 。
例如:对 12 , 3 ,5 ,10 ,4 ,9 进行排序。
代码 ( 详见下方链接):
Addition :
1. 时间复杂度 : O(n logn);
2. 稳定性:不稳定。
归并排序 :
原理:
核心是有序子列的归并。
排序过程:
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
- 重复步骤 3 直到某一指针达到序列尾;
- 将另一序列剩下的所有元素直接复制到合并序列尾。
代码 :(下面的例子中,已经对两个子序列排好序并合并起来了。如果没有的话,可以再用一个函数,先进行子序列的排序。)
#include <iostream>
using namespace std;
int A[8]={2,8,13,24,3,5,15,22};
int TmpA[8];
int N=8;
int L=0,R=4,RightEnd=7;
/*L=左边起始位置,R=右边起始位置,RightEnd=右边终点位置*/
void Merge_Sort (int A[],int TmpA[])
{
int LeftEnd=R-1; /*左边终点位置,假设两个数组同列*/
int Tep=L; /*存放结果的数组的初始位置*/
int N=RightEnd-L+1;
while(L<=LeftEnd && R<=RightEnd)
{
if(A[L]<=A[R]) {TmpA[Tep++]=A[L++]; }
else { TmpA[Tep++]=A[R++]; }
}
while(L<=LeftEnd)
{
TmpA[Tep++]=A[L++];
}
while (R<=RightEnd)
{
TmpA[Tep++]=A[R++];
}
for(int i=0;i<N;i++,RightEnd--)
{
A[RightEnd]=TmpA[RightEnd];
}
}
int main()
{
Merge_Sort(A,TmpA);
for(int i=0;i<N;i++) cout<<A[i]<<endl;
return 0;
}
1. 时间复杂度 : O(n logn); 需要额外的内存空间。
2. 稳定性:稳定。