zoukankan      html  css  js  c++  java
  • Even法生成排列

    1.    Even法生成排列

    1.1.算法描述

    Even算法的过程描述如下

    (1)求出最大的活动整数m

    (2)交换m和其箭头所掼向的与其相信的整数。

    (3)交换所有满足p>m的整数的p的方向。

    1.2.算法分析

    由于每个数字还带有方向这个属性,因些需要使用自己定义数据类型。本算法中用一个结构来表示,结构有两个域,一个代表值,一个代码方向。

    算法最大的难点在于,一是判断当前元素是否活动,二是需要找到最大的活动的元素。

    通过试验生成过程,可以发现,其中最活跃的元素就是最大的那个元素,因为每交换一个比它小的元素,它都会由不活动状态变成活动状态。因此,在算法的实现上,要格外关注最大的那个元素。事实上,整个算法主要是在将最大的那个元素进行移动。也对最大的那个元素的位置进行了标识。

    判断当前元素是否活动,有三种情况是不活动的:

    1. 该元素在第一位,并且指向左边。

    2. 该元素在最后一位,并且指向右边。

    3. 该元素在中间,并且指向的元素比它要大。

    通过这三个条件,就可判断当前元素是否活动的。

    考虑扩展性,可排列的元素可以不从0开始,也可以不连续。因为排列归根结底是对元素的下标进行排列。因些可考虑让用户自己定义打印算法。

      1#ifndef U8
      2#define U8 unsigned char
      3#endif // U8
      4
      5#define DIR_LEFT 0 // 箭头向左
      6#define DIR_RIGHT 1 // 箭头向右
      7
      8// 用于输出 一个排列
      9typedef void(*AdjustCallback)(void *constint size);
     10
     11// 一个排列列的元素,它包括数字和这个数字上箭头的方向
     12typedef struct Item
     13{
     14  int num;
     15  U8 direct; 
     16}
    ;
     17
     18// 默认输出排列的函数
     19void def_printarray(void *const array, int size)
     20{
     21  if(array == NULL)
     22    return;
     23  for(int i=0;i<size;i++)
     24  {
     25    cout<<((Item **)array)[i]->num<<' ';
     26  }

     27  cout<<endl;
     28}

     29
     30// 用Even方法生成排列的类
     31class Even
     32{
     33private:
     34  Item **array; // 一队排列数
     35  int size; // 排列数,表明是几排列。如5排列
     36private:
     37  void initarray(); // 初始化排列
     38  void deletearray(); // 删除排列的元素
     39  void printarray(); // 打印排列元素
     40  U8 isMaxActive(Item *item); // 判断最大的元素是否活动
     41  U8 isItemActive(int index); // 判断当前元素是否活动
     42  U8 forward(int index); // 数列元素的一次交换,它是将当前元素与前面(或后面)的元素进行交换,具体根据箭头来判断
     43  void swap(Item **p1, Item **p2); // 具体的交换操作
     44  int getMaxActiveIndex(); // 获取数列中,最大的活动的元素
     45  void adjustPrimar(int index); // 将比当前元素大的元素的方向换向
     46public:
     47  Even();
     48  Even(int size);
     49  virtual ~Even();
     50  void gen(); // 产生排列的主函数
     51  inline int getsize()const;
     52  inline void setsize(int size);
     53  
     54  AdjustCallback _printarray;  // 打印数列的回调函数,支持用户自定义
     55}
    ;
     56
     57Even::Even()
     58{
     59  array = NULL;
     60  size = 0;
     61  _printarray = &def_printarray;
     62}

     63
     64Even::Even(int size)
     65{
     66  array = NULL;
     67  this->size = size;
     68  _printarray = &def_printarray;
     69}

     70
     71Even::~Even()
     72{
     73  //
     74}

     75
     76int Even::getsize()const 
     77{
     78  return size;
     79}

     80
     81void Even::setsize(int size)
     82{
     83  deletearray();
     84  this->size = size;
     85}
     
     86
     87void Even::printarray()
     88{
     89  if(array == NULL)
     90    return;
     91  for(int i=0;i<size;i++)
     92  {
     93    cout<<array[i]->num<<' ';
     94  }

     95  cout<<endl;
     96}

     97
     98void Even::deletearray()
     99{
    100  if(array == NULL)
    101    return;
    102  
    103  for(int i=0;i<size;i++)
    104    delete array[i];
    105  delete []array;
    106  array = NULL;
    107}

    108
    109void Even::initarray()
    110{
    111  if(size <= 0)
    112    return;
    113    
    114  deletearray();
    115  
    116  array = new Item* [size];
    117  Item *curr;
    118  
    119  // 
    120  for(int i=0;i<size;i++)
    121  {
    122    curr = new Item; //(Item *)malloc(sizeof(curr));
    123    curr->num = i;
    124    curr->direct = 0//<-
    125    array[i] = curr;
    126  }

    127}

    128
    129void Even::gen()
    130{
    131  if(size <= 0)
    132    return;
    133  initarray();
    134  
    135  Item &max = *(array[size - 1]);
    136  int currindex = size - 1;
    137  int activeindex = -1;
    138  U8 dir;
    139  
    140  //printarray();
    141  _printarray(array, size);
    142  do{
    143      //  
    144      while(isMaxActive(&max))
    145      {
    146        //exchange
    147        dir = forward(currindex);
    148        //printarray();
    149        _printarray(array, size);
    150        // adjust
    151        if(dir == DIR_LEFT)
    152          currindex--;
    153        else currindex++;
    154      }

    155      
    156      // 
    157      activeindex = getMaxActiveIndex();
    158      if(activeindex == -1)
    159       break;
    160       
    161      dir = forward(activeindex);
    162      
    163      // 
    164      if(dir == DIR_LEFT)
    165        activeindex--;
    166      else activeindex++;
    167      adjustPrimar(activeindex);
    168      //printarray();
    169      _printarray(array, size);
    170      
    171  }
    while(activeindex != -1);
    172}

    173
    174U8 Even::isMaxActive(Item *item)
    175{
    176  return (item->direct == DIR_LEFT && (item != array[0])) ||
    177    (item->direct == DIR_RIGHT && (item != array[size - 1]));  
    178}

    179
    180U8 Even::isItemActive(int index)
    181{
    182  if(index == 0 && array[index]->direct == DIR_LEFT)
    183    return 0;
    184  else if(index == size-1 && array[index]->direct == DIR_RIGHT)
    185    return 0;
    186  if(array[index]->direct==DIR_LEFT && array[index] > array[index-1])
    187    return 1;
    188  if(array[index]->direct==DIR_RIGHT && array[index] > array[index+1])
    189    return 1;
    190  return 0;
    191}

    192U8 Even::forward(int index)
    193{
    194  Item *item = array[index];
    195  if(item->direct == DIR_LEFT && index > 0)
    196  {
    197    swap(&array[index], &array[index - 1]);
    198    return DIR_LEFT;
    199  }

    200  else if(item->direct == DIR_RIGHT && index < size - 1)
    201  {
    202    swap(&array[index], &array[index + 1]);
    203    return DIR_RIGHT;
    204  }

    205  return 0;
    206}

    207
    208void Even::swap(Item **p1, Item **p2)
    209{
    210  Item *tmp = *p2;
    211  *p2 = *p1;
    212  *p1 = tmp;
    213}

    214
    215int Even::getMaxActiveIndex()
    216{
    217  int index = -1;
    218  Item *currmax = NULL;
    219  for(int i=0;i<size;i++)
    220  {
    221    if(isItemActive(i) && (currmax == NULL || currmax->num < array[i]->num))
    222    {
    223      index = i;
    224      currmax = array[i];
    225    }

    226  }

    227  return index;
    228}

    229
    230void Even::adjustPrimar(int index)
    231{
    232  for(int i=0;i<size;i++)
    233  {
    234    if(i==index) continue;
    235    if(array[i]->num > array[index]->num)
    236      array[i]->direct = (array[i]->direct == DIR_LEFT? DIR_RIGHT:DIR_LEFT);
    237  }

    238}

    239
    240void test1();
    241void test2();
    242void my_printarray(void *const array, int size);
    243
    244int main(int argc, char *argv[])
    245{
    246/*  int size, selcount;
    247  cin>>size;
    248  if (size <= 2)
    249    return -1;
    250    
    251  Even e;
    252  e.setsize(size);
    253  e.gen();
    254  */

    255// test1();
    256   test2();
    257  system("PAUSE");    
    258  return 0;
    259}

    260
    261void test1()
    262{
    263  cout<<"请输入排列的阶数:";
    264   int size, selcount;
    265  cin>>size;
    266  if (size <= 2)
    267    return;
    268    
    269  Even e;
    270  e.setsize(size);
    271  e.gen(); 
    272}

    273
    274int arrTarget[] = {12955341};
    275void test2()
    276{
    277  cout<<"原数列为:";
    278  for(int i=0;i<sizeof(arrTarget)/sizeof(int);i++)
    279    cout<<arrTarget[i]<<",";
    280  cout<<endl;
    281  
    282  Even e;
    283  e.setsize(5);
    284  e._printarray = &my_printarray;
    285  e.gen();
    286  cout<<endl;
    287}

    288
    289void my_printarray(void *const array, int size)
    290{
    291  int index;
    292  for(int i=0;i<size;i++)
    293  {
    294    index = ((Item **)array)[i]->num;
    295    cout<<arrTarget[index]<<' ';
    296  }

    297  cout<<endl;
    298}
  • 相关阅读:
    maquee 无缝轮播
    pascal语言中学版整理
    SPFA
    Bellman—Ford算法思想
    序列化
    random 模块 时间模块(time) sys模块 os模块
    1、正则表达式
    1、__del__ 2、item系列 3、__hash__ 4、__eq__
    小总结 面向对象
    1、面向对象内置函数 2、反射 3、内置方法
  • 原文地址:https://www.cnblogs.com/qkhh/p/1053277.html
Copyright © 2011-2022 走看看