现在的位置: 首页 > 综合 > 正文

常见的排序算法

2018年04月06日 ⁄ 综合 ⁄ 共 3778字 ⁄ 字号 评论关闭

最近笔试面试,都涉及到一些常用的排序算法,包括算法的时间复杂度,那个算法最优,代码实现等,现把它们总结总结

1、冒泡排序算法

基本思想是每一次排序把最小(最大)的通过不停地交换之后,放在数组最前列,以此不断循环。

举例:10、9、8、7

交换的时候通过数组的下标交换,而使数组值交换

第一轮:i=0,j<n-i,10、9、8、7--》10、9、7、8--》10、7、9、8--》7、10、9、8   

第二轮:i=1,j<n-i,7、10、9、8--》7、10、8、9--》7、8、10、9

第三轮:i=1,j<n-i,7、8、10、9--》7、8、9、10

算法的时间复杂度是O(n*n)是最慢的算法!

int maopao(int a[],int n,int num)

{

int i,j,t;

for(i=0;i<n-1;i++)

for(j=0;j<n-1;j++)

{

if(a[j]>a[j+1])

{

t=a[j];

a[j]=a[j+1];

a[j+1]=t;

}

num++;

}

return num;  //返回比较次数

}

2、选择排序算法

选择法比冒泡法效率要高些啊,这种方法的基本思想是,从数据中选择最小的同第一个数值交换,在从省下的部分中选择最小的与第二个交换,如此往复。

举例:10、9、8、7

第一轮:i=0,j=1,j<n, 10、9、8、7 iTemp=10--》10、9、8、7 iTemp=9--》10、9、8、7   iTemp=8--》10、9、8、7  iTemp=7   交换7、9、8、10

第二轮:i=1,j=2,j<n,7、9、8、10  iTemp=9--》7、9、8、10  iTemp=8 交换7、8、9、10

第三轮:i=2,j=3,j<n,不交换

时间复杂度是O(n*n)

int SelectSort(int* pData,int Count,int num) 

{ 

int iTemp;   //一个存储值。

int iPos;    //一个存储下标。

int j;

for(int i=0;i<Count-1;i++) 

{ 

iPos = i; 

for(j=i+1;j<Count;j++) 

{ 

if(pData[iPos]>pData[j])    //选择排序法就是用第一个元素与最小的元素交换。

{ 

iPos = j;              //下标的交换赋值。

num++;

} 

} 

iTemp = pData[i]; 

pData[i] = pData[iPos]; 

pData[iPos] = iTemp; 

} 

return num;

}

3、快速排序算法

设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

  一趟快速排序的算法是:

  1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;

  2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];

  3)从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于key的值A[J],并与A[I]交换;

  4)从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于key的A[I],与A[J]交换;

  5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)

  例如:待排序的数组A的值分别是:(初始关键数据:X=49) 注意关键X永远不变,永远是和X进行比较,无论在什么位子,最后的目的就是把X放在中间,小的放前面大的放后面。

  A[0] A[1] A[2] A[3] A[4] A[5] A[6]:

  49 38 65 97 76 13 27

  进行第一次交换后:27 38 65 97 76 13 49

  ( 按照算法的第三步从后面开始找)

  进行第二次交换后:27 38 49 97 76 13 65

  ( 按照算法的第四步从前面开始找>X的值,65>49,两者交换,此时:I=3 )

  进行第三次交换后:27 38 13 97 76 49 65

  ( 按照算法的第五步将又一次执行算法的第三步从后开始找

  进行第四次交换后:27 38 13 49 76 97 65

  ( 按照算法的第四步从前面开始找大于X的值,97>49,两者交换,此时:I=4,J=6 )

  此时再执行第三步的时候就发现I=J,从而结束一趟快速排序,那么经过一趟快速排序之后的结果是:27 38 13 49 76 97 65,即所有大于49的数全部在49的后面,所有小于49的数全部在49的前面。

  快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:

  初始状态 {49 38 65 97 76 13 27}

  进行一次快速排序之后划分为 {27 38 13} 49 {76 97 65}

  分别对前后两部分进行快速排序 {27 38 13} 经第三步和第四步交换后变成 {13 27 38} 完成排序。

  {76 97 65} 经第三步和第四步交换后变成 {65 76 97} 完成排序。

快速排序算法时间复杂度是O(log2(n)*n)

int quicksort(int a[],int k,int r,int num)

{

int m,i,j;

int itemp;

i=k;

j=r;

m=a[k];

do

{

for(;j>k;j--)

{

if(a[j]>=m)

{

num++;

break;

}

num++;

}

for(;i<r;i++)

{

if(a[i]<=m)

{

num++;

break;

}

num++;

}

if(i<=j)

{

itemp=a[i];

a[i]=a[j];

a[j]=itemp;

i++;

j--;

}

}while(i<=j);

if(k<j)

num=quicksort(a,k,j,num);

if(r>i)

num=quicksort(a,i,r,num);

return num;     //比较返回次数

}

4、插入排序

       网上各种讲插入排序的思路,理论性很强,其中有个拿打牌的例子来讲插入排序,感觉比较容易理解。

    插入排序的工作机理与很多人打牌时,整理手中牌时的做法差不多。在开始摸牌时,左手是空的,牌面朝下放在桌上。接着,一次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,要将它与手中已有的牌从右到左地进行比较。无论什么时候,左手中的牌都是排好序的。如果输入数组已经是排好序的话,插入排序出现最佳情况,其运行时间是输入规模的一个线性函数。如果输入数组是逆序排列的,将出现最坏情况。平均情况与最坏情况一样,其时间代价是Θ(n2)。

    也许你没有意识到,但其实你的思考过程是这样的:现在抓到一张7,把它和手里的牌从右到左依次比较,7比10小,应该再往左插,7比5大,好,就插这里。为什么比较了10和5就可以确定7的位置?为什么不用再比较左边的4和2呢?因为这里有一个重要的前提:手里的牌已经是排好序的。现在我插了7之后,手里的牌仍然是排好序的,下次再抓到的牌还可以用这个方法插入。编程对一个数组进行插入排序也是同样道理,但和插入扑克牌有一点不同,不可能在两个相邻的存储单元之间再插入一个单元,因此要将插入点之后的数据依次往后移动一个单元。

long insertsortcompare(long R[],long n)
{
 long IC=0;
 for(long i=1;i<n;i++)                  //i表示插入次数,共进行n-1次
 {
  
  long temp=R[i];                    //把待排序元素赋给temp
  long j=i-1;
  while((j>=0)&&(temp<R[j]))
  {   
   if(temp>=R[j])
   {
    IC++;
   }
   R[j+1]=R[j];                   //顺序比较和移动
   j--;IC++;//比较次数
   
  }
  R[j+1]=temp;
 }
 return IC;
}

链接:

http://www.cnblogs.com/zzp28/articles/1788878.html

http://blog.csdn.net/elegant87/article/details/2418489

http://baike.baidu.com/view/19016.htm

http://hi.baidu.com/zhaoyh_ch2000/blog/item/479fd93790e6afd7a3cc2b8f.html

http://wenku.baidu.com/view/d5a5f835f111f18583d05a1a.html

http://fangxia722.blog.163.com/blog/static/3172901220091013113913631/  这篇文章用打牌做例子讲插入排序,比较通俗易懂

http://zhidao.baidu.com/question/287741538.html

http://www.cnblogs.com/Clingingboy/archive/2011/09/12/2174140.html   这篇文章基于Java算法讲的比较详细,很有参考价值

【上篇】
【下篇】

抱歉!评论已关闭.