冒泡法
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";
}
倒序 ( 最糟情况 )
第一轮: 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) 。乱序时处于中间状态。正是由于这样的
原因,我们通常都是通过循环次数来对比算法。
这是最原始,也是众所周知的最慢的算法了。他的名字的由来因为它的工作看来象是冒泡:
#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";
}
倒序 ( 最糟情况 )
第一轮: 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) 。乱序时处于中间状态。正是由于这样的
原因,我们通常都是通过循环次数来对比算法。