##几种排序方法总结##
1:插入排序法
插入排序算法十分稳定,算法最坏时间复杂度情况,每个i循环都需要执行i次移动,总共需要1+2+3+4+·····+N-1=(N*N-N)/2,既算法复杂度为O(N*N).该排序算法与输入数据顺序升序的个数有关,当输入数据为升序排列,A[j]从开始到结尾都不用移动。
#include<stdio.h>
int main()
{
int n,a[10];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<n;i++)/*i循环变量,表示未排序部分的开头元素,v临时保存a[i]的值,j循环变量,用于在已排序位置寻找v的插入位置*/
{
int v=a[i];
int j=i-1;
while(j>=0 && a[j]>v)
{
a[j+1]=a[j];
j--;
}
a[j+1]=v;
}
for(int i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
return 0;
}
2:冒泡排序法
冒牌排序法时间复杂度为(N-1)+(N-2)+(N-3)+····+1=(N*N-N)/2,既为O(N*N),其排序法也算稳定,但要是出现a[i]<=a[i-1]情况,该算法就会失去稳定性。
#include<stdio.h>
int main()
{
int n,a[10];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int flag=1;
while(flag)
{
flag=0;
for(int i=n-1;i>=1;i--)/*共进行n-1次操作,每次操作就是找到除已排好数之外最小的数将其排到最后面*/
{
if(a[i]<a[i-1])
{
int median;
median=a[i];
a[i]=a[i-1];
a[i-1]=median;
flag=1;
}
}
}
for(int i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
return 0;
}
3选择排序法
插入排序法由于会直接交换两个不相邻的元素所以属于不稳定的排序方法,其时间复杂度与冒泡排序法计算方法一样都为O(N*N).
#include<stdio.h>
int main()
{
int n,a[10];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++)
{
int imin=i;
for(int j=i;j<n;j++)
{
if(a[j]<a[imin])
{
imin=j;
}
}
int median=a[i];
a[i]=a[imin];
a[imin]=median;
}
for(int i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
return 0;
}
4快速排序法
此方法是入门之后最常用的一个排序方法,不过此方法用到了二分查找思想和递归思想,需掌握以上两种思想才能更好的理解此排序方法,它的时间复杂度为O(NlogN),比以上几种排序方法都节约时间。
快速排序是对冒泡法排序的一种改进。
快速排序算法 的基本思想是:将所要进行排序的数分为左右两个部分,其中一部分的所有数据都比另外一 部分的数据小,然后将所分得的两部分数据进行同样的划分,重复执行以上的划分操作,直 到所有要进行排序的数据变为有序为止。
可能仅根据基本思想对快速排序的认识并不深,接下来以对n个无序数列a[0], a[1]…, a[n-1]采用快速排序方法进行升序排列为例进行讲解。(注意i就是left,j就是right,)
(1)定义两个变量left和right,将left,right分别设置为要进行排序的序列的起始元素和最后一个元素的下标。第一次,left和right的取值分别为0和n,接下来的每次取值由划分得到的序列起始元素和最后一个元素的下标来决定。
(2)定义一个变量median,接下来以median的取值为基准将数组a划分为左右两个部分,通 常,median值为要进行排序序列的第一个元素值。第一次的取值为a[0],以后毎次取值由要划 分序列的起始元素决定。
(3)从right所指向的数组元素开始向左扫描,扫描的同时将下标为j的数组元素依次与划分基准值median进行比较操作,直到j不大于i或找到第一个小于基准值median的数组元素,然后将该值赋值给i所指向的数组元素,同时将i右移一个位置。
(4)如果i依然小于j,那么由j所指向的数组元素开始向右扫描,扫描的同时将下标为j的数组元素值依次与划分的基准值median进行比较操作,直到i不小于j或找到第一个大于基准值median的数组元素,然后将该值赋给j所指向的数组元素,同时将j左移一个位置。
(5)重复步骤(3) (4),直到i的植不小于j为止,这时成功划分后得到的左右两部分分别为a[i……i-1]和a[i+1……right],其中,i下标所对应的数组元素的值就是进行划分的基准值median,所以在划分结束时还要将下标为i的数组元素赋值 为 median。
(6)将划分得到的左右两部分a[left……i-1]和a[i+1……right]继续采用以上操作步骤进行划分,直到得到有序序列为止。
#include<stdio.h>
int n,a[100001];
void quicksort(int left,int right)
{
int i,j,median,temp;
i=left;
j=right;
if(left>right)
{
return;
}
median=a[left];/*median是基准数*/
while(i!=j)
{
while(a[j]>=median && i<j)/*注意顺序非常重要,一定要先从右边开始找,不然答案不对*/
{
j--;
}
while(a[i]<=median && i<j)
{
i++;
}
if(i<j)/*交换左边和右边的值*/
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
a[left]=a[i];
a[i]=median;
quicksort(left,i-1);/*继续处理左边的,递归过程*/
quicksort(i+1,right);/*继续处理右边的,递归过程*/
return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
quicksort(1,n);
for(int i=1;i<n;i++)
{
printf("%d ",a[i]);
}
printf("%d",a[n]);
return 0;
}
稳定排序法和希尔排序法不适合新手选择来排序,并且也不常用,在此就不总结了,有兴趣可以去查阅书籍: