关于一道1到N自然数排序的华为面试题

 在网上逛某论坛时,发现一所谓的高手贴了这样一道题,说是华为的面试题,如下:
有N个大小不等的自然数(1--N),请将它们由小到大排序。  
要求程序算法:时间复杂度为O(n),空间复杂度为O(1)。
高手经过一番分析后,说该题其实很简单,给出了答案如下:

void    sort( int    e[],    int    n)   
{   
    
int   i;   
    
int   t;   /*临时变量:空间复杂度O(1)*/ 

    
for   (i=1;   i <n+1;   i++)   /*时间复杂度O(n)*/   
     
{   
          t   
=   e[e[i]];   /*下标为e[i]的元素,排序后其值就是e[i]*/   
          e[e[i]]   
=   e[i];   
          e[i]   
=   t;   
     }
   
}
 

看了看总觉得不大妙,用他这个算法写了个程序试了下,数组{5,4,3,1,2}排序完之后是{2,1,3,4,5},根本没有达到效果,一时有些迷茫.仔细想了想,虽然该高手的分析没有问题,但在实现上忽略了一些东西,以上算法中每次赋值只是保证了e[e[i]]的正确,却无法保证e[i]的正确,之后i值变为i+1,该次赋值就结束了,所以才会出现问题。
思考良久,没有想出正确的来,看来华为还是有些难度的。
网上查了下,结果让我很郁闷,许多人都是把上面的解法直接转贴过来,根本不在乎其中内容的正确性,估计连脑子也没过就直接贴上去了,最让我无法忍受的是某些装B的高手。
煞有介事地冠之以题目“从华为一道面试题浅谈计算机专业在校大学生该如何学习专业课程”,然后从就业形势严峻谈起,引出该题目,还来了一句很自信的话“简单一道排序题,考倒多少读书人!”,然后分析该题,最后说通过这个题谈谈如何学习专业课程,还建议多在基础知识方面下工夫,有条件的多做习题、多上机、勤思考,多看看同一个问题其他人是怎么解决的,等等站在高手角度教育人的一番话。
于是期待成为编程高手的我耐心看完了这裹脚布一般的大论,再看他给出的解法如下:

void  sort( int  e[],  int  n)
{
 
int i;
 
int t; /*临时变量:空间复杂度O(1)*/

 
for (i=1; i<n+1; i++/*时间复杂度O(n)*/
 
{
  t 
= e[e[i>/*下标为e[i]的元素,排序后其值就是e[i]*/
  e[e[i
> = e[i];
  e[i] 
= t;
 }

}


void  main()

 
#define MAX 10
 
int i, a[MAX+1]; 
 
 printf(
"Input the number from 1 to %d: ",MAX);
 
for (i=1; i<MAX+1; i++)
 
{
  scanf(
"%d",&a[i]);
 }

  
 sort(a,MAX);

 printf(
" ====sort over==== ");
 
for (i=1; i<MAX+1; i++)
 
{
  printf(
"%d ",a[i]);
 }


 printf(
" ");
 system(
"pause");
}

靠,怎么和最上面的算法一样?上面的算法根本不对啊!我本来懒得说什么,但还是忍不住。
不知该高手在建议“多上机”的同时是否上机亲自验证了一下自己的算法?不知该高手在建议“勤思考”的同时是否把这个题看得很简单但还是认真思考了?以自己的这种不负责态度还如此这样教育新人,是自以为是,更是误人子弟!要是我没仔细想就按这个记下来了,以后岂不是……
闲话不扯了,接着说这道题,我这个菜鸟虽然知道上面的算法不对,可自己也想不出什么好的改进方法来,幸好我又百度到了一个论坛,该论坛中有人给出的解答如下:

int  cnt  =   0 ; // 辅助变量,不是算法组成部分

void  sort( int  arr[],  int  n)

{

 
int t;  /*临时变量:空间复杂度O(1)*/ 

 
//可以证明这个算法每次交换必然将一个数字正确安排到位,而且最多只有N次交换。 

 
//具体体现在cnt的值上,所以虽然是二重循环仍然是时间复杂度O(n)

 
for (int i = 1; i <= n; i++)

 
{

  
while(arr[i] != i)

  
{

   t 
= arr[arr[i]];

   arr[arr[i]] 
= arr[i];

   arr[i] 
= t;

   
++cnt;

  }


 }


}
又来到CSDN上面发帖问,也有人如此为我解答,算出来的结果没有问题,根据给出的解释,复杂度也应该符合要求,该问题应该就是如此答案了吧。如果您有什么新的见解,请不吝赐教。
最后再BS一下自以为是的所谓高手,还有那些只顾埋头转贴的人……

你可能感兴趣的:(基础)