一个很大的数组,如何高效的把零都移到前面

   1:   /*
   2:   *discription:给定一组数,将零全部排到最后,将非零元素排在最前,华为面试
   3:   *autor:justinzhang
   4:   *Email:uestczhangchao@gmail.com
   5:   *Established:2011年2月8日21:13:47
   6:   *Revised1:2011年4月24日15:57:22 
   7:   *Revised2:2011年5月10日15:21:54,受到算法导论快速排序的启发,(p85)
   8:   *                                利用快速排序中用来寻找支点的算法来完成任务
   9:   */
  10:   
  11:   
  12:   #include <iostream>
  13:   using namespace std;
  14:   #define arraysize(type, name) (sizeof(name) / sizeof(type))
  15:   
  16:   
  17:   /*http://www.iteye.com/topic/684511 这个帖子是讲如何将0元素移动到最前面,非零元素移动到最后面的*/
  18:   
  19:   /*
  20:   *nonezerofirst()和zerofirst()采用了不同的思想,具体参见源代码了. 
  21:   *
  22:   */
  23:   
  24:   
  25:   /* 打印数组里的元素*/
  26:   void display(int data[], int len)
  27:   {
  28:       for(int i=0; i<len; i++)
  29:           cout << data[i] << endl;
  30:   }
  31:   
  32:   /*用算法导论中快速排序算法找支点的思想来完成将0元素集中到最前面
  33:   *使用这个思想可以解决把具有某一性质(0,非零,负数,正数等等)
  34:   *的元素移动到数组的末尾或者最前面的问题
  35:   */
  36:   
  37:  void quickmove_zerofirst(int data[], int len)
  38:  {
  39:      int i = -1;
  40:      
  41:      /*data中元素下标从0开始,故倒数第1个元素的下标为len-1;
  42:      *从左向右扫描数组,如果发现0就与最前边由i记录的位置处元素交换
  43:      */
  44:      for(int j=0; j<=len-1;j++)
  45:      {
  46:          if(data[j]==0)
  47:          {
  48:              i++;
  49:              data[j] = data[i];
  50:              data[i] = 0;
  51:          }
  52:      }
  53:      cout << "in quickmove_zerofirst" << endl;
  54:       display(data,len);
  55:       cout << "end of quickmove_zerofirst" << endl;
  56:  }
  57:   
  58:   
  59:  /*用算法导论中快速排序算法找支点的思想来完成将0元素集中到最后面*/
  60:  void quickmove_zerolast(int data[], int len)
  61:  {
  62:      //data中元素下标从0开始,故倒数第1个元素下一个元素为len,
  63:      //此处为刚好为数组越界的位置,这样做主要是为了方便循环的处理的统一
  64:      //i记录的是最右边0元素序列的最左边位置
  65:      int i=len;
  66:      for(int j=len-1; j>=0;j--)
  67:      {
  68:          //如果在扫描过程中发现了0元素,就把它交换到数组右边0元素序列的最左边
  69:          if(data[j]==0)
  70:          {
  71:              i = i-1;
  72:              data[j] = data[i];
  73:              data[i] = 0;
  74:          }
  75:      }
  76:      cout << "in quickmov_zerolast" << endl;
  77:      display(data,len);
  78:      cout << "end of quickmov_zerolast" <<endl;
  79:  }
  80:   
  81:   
  82:   
  83:   
  84:   /*
  85:   *该函数将0元素移动到数据的最前面,非零元素移动到队列的最后面。 
  86:   *实现方法是:从数组的最后一个元素向前扫描,记住非零元素串最右边的位置,
  87:   *程序中用high来表示,结束扫描的时候[0,high]之间的数全部清零就可以完成任务。 
  88:   */
  89:   void zerofirst(int data[], int len)
  90:   {
  91:        //自右向左扫描,将所有非零元素紧凑到右侧  
  92:        int low, high;
  93:        for(low = len -1,high = low; low >=0; low--)
  94:        {
  95:                if(data[low]!=0)
  96:                {
  97:                     data[high] = data[low];
  98:                     high--;//更新紧凑序列的最左侧元素   
  99:                }
 100:        } 
 101:        
 102:        for(;high>=0; high--)
 103:        {
 104:            data[high] = 0;
 105:        }
 106:        cout << "in zero first" << endl;
 107:         display(data, len);
 108:         cout << "end of zero first" << endl;
 109:        
 110:   } 
 111:   
 112:   void nonzerofirst(int data[], int len)
 113:   {
 114:      //自左向右扫描,将非零元素紧凑到最左边 
 115:      int j = 0;
 116:      for (int i = 0; i < len; i++) { 
 117:          //加入下面的判断是为了记录下非零元素串最右边的位置 
 118:          if(data[i] != 0)
 119:                  j++; //更新紧凑序列最右边的元素位置 
 120:          if (data[i] == 0 && i != len - 1 && data[i + 1] != 0) {   
 121:              data[j++] = data[i + 1];   
 122:              data[i + 1] = 0;   
 123:          }   
 124:      }   
 125:      cout << "non zero first " << endl;
 126:      display(data, len);
 127:      cout << "end of non zero first " << endl;
 128:   }
 129:   
 130:   int main()
 131:   {
 132:   int a[] = { 4,4,0, 4, -7, 2, 160, 0,0,0,0, 34, 21, 0, 19, 107 };   
 133:   int j = 0;   
 134:   int tmp = arraysize(int, a);
 135:   cout << sizeof(a) << endl; 
 136:   cout << "sizeof(a)" << tmp << endl;
 137:   quickmove_zerofirst(a,tmp);
 138:   quickmove_zerolast(a,tmp);
 139:   
 140:   zerofirst(a, tmp);
 141:   nonzerofirst(a, tmp); 
 142:   system("pause");
 143:  }

posted @ 2012-04-15 20:34  justinzhang  阅读(2078)  评论(0编辑  收藏  举报