若将一组数n个从小到大排列
1.冒泡排序
冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。相当于每次找到最大的数放在最后面,类似于冒泡。
第一次:从第一个数开始,相邻的两个数进行交换,若a[i]<a[i+1],就比较下一组a[i+1]和a[i+2]的大小,否则就交换a[i]和a[i+1],交换后拿新的a[i+1]和a[i+2]进行比较。一直比较到最后面一个数,那么第一次比较后最后一个数a[n-1]就是最大的一个数了。
第一次需要进行n-1次判断,第二次需要进行n-2次判断....第n-1次需要1次判断
故时间复杂度为:O(T)=1+2+...(n-1)=n(n-1)/2=O(n^2);
改进:如果我们在进行某一次排序时,从前到后发现并没有进行前后数据的交换,那么说明数据已经满足了从小到大的排列顺序,此时就不需要继续进行排序运算了。
void BubbleSort(int a[],int n)
{
int i=0,j=0;
bool flag=false;
for (j=0;j<n;j++)
{
flag=true;
for (i=0;i<n-1-j;i++)
{
if (a[i]>a[i+1])
{
int temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
flag=false;
}
}
if(flag) break; 如果第j次排序时没有发生数据交换,就不需要继续进行排序计算了。
}
}
2.交换排序
所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。从第一个数开始,然后把它和后面的数依次比较,如果比它小,两者交换位置,否则依次比较后面的值。第一轮比较完之后,再从第二个数开始,和后面的数依次比较。比较次数为(n-1)+(n-2)+...+1=n(n-1)/2,所以时间复杂度和冒泡排序一样为O(T)=O(n^2)。
int i=0,j=0;
for (i=0;i<n;i++)
{
for (j=i+1;j<n;j++)
{
if (a[i]>a[j])
{
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
3.选择排序
每一次从剩下的第(i+1)~n个数中找出最下的那个数,下标记为Pos,然后判断a[i]>a[Pos],满足的话就交换两者的值。依次知道排序结束。
void selectSort(int a[],int n)
{
int i=0,j=0;
for (i=0;i<n;i++)
{
int iTemp=a[i];
int jPos=i;
for (j=i+1;j<n;j++)
{
if (a[j]<iTemp)
{
iTemp=a[j];
jPos=j;
}
}
if (i!=jPos)
{
int temp=a[i];
a[i]=a[jPos];
a[jPos]=temp;
}
}
}
它和选择排序的不同就是减少了两个值交换的次数,每找一次最多只进行一次交换。
但它的时间复杂度也是O(T)=O(n^2)。
4.插入排序
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这就是插入排序的思想。
第一次循环:以a[0]为排好序的数列,将a[1]插入到a[0]的数列中。记temp=a[1],如果temp<a[0],交换。
第二次循环:以a[0],a[1]为排好序的数列,将a[2]插入到之前的数列中。
第i次循环:将前面a[0],a[1]...a[i-1]作为排好序的数列,将a[i]插入到数列中。先记iPos=i-1,iTemp=a[i],然后对排好序的数列从前往后比较,若a[i-1]>iTemp,那么a[iPos+1]=a[iPos],将a[i-1]赋值给a[i],将iPos前移。一直到排序结束。
如有一组数为:16,10,6,14,36
第一次:10,16,6,14,36;
第二次:10,6,16,14,36; 6,10,16,14,36;
第三次:6,10,14,16,36;
第四次:6,10,14,16,36;
void InsertSort(int a[],int n)
{
int i=0,j=0;
for (i=1;i<n;i++)
{
int iPos=i-1;
int iTemp=a[i];
while(iPos>=0&&a[iPos]>iTemp)
{
a[iPos+1]=a[iPos];
iPos--;
}
a[iPos+1]=iTemp;
}
}
5.快速排序
快速排序(Quicksort)是对冒泡排序的一种改进,它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
void sort(int *a,int x,int y)
{
int xx=x,yy=y;
int k=a[x];
if(x>=y) return ;
while(xx!=yy)
{
while(xx<yy&& a[yy]>=k) 从最后面一个值开始,若都比k值大,则一直往前找。
yy--;
a[xx]=a[yy]; ///找到比k值小的数,那么将这个数放在比较的索引位置。
while(xx<yy&& a[xx]<=k) /再从前往后找,若都比k值小,则一直往后找。
xx++;
a[yy]=a[xx]; /找到比k值大的数,那么将这个大的数放在之前从后往前停留的索引位子。
}
a[xx]=k; ///将k值放在两者交叉的索引位置,此时左边的值都比k小,右边的都比K大。
sort(a,x,xx-1);//左边数列进行递归。
sort(a,xx+1,y);右边数列进行递归。
}