算法与数据结构:荷兰国旗问题

问题:给定一个无序数组arr,元素只有0,1,2三种取值

要求:重新排列数组,使得所有值为0的元素在数组左边,值为1的元素在数组右边,值为2的元素在数组中间。

思路:设三种数组索引,mid, left, right, 假设一种中间过程,[0, left) 区间内元素的值为0,(right, len-1] 区间内元素为1, [left, mid)区间内元素为2,[mid, right] 区间内元素未排序

arr[mid]的值分为3种情况:

1. arr[mid] == 2, 为保持中间状态,mid向右移动一步即可

2. arr[mid] == 0, 因为arr[left]为2, 交换arr[mid]和arr[left],  left和mid各向右移动一步

3. arr[mid] == 1, 交换arr[right]和arr[mid], right向左移动一步

依据上述的迭代方法,最终可以使得[mid, right]区间为空,到这里时,迭代完成。此时mid>right。因此只要mid<=right就必须不断迭代。

依据上述思路,可以很快写出代码:

void rearrange(int* arr, int len)
{
  if (! arr || len == 0)
    return;

  int right = len - 1;
  int left = 0;
  int mid = 0;
  while (mid <= right)
  {
    int val = arr[mid];
    if (val == 0)
    {   
      swap(arr[left], arr[mid]);
      left++;
      mid++;
    }   
    else if (val == 2)
    {   
      mid++;
    }   
    else 
    {   
      swap(arr[mid], arr[right]);
      right--;
    }   
  }
}

 

posted @ 2017-04-12 15:12  后端技术小屋  阅读(875)  评论(0编辑  收藏  举报