双向冒泡排序 和 单向冒泡排序 算法分析比较

假设单向冒泡排序也是 在如果没有交换发生的情况下则终止(即changeFlag==false的情况下).

以下是单向冒泡排序

template<class T> void SSearch<T>::Ascendsort() { T t; bool changeFlag=false; for(int i=0;i<len;i++) //pop sort ,every time ,it sorted (i+1) numbers at the end of the number line { changeFlag=false; for(int j=0;j<len-i-1;j++) { if(ST[j].key>ST[j+1].key) { t=ST[j].key; ST[j].key=ST[j+1].key; ST[j+1].key=t; if(!changeFlag) changeFlag=true; } } if(!changeFlag) break; } cout<<"Ascend SORT SUCCESS|!/n"; } 

1、最差情况:假设输入打下为n

1)单向排序

  需要进行n次外循环,n次changeFlag=false;赋值和后面的比较判断,即2*n。每次外循环有n-i-1次内循环,(内循环总数为0+1+2+…+(n-1)=n*(n-1)/2次循环。每次内循环需要进行两次比较,三次赋值,(2+3)*n*(n-1)/2.

所以最差时间复杂度为2*n+5*n*(n-1)/2=5/2*n^2-n/2=o(n^2);

2)双向排序

template<class T> void SSearch<T>::BiDirectionAscendSort() //双向冒泡排序 { T t; int pos[2]; pos[0]=0; pos[1]=len-1; int d=1; // d 步长,正向冒泡为1,反向冒泡为-1 bool changeFlag=false; int change=len-1; //记录最后一次进行交换的位置 do { changeFlag=false; for(int i=pos[(1-d)/2];i!=pos[(1+d)/2];i=i+d) { if(d>0) //正向 { if(i==len-1) //最后一位不与其后面一位比较 break; if(ST[i].key>ST[i+d].key) { t=ST[i].key; ST[i].key=ST[i+d].key; ST[i+d].key=t; if(!changeFlag) changeFlag=true; change=i; } } else { if(i==0) //最前一位不与-1位比较 break; if(ST[i].key<ST[i+d].key) { t=ST[i].key; ST[i].key=ST[i+d].key; ST[i+d].key=t; change=i; if(!changeFlag) changeFlag=true; } } Display();//看看现在排序情况 } if(changeFlag) { pos[(1+d)/2]=change; cout<<"Change at/t"<<change<<"/n"; if(d>0) cout<<"----正向冒泡一次结束/n"; else cout<<"----反向冒泡一次结束/n"; } else cout<<"NO CHANGE!! END NOW/n"; d=-d; }while(changeFlag); } 

//除去那些打印的附加信息,需要进行n/2上取整 次数的do--while循环,需要进行两次赋值和一次比较,比较内部还有一次赋值,即4*n/2,每次do-while内部需要一次for循环,每次for循环4次赋值和4次比较,而第一次for循环次数为0到n-2,第二次for循环(反向)次数为n-3到0,第三次for循环次数为1到n-3,第四次为n-4到2。所以为(n-1)+(n-2)+(n-3)+…+(1)=n*(n-1)/2.

所以总共:4*n/2+8*n*(n-1)/2=4*n^2-2*n=o(n^2)。但是如果去除

在最差情况下还不如 单向冒泡,但是都是o(n^2)的时间复杂度。

 

但是双向的优点在于每次能够记住最后一次交换的位置,而且两边都可以记住,也就是说假设10个数中, 只有少数几个数是乱的,假设1到10,2,3,4,5,1,10,6,7,8,9。单向排序需要5次(1到最前面需要4次+依次无交换检测)循环,使得最大的10,次大的9,……最小的1依次在各自位置。

双向需要3次(1到最前面一次,10到最后面1次,再加上一次无交换检测)。优点在于少量的打乱的情况下,双向能够记录当前的交换的位置,缩短循环的区间。

单向是:n-1,n-2,n-3….0

双向可以是:n-1,n-2(前两次),其他的可以是很小的区间pos[0]到pos[1],区间最大值等于单向,但是基本上都小于单向的。    

你可能感兴趣的:(双向冒泡排序 和 单向冒泡排序 算法分析比较)