一种奇特有效的新排序法__张仰彪第三排序法问世, 欢迎大家来评判
张仰彪第三排序法
张仰彪第三排序法的原理:它将待排序数组内的数据以两个为一对进行处理,排序的过程可以分成两种不同的步骤:
a步骤是将各对数据进行比较和交换。
b步骤是在各对数据之间进行比较和交换。
a、b两种步骤交替进行,直到发现其中一个步骤完成后,接下来的另一个步骤没有交换数据,此时数组内各对数据自身都已有序,并且各对数据之间也已经有序,排序完毕。
这个排序法如果要遇到麻烦,那一定是在待排序数组内数据总数的奇偶上,因为如果数组内数据的总数是偶数,那就正好可以分成一对一对的,这种情况似乎比较好处理。但如果数组内数据的总数是奇数,那么按对划分数据时最后必然有一个数据是单个的,无法成对,这种情况似乎较难处理,或者需要多写很多行代码去单独处理这种情况,其实不然。
由于本排序法的独特原理,它的两个交替的排序步骤a和b其实是类似的两个处理过程,只是它们所处理的数据沿着数组的长度方向正好错开了一个数据的位置,这对于处理数据的总数是奇数的数组反而更有利,所以在for( )循环的循环上限上无论奇、偶数组都是i< =n-1,这一点至关重要,提请各位看官仔细体会这一点。
下面给出张仰彪第三排序法的C语言代码:
-----------------------------------------------------------------------------------------------------
# include < stdio.h >
void main ( )
{
int a [10];
int i; /* 记录排序的当前位置,并用于输入输出 */
int j= -1 , t= -1; /* 记录一次排序循环中交换数据的次数 */
int temp; /* 数据交换时的存储中介 */
printf ( " Input 10 numbers:\n" );
for ( i=0;i < 10;i++ ) /* 输入任意10个整数 */
scanf ( " %d",&a[i] );
printf ( " \n" );
while(j>0 || t>0) /* 如果数据对内部排序或数据对之间排序曾交换数据*/
{
j = 0; /* 先清零 */
for ( i = 0;i < =8;i +=2 ) /* 从头至尾,逐对排序 */
{
if ( a[i] > a[i+1] )
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
j++; /* 记住有了一次数据交换 */
}
}
if(j= =0 && t!= -1) break; /* t= -1说明是头一个排序步骤,此时即使数
据对内部有序,还要检查数据对之间是否有序*/
t=0; /* 先清零 */
for ( i = 1;i < =8;i +=2 ) /* 从第二至尾,在各对数据之间排序 */
{
if ( a[i] > a[i+1] )
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
t++; /* 记住有了一次交换 */
}
}
if(t= =0) break;
}
printf ( " The sorted numbers is:\n" );
for ( i=0;i < 10;i ++ ) /* 输出排好序的10个整数 */
printf ( " %d",a[i] );
printf ( " \n" );
}
--------------------------------------------------------------------------------------------------
下面是本排序法的算法例子。
{ 4, 5, 2, 4, 1, 3,0,2, 2,0 }
第1步: 数据对之内排序,只有最后一对数据“2和 0”要进行交换,
数组现在变为:
{ 4, 5, 2, 4, 1, 3,0,2, 0,2 }
第2步: 数据对之间排序,各数据对之间都要进行交换,
数组现在变为:
{ 4, 2, 5, 1, 4, 0,3,0, 2,2 }
第3步: 数据对之内排序,前四对数据要进行交换,
数组现在变为:
{ 2, 4, 1, 5, 0, 4,0,3, 2,2 }
第4步: 数据对之间排序,各数据对之间都要进行交换,
数组现在仍为:
{ 2, 1, 4, 0, 5, 0,4,2, 3,2 }
第5步: 数据对之内排序,各对数据都要进行交换,
数组现在变为:
{ 1, 2, 0, 4, 0, 5,2,4, 2,3 }
第6步: 数据对之间排序,各数据对之间都要进行交换,
数组现在变为:
{ 1, 0, 2, 0, 4, 2,5,2, 4,3 }
第7步: 数据对之内排序,各数据对之间都要进行交换,
数组现在变为:
{ 0, 1, 0, 2, 2, 4,2,5, 3,4 }
第8步: 数据对之间排序,只有第二和第三数据对之间不需要进行交换,
数组现在变为:
{ 0, 0, 1, 2, 2, 2,4,3, 5,4 }
第9步: 数据对之内排序,第四、第五数据对内部要进行交换,
数组现在变为:
{ 0, 0, 1, 2, 2, 2,3,4, 4,5}
第10步: 数据对之间排序,所有数据对之间都不需要进行交换
数组现在仍为:
{ 0, 0, 1, 2, 2, 2,3,4, 4,5}
发现一个排序步骤没有进行数据交换,排序完毕。
-----------------------------------------------------------------------------------------------------
可以看出,此排序法的空间效率与冒泡排序法是相当的,至于时间效率经过计算,与冒泡排序法也是基本相同的,以待排序数组{6,5,4,3,2,1,0}为例:
这个数组对于冒泡排序法和本排序法都是最坏情况,冒泡排序法处理此数组需要六次排序大步骤,要比较数据6+5+4+3+2+1=21次,交换数据也是21次,本排序法同样如此。经过演算,本排序法处理上述完全倒置排序数组需要八次排序大步骤,要比较数据24次,交换数据21次。由此可见二者相差无几。
而且此排序法具有很高的智能,尤其对有序数组,两次循环后就可以发现所有数据对的内部和数据对之间都不需要交换,从而判定此待排序数组已经有序,而立即结束排序。
这一点尤其适合银行、社保等部门内用来处理海量的ID号等数据,这些数据在99.99%的概率下是有序的,但为了万无一失也要进行排序。此时本排序法将是最合适的,因为在99.99%的情况下它只循环两次就结束,比任何一种现有的排序法都快。
本排序法原理极其简单、独特,同时空间效率和时间效率都不低,并且具有一定的智能,是一种很好的新排序法,值得关注。
简单就是美。
< 完 >