记10月11北航IGT笔试题—在一个array本身上排序

题目要求是这样的:

          给一个数组,由三种字符组成,R,G,B,那么把这个数组重新排序,所有的R在最前面,所有的G在其次,所有的B在最后。排序要在O(n)的复杂度下完成,

不允许新身亲数组作为临时变量,不允许遍历数组多次。写出一种算法。

        我的思路是这样的,假如一个数组为:RGGBGRBGRGGBBGGBRB......

                                   

                                 
   定义四个指针,A,B从开始第一个非R的字符,C,D指向从开始第一个非B的字符。然后B向前移动,每次移动一位,如果该位置的字符为“R”那边把这个值变为A指针指向的值,而A指针指向的值变为R(实际上是A和B的值互换,使前面都是R),然后A的位置既然为“R”那么A指针向前移动,指向不是R的位置。同时,C也向前移动,每次移动一位,如果所指的位置的字符为“B”,那么D指针的值和C指针的值互换。(使后面都是B),然后D的位置既然是B,那么D指针向前移动,指向非“B”的位置。  

   什么时候完成这个算法呢?这是我在笔试时没考虑完全的地方,我开始认为,B向前移动到D指针的位置(后面全是B)了,或者C移动到A指针的位置(前面全是R)即可。这两者是‘||’的关系,实际上是不对的,B移动到D的位置,只能说明D前面的R全部移到了数组的开始位置,而A指针之后的B仍然没有全部移动到结尾处。所以只有满足,C指向A的位置,和B指向D的位置同时满足,才可以结束算法。

下面是代码:

void sortRGBarray(char *array,int length)
{
  int a,b=0;
  int c,d=length-1;
  int i=0;
  int j=length-1;
  while(array[i]=='r')
      {
       a++;
       b++;
       i++;
       }
  while(array[length-1]=='B')
     {
     c--;
     d--;
     j--;
     } 
     for(;a!=d&&c!=b;b++,c--)
      {
       if(array[a]=='r')
         a++;
       if(array[b]=='r')
             {array[b]=array[a];
                   array[a]='r' ;  }
       if(array[c]=='b')
                {array[d]=array[c];
                    array[c]='b';} 
        }        

      当然,这只是我的个人想法,期待有人有更好的算法。。。虽然这个博客看的人不多。。。

 

 

posted @ 2012-10-11 23:27  孙铭泽  Views(645)  Comments(0)    收藏  举报