考察排序算法,我们一般要考察算法的复杂度和算法是否是稳定排序。稳定排序是指在一个序列中,A与B的值相等,经过排序后,A与B的相对顺序没有改变,则该算法称为稳定排序。
二:初等排序算法 1.冒泡排序算法冒泡排序法,排序时,分为排好部分与没有排好部分,每次排序的排好部分会增加一个排好的元素。每次排序序列的末尾开始向前两两对比,若降序,当后一个元素大于前一个元素,则交换两元素位置。冒泡排序算法,对于长度为N的序列的最坏情况的交换为 ( N 2 − N ) / 2 (N^2-N)/2 (N2−N)/2,故复杂度为 O ( N 2 ) O(N^2) O(N2)。算法比较部分若使用 A[j]
//降序冒泡排序
int bubbleSort(int *A,int N){
int i,j,sw=0;
bool flag = 1;
for (i=0;flag;i++){
flag = 0;
for(j=N-1;j>=i+1;j--){
if (A[j]>A[j-1]) {
swap(A+j,A+j-1);
flag = 1;
sw ++;
}
}
}
}
2.插入排序算法
插入排序法,排序时,分为排好序和未排序的两部分,左边为排好序部分,右边顺序一个一个的抽出插入到排好序部分.
插入排序算法复杂度
O
(
n
2
)
O(n^2)
O(n2),是一个稳定排序算法。
#include3.选择排序算法using namespace std; void swap(int *a,int *b){ int v; v = *a; *a = *b; *b = v; } //输出数组 void trace(int *A,int N){ int i; for(i=0;i =0 && A[j]>v){ A[j+1] = A[j]; j --; sw++; } A[j+1] = v; } return sw; } //主函数入口 int main(int argc, char** argv){ int A[] = {5,3,9,6,1}; cout<<"未排序数组:"; trace(A,5); insertSort(A,5); cout<<"排序后数组:"; trace(A,5); return 0; }
选择排序法,排序时,每次都选取一个最小或最大的数,插入到已经初步的排序好的部分,直到完全排好序。
选择排序算法是一个不稳定算法,无论何种情况,对于长度为N的序列,进行的比较次数都是(
N
2
−
N
N^2-N
N2−N)/2
所以算法的复杂度为O(
N
2
N^2
N2)
int selectSort(int *A,int N){
int minj,i,j,sw=0;
for(i=0;iA[j]){
minj = j;
}
}
swap(A+i,A+minj);
if (i != minj){
sw++;
}
}
return sw;
}
4.希尔排序算法
希尔排序是插入排序的优化,一个希尔排序算法由几个不同步长的插入排序逐个按序对待排序序列进行排序。
步长的选择有很多选择,不同步长的选择会对算法的复杂度有影响,一个较为高效的选择是
{1,4,13,…},即
g
n
+
1
=
3
∗
g
n
−
1
+
1
g_{n+1}=3*g_{n-1}+1
gn+1=3∗gn−1+1
复杂度大概在
O
(
N
1.25
)
O(N^{1.25})
O(N1.25)
但不是一个稳定排序
#includevector G; //N step插入排序排序法 void insertSort(int *A,int N,int g){ int i,j,v; for(i=g;i =0 && A[j]>v){ A[j+g] = A[j]; j -= g; } A[j+g] = v; } } //希尔排序法 void shellSort(int *A,int N){ int i,h; for(h=1;;){ if(h>N) break; G.push_back(h); h = 3*h +1; } for(int i=G.size()-1;i>=0;i--){ insertSort(A,N,G[i]); } }
后续还会补充一些高级的排序算法。



