(一)、插入排序
1、直接插入排序
(1)、算法思想:
从第二个元素开始,如果它比前一个元素小,则从后往前查找待插入位置进行插入。
(2)、实现代码:
void insertSort(ElemType A[],int n){
int i,j;
for(i=2;i<=n;i++){//数组从A[1]开始计数,依次将A[2]-A[n]插入到前面已排序序列
if(A[i].key<A[i-1].key){//如果A[i]的关键字小于其前驱,需将A[i]插入到i-1前面的有序表
A[0]=A[i];
for(j=i-1;A[0].key<A[j].key;j--){//从后往前查找待插入位置
A[j+1]=A[j];//向后挪位
}
A[j+1]=A[0];//之所以为j+1是因为之前的j--
}
}
(3)、时间效率:
最好情况下,O(n);最坏情况下O(n2);
(4)、稳定性:稳定的
2、希尔排序
(1)、算法思想:
先取一个小于n的步长d1,把表中全部记录分成d1组,所有距离为d1的倍数的记录放在同一组中,在各组中进行直接插入排序;然后取第二个步长d2=d1/2,重复上述步骤;,直到dn=1;
(2)、实现代码:
void shellSort(ElemType A[],int n)
{
//增量为dk
for(dk=len/2;dk>=1;dk=dk/2){ //步长变化
for(i=dk+1;i<=n;i++){ //从每一组的第二个元素开始做插入排序
if(A[i].key<a[i-dk].key){
A[0]=A[i];
for(j=i-dk;j>0&&A[0].key<A[j].key;j-=dk)//从i的前一个元素开始后移
{
A[j+dk]=A[j];
}
A[j+dk]=A[0];//因为之前的j-=dk多减了一次
}
}
}
(3)、稳定性:不稳定
(二)、交换排序
1、冒泡排序:
(1)、算法思想:
最多执行n-1趟冒泡操作,每一趟冒泡把最小的元素交换到待排序序列的第一个位置。
(2)、实现代码:
void bubbleSort(ElemType A[],int n){
for(int i=0;i<n-1;i++){//执行n-1趟冒泡操作
flag=false;
for(int j=n-1;j>i;j--){//从后面开始把最小的元素交换到待排序序列的第一个位置
if(A[j-1]>A[j]){
swap(A[j-1],A[j]);
flag=true;
}
}
if(flag=true){
return;
}
}
}
(3)、时间效率:最好情况O(n),最坏情况O(n2)
(4)、稳定性:稳定
2、快速排序
(1)、算法思想:
快速排序算法是基于分治算法和递归算法的。在待排序的数组中取第一个元素作为pivot基准。通过一趟排序把pivot放到中间,pivot左面的元素都小于pivot,右面的元素都大于pivot。然后分别递归的对左右两个部分重复上述过程,知道每部分内只有一个元素或者为空为止。
(2)、实现代码:
void QuickSort(ElemType A[] ,int low,int high){
if(low<high){//递归到每部分只有一个元素或者空为止
int pivotpos=Partition(A,low,high);
QuickSort(A,low,pivotpos-1);
QuickSort(A,pivotpos+1,high);
}
}
int Partition(Elem A[],int low ,int high){
Elemtype pivot=A[low];//把A[low]先保存起来,并且作为枢轴值
while(low<high){//一趟排序结束
while(low<high&&A[high]>=pivot){
--high;
}
A[low]=A[high];
while(low<high&&A[low]<=pivot){
++low
}
A[high]=A[low];
}
A[low]=pivot;//把原来的A[low]放到新的low下标处
return low;//返回枢轴值
}
(3)、时间效率:
最坏情况O(n2),平均情况O(n*log(n))
(4)、稳定性:不稳定
(三)、选择排序
1 、简单选择排序
(1)、算法思想:
(2)、实现代码:
(3)、时间效率:
(4)、稳定性:
2、堆排序
(1)、算法思想:
(2)、实现代码:
(3)、时间效率:
(4)、稳定性: