原始地址:C / C++算法学习笔记(5)-选择法
选择法:
现在我们终于可以看到一点希望:选择法,这种方法提高了一点性能(某些情况下)这种方法类似我们人为的排序习惯:
从数据中选择最小的同第一个值交换,在从省下的部分中选择最小的与第二个交换,这样往复下去。
#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;
}
}
void main()
{
int data[] = {10,9,8,7,6,5,4};
SelectSort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"/n";
}
该排序法的图示如下;
i=0时: iTemp = pData[0]=10;iPos = i=0;
j=1 ;
pData[j]<iTemp ---> pData[1]=9<10;
iTemp=pData[1]=9;
ipos=j=1;
j++=2
j=2;
pData[j]<iTemp----> pData[2]=8<9;
iTemp=pData[2]=8;
ipos=j=2;
j++=3
. . .
j=6;
pData[j]<iTemp----> pData[6]=4<5;
iTemp=pData[6]=4;
ipos=j=6;
j++=7;
pData[6]=Pdata[0];
pData[0]=4;
比较前 | 第一次 | 第二次 | 第三次
10 4 4 4
9 9 5 5
8 8 8 6
7 7 7 7
6 6 6 8
5 5 9 9
4 10 10 10
由上面可以看到选择排序法并没有在一开始就交换数据,而是用第一个数据去和所有的数据比较,
如果第一个数据小于第二个数据,那么,先把第二个数据放到一个临时变量里面,同时记录这个较小
的数据在待排序的集合中的位置。再用该集合中的下一个数据和我们之前放在临时变量中的数据比较。
也就是我们目前认为最小的数据比较,如果比我们之前选出来的数据小,那么再替换该变量。如果比这个
数据大,则继续用下一个数据来比较。知道所有的数据都比较完为止。到这时,临时变量里面访的就是
最小的数据了。我们把这个数据和第一个数据做对换。此时,最小的元素排到了第一位。
倒序(最糟情况)
第一轮:10,9,8,7->(iTemp=9)10,9,8,7->(iTemp=8)10,9,8,7->(iTemp=7)7,9,8,10(交换1次)
第二轮:7,9,8,10->7,9,8,10(iTemp=8)->(iTemp=8)7,8,9,10(交换1次)
第一轮:7,8,9,10->(iTemp=9)7,8,9,10(交换0次)
循环次数:6次
交换次数:2次
其他:
第一轮:8,10,7,9->(iTemp=8)8,10,7,9->(iTemp=7)8,10,7,9->(iTemp=7)7,10,8,9(交换1次)
第二轮:7,10,8,9->(iTemp=8)7,10,8,9->(iTemp=8)7,8,10,9(交换1次)
第一轮:7,8,10,9->(iTemp=9)7,8,9,10(交换1次)
循环次数:6次
交换次数:3次
遗憾的是算法需要的循环次数依然是1/2*(n-1)*n。所以算法复杂度为O(n*n)。
我们来看他的交换。由于每次外层循环只产生一次交换(只有一个最小值)。所以f(n)<=n
所以我们有f(n)=O(n)。所以,在数据较乱的时候,可以减少一定的交换次数。