排序方法 | 平均 | 最好 | 最坏 | 辅助空间 | 稳定性 |
冒泡 | O(n2) | O(n) | O(n2) | O(1) | 稳定 |
简单选择 | O(n2) | O(n2) | O(n2) | O(1) | 稳定 |
插入 | O(n2) | O(n) | O(n2) | O(1) | 稳定 |
希尔 | O(nlogn)~O(n2) | O(n1.3) | O(n2) | O(1) | 不稳定 |
堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 不稳定 |
归并 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | 稳定 |
快速 | O(nlogn) | O(nlogn) | O(n2) | O( logn) ~O(n) | 不稳定 |
冒泡排序:
void BubbleSort(List *l){
int i , j ;
int flag = TURE;
for (i = 1; i <l->length &&flag;i++){
flag = FALSE;
for (j = l->length-1;j>=i;j--){
if (l[j]<l[j+1]){
swap (l,j,j+1);
flag = TURE;}
}}}
简单选择排序(性能略优于冒泡)
通过n-i次比较,选择最小的和目标i交换
//简单排序
void SelectSort(List *l)
{
int min;
for (int i = 0; i < l->length; i++)
{
min = i;
for (int j = l->length - 1; j > i; j--)
{
if (l[j]>l[min])
min = j;
}
if (min != i)
swap(l, i, min);
}
}
插入排序
基于有序的假设插入,比较后,数据右移,填空
//插入排序,基于有序的事实,数据右移,插入
void InsertionSort(int A[],int n)
{
int temp;
fot(int i = 1; i < n; i++)
{
temp = A[i];
for (int P = i; P > 0 && A[P - 1] > temp; P--)
A[P] = A[P - 1];//如果大于数据右移
A[p] = temp;
}
}
堆排序
建立堆(根、子节点,下滤),根与堆末尾交换,调整堆
特点:非常稳定 O(NlogN),相比于希尔排序慢(移动数据进行两次比较)
//堆排序 ,先建立堆,让堆的首尾交换,重新建立堆
#define leftchild (i) (2*i+1)
void PercDown(int *A, int i, int N)
{
int child;
int tmp;
for (tmp = A[i]; leftchild(i) < N; i = child)
{
child = leftchild(i);
if (child != N - 1; A[child + 1] > A[child])
{
child++;
}
if (A[child] > A[i])
A[i] = A[child];
else
break;
}
A[i] = tmp;
}
void HeapSort(int *A, int N)
{
for (int i = n / 2; i >= 0; i --)//注意构建时是i--,每个子节点可能是别的根节点
PercDown(A, i, N);
for (int i = N-1; i >=0; i--)
{
Swap(A + i, A);
PercDown(A, 0, i);
}
}
归并排序分治 、 递归、 声明一个临时变量TmpArray,避免递归占空间,
很难用于主存排序,O(NlogN),合并是外部排序的中心思想。
void Merge(int *A, int * TmpArray, int Lpos, int Rpos, int Rend)//命名是否帮助理解
{
int Leftend = Rpos-1;
int TmpPos = Lpos;
while (Lpos <= Leftend && Rpos <= Rend)
{
if (A[Lpos] > A[Rpos])
{
TmpArray[TmpPos++] = A[Rpos++];
}
else
{
TmpArray[TmpPos++] = A[Lpos++];
}
}
while (Lpos <= Leftend)
{
TmpArray[TmpPos++] = A[Lpos++];
}
while (Rpos <= Rend)
{
TmpArray[TmpPos++] = A[Lpos++];
}
for (int i = 0; i < Rend - Lpos + 1; i++, Rend--)
{
A[Rend] = TmpArray[Rend];
}
}
void Msort(int *A, int * TmpArray, int Left, int Right)
{
int Center;
if (Left < Right)
{
Center = (Left + Right) / 2;
Msort(A, TmpArray, Left, Center);
Msort(A, TmpArray, Center + 1, Right);
Merge(A, TmpArray, Left, Center + 1, Right);
}
}
void MergeSort(int *A, int N)
{
int * TmpArray = new int(N);
if (TmpArray != NULL)
{
Msort(A, TmpArray, 0, N-1);
delete TmpArray;
}
else {
FatalError("no space");
}
}
希尔
O(N7/6) 最坏 O(N4/3)
快排