1.冒泡法:
这是最原始,也是众所周知的最慢的算法了。他的名字的由来因为它的工作看来象是冒泡:
#include <iostream.h>
void BubbleSort(int* pData,int Count)
{
int iTemp;
for(int i=1;i<Count;i++)
{
for(int j=Count-1;j>=i;j--)
{
if(pData[j]<pData[j-1])
{
iTemp = pData[j-1];
pData[j-1] = pData[j];
pData[j] = iTemp;
}
}
}
}
void main()
{
int data[] = {10,9,8,7,6,5,4};
BubbleSort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"/n";
}
图示:
before_compare|one_turn|two_turn|three_turn|four_turn|five_turn|six_turn
10 10 10 10 10 10 4
9 9 9 9 9 4 10
8 8 8 8 4 9 9
7 7 7 4 8 8 8
6 6 4 7 7 7 7
5 4 6 6 6 6 6
4 5 5 5 5 5 5
通过上图可以看出,冒泡法形象的描述来,4这个元素就像一个气泡逐渐冒到上
面来了。
我们排序的有7个元素,最坏的情况全部倒序,4这个元素要冒上来需要6次。
因此,n个元素,最坏的情况,需要移动:1+2+3+ ...+(n-1)=1/2*n(n-1)次。
倒序(最糟情况)
第一轮:10,9,8,7->10,9,7,8->10,7,9,8->7,10,9,8(交换3次)
第二轮:7,10,9,8->7,10,8,9->7,8,10,9(交换2次)
第一轮:7,8,10,9->7,8,9,10(交换1次)
循环次数:6次
交换次数:6次
其他:
第一轮:8,10,7,9->8,10,7,9->8,7,10,9->7,8,10,9(交换2次)
第二轮:7,8,10,9->7,8,10,9->7,8,10,9(交换0次)
第一轮:7,8,10,9->7,8,9,10(交换1次)
循环次数:6次
交换次数:3次
上面我们给出了程序段,现在我们分析它:这里,影响我们算法性能的主要部分是
循环和交换,显然,次数越多,性能就越差。从上面的程序我们可以看出循环的
次数是固定的,为1+2+...+n-1。写成公式就是1/2*(n-1)*n。
现在注意,我们给出O方法的定义:
若存在一常量K和起点n0,使当n>=n0时,有f(n)<=K*g(n),则f(n) = O(g(n))。(呵呵,不要说没学好数学呀,对于编程数学是非常重要的!!!)
现在我们来看1/2*(n-1)*n,当K=1/2,n0=1,g(n)=n*n时,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)=O(g(n))=O(n*n)。所以我们程序循环的复杂度为O(n*n)。
再看交换。从程序后面所跟的表可以看到,两种情况的循环相同,交换不同。其实交换本身同数据源的有序程度有极大的关系,当数据处于倒序的情况时,交换次数同循环一样(每次循环判断都会交换),复杂度为O(n*n)。当数据为正序,将不会有交换。复杂度为O(0)。乱序时处于中间状态。正是由于这样的原因,我们通常都是通过循环次数来对比算法。
pp.sohu.com/u/178199931/wTO0j8AeHbD/pTO0TNYBW3g
pp.sohu.com/u/178199931/wTO0j8AeHbD/pTO0TNYBW3g
pp.sohu.com/u/178199931/wTO0b5Rmxt2
pp.sohu.com/u/178199931/wTO0itWuwaq
pp.sohu.com/u/178199931/wTO02FejEIq
pp.sohu.com/u/178199931/wTO0BOlwkGH
pp.sohu.com/u/178199931/wTO0nSxqlkp
pp.sohu.com/u/178199931/wTO0wjCdY1d
pp.sohu.com/u/178199931/wTO0LDlFxQj
pp.sohu.com/u/178199931/wTOYANgxaIM
pp.sohu.com/u/178199931/wTOYYqFcVsG
pp.sohu.com/u/178199931/wTOY62SvKGE
pp.sohu.com/u/178199931/wTOYZPW3Rvk
pp.sohu.com/u/178199931/wTOYb7kkaX2
pp.sohu.com/u/178199931/wTOYipyU5aj
pp.sohu.com/u/178199931/wTOY9oRfl2p
pp.sohu.com/u/178199931/wTOYQ6T5wJj
pp.sohu.com/u/178199931/wTOYowLJMJn
pp.sohu.com/u/178199931/wTOYw1AGtxX
pp.sohu.com/u/178199931/wTOY7ijNYSt
pp.sohu.com/u/178199931/wTOkxyYDjkv
pp.sohu.com/u/178199931/wTOkc65wbtH
pp.sohu.com/u/178199931/wTOkNrOQQTg
pp.sohu.com/u/178199931/wTOkYVAj7Jf
pp.sohu.com/u/178199931/wTOkMjO3ys1
pp.sohu.com/u/178199931/wTOkT157y4d
pp.sohu.com/u/178199931/wTOktvFBJFg
pp.sohu.com/u/178199931/wTOkmdGLfDx
pp.sohu.com/u/178199931/wTOkUfQxeOG
pp.sohu.com/u/178199931/wTOkyDtYEWE
pp.sohu.com/u/178199931/wTOkVkF1RdD
pp.sohu.com/u/178199931/wTOkBC8qaoA
pp.sohu.com/u/178199931/wTOkHkIRFWD
pp.sohu.com/u/178199931/wTOkomxtN8z
pp.sohu.com/u/178199931/wTOkLy6jAwf
pp.sohu.com/u/178199931/wTOkERyFMLN
pp.sohu.com/u/178199931/wTOkunfLhLL
pp.sohu.com/u/178199931/wTOhSj1ZEFj
pp.sohu.com/u/178199931/wTOheZ0Ar1X
pp.sohu.com/u/178199931/wTOh0WJufcN
pp.sohu.com/u/178199931/wTOhMYiVEWx
pp.sohu.com/u/178199931/wTOhTHoC4ag
pp.sohu.com/u/178199931/wTOhDJLTn2E
pp.sohu.com/u/178199931/wTOh3hSxLAc
pp.sohu.com/u/178199931/wTOhmFQ8UO0
pp.sohu.com/u/178199931/wTOh8jDwmRf
pp.sohu.com/u/178199931/wTOhUcaw0Mk
pp.sohu.com/u/178199931/wTOh2fhccIq
pp.sohu.com/u/178199931/wTOhO2TeeTJ
pp.sohu.com/u/178199931/wTOhnH6z6R0
pp.sohu.com/u/178199931/wTOhwdqamCf
2.交换法:
交换法的程序最清晰简单,每次用当前的元素一一的同其后的元素比较并交换。
#include <iostream.h>
void ExchangeSort(int* pData,int Count)
{
int iTemp;
for(int i=0;i<Count-1;i++)
{
for(int j=i+1;j<Count;j++)
{
if(pData[j]<pData[i])
{
iTemp = pData[i];
pData[i] = pData[j];
pData[j] = iTemp;
}
}
}
}
void main()
{
int data[] = {10,9,8,7,6,5,4};
ExchangeSort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"/n";
}
before_compare|one_turn|two_turn|three_turn|four_turn|five_turn|six_turn
10 9 8 7 6 5 4
9 10 10 10 10 10 10
8 8 9 9 9 9 9
7 7 7 8 8 8 8
6 6 6 6 7 7 7
5 5 5 5 5 6 6
4 4 4 4 4 4 5
从上面的算法来看,基本和冒泡法的效率一样。倒序(最糟情况)第一轮:
10,9,8,7->9,10,8,7->8,10,9,7->7,10,9,8(交换3次)第二轮:7,10,9,8->7,9,10,8->7,8,10,9(交换2次)第一轮:7,8,10,9->7,8,9,10(交换1次)循环次数:6次交换次数:6次其他:第一轮:8,10,7,9->8,10,7,9->7,10,8,9->7,10,8,9(交换1次)第二轮:7,10,8,9->7,8,10,9->7,8,10,9(交换1次)第一轮:7,8,10,9->7,8,9,10(交换1次)循环次数:6次交换次数:3次从运行的表格来看,交换几乎和冒泡一样糟。事实确实如此。循环次数和冒泡一样也是1/2*(n-1)*n,所以算法的复杂度仍然是O(n*n)。由于我们无法给出所有的情况,所以只能直接告诉大家他们在交换上面也是一样的糟糕(在某些情况下稍好,在某些情况下稍差)。
3.选择法:
现在我们终于可以看到一点希望:选择法,这种方法提高了一点性能(某些情况下)这种方法类似我们人为的排序习惯:
从数据中选择最小的同第一个值交换,在从省下的部分中选择最小的与第二个交换,这样往复下去。
#include <iostream.h>
void SelectSort(int* pData,int Count)
{
int iTemp;
int iPos;
for(int i=0;i<Count-1;i++)
{
iTemp = pData[i];
iPos = i;
for(int j=i+1;j<Count;j++)
{
if(pData[j]<iTemp)
{
iTemp = pData[j];
iPos = j;
}
}
pData[iPos] = pData[i];
pData[i] = iTemp;
}
}