調整數組順序使奇數位於偶數以前

問題:調整數組順序是奇數位於偶數以前。ios

    若是不考慮時間複雜度,最簡單的思路是從頭開始掃描數組,每當遇到一個偶數,就將其取出,而後把該偶數後面的全部數字往前移一位,而後將這個偶數放在數組的最後一個空位上。此時,算法的時間複雜度是 O(N^2)。算法

    該題目要求把奇數放在數組的前半部分,偶數放在數組的後半部分,所以,全部的奇數都應該位於偶數以前。也就是說,若是在掃描數組的時候,發現偶數位與奇數的前面,則將奇數與偶數互換位置。數組

    【快慢指針】:所以咱們能夠維護兩個指針,第一個指針初始化的時候指向數組的第一個數字,它只向前移動;第二個指針初始化的時候指向數組的最後一個數字,它只向後移動。第一個指針老是位於第二個指針的前面。若是第一個指針指向的數字是一個偶數,而且第二個指針指向的是一個奇數,則就交換這兩個數字。框架

注意:函數

    a)把第一個指針指向第一個數字,把第二個指針指向最後一個數字spa

    b)向後移動第一個指針,直至其指向一個偶數;此時,第二個指針向前移動,直至指向一個奇數指針

    c)交換兩個指針指向的數字io

    d)繼續重複 b),直至第二個指針位於第一個指針的前面,此時,說明全部的奇數都位於偶數的前面。算法結束。stream

//調整數組順序,是奇數位於偶數以前
#include<iostream>
using namespace std;
擴展

void ReorderOddEven(int *pData, int length)
{
 if(pData == NULL || length <= 0)
  return;
 int *pBegin = pData;
 int *pEnd = pData + length - 1;
 while(pBegin < pEnd)
 {
  while(pBegin < pEnd && (*pBegin & 0x1) != 0)
   pBegin++;
  while(pBegin < pEnd && (*pEnd & 0x1) == 0)
   pEnd--;
  if(pBegin < pEnd)
  {
   int tmp = *pBegin;
   *pBegin = *pEnd;
   *pEnd = tmp;
  }
 }
}

int main()
{
 int data[5] = {1, 2, 3, 4, 5};
 ReorderOddEven(data, 5);
 for(int i = 0; i < 5; i++)
  cout << data[i] << " ";
 cout <<endl;

 system("pause");
 return 0;
}

考慮可擴展性的解法:(解決一系列問題的通用解法)

    將該問題的邏輯框架抽取出來,把判斷的標準變成一個函數指針,也就是使用一個單獨的函數判斷數字是否符合標準。此時,能夠把整個函數解耦成兩部分:(一)判斷數字應該在數組的前半部分仍是後半部分的標準;(二)拆分數組的操做。

 

//解耦操做:使用函數指針(*fun)(int)
void ReOrder(int *pData, int length, bool(*fun)(int))
{
 if(pData == NULL || length <= 0)
  return;
 int *pBegin = pData;
 int *pEnd = pData + length - 1;
 while(pBegin < pEnd)
 {
  while(pBegin < pEnd && !fun(*pBegin)) //第一個指針指向的數字爲奇數的時候,則繼續向後移動第一個指針
   pBegin++;
  while(pBegin < pEnd && fun(*pEnd))
   pEnd--;
  if(pBegin < pEnd)
  {
   int temp;
   temp = *pBegin;
   *pBegin = *pEnd;
   *pEnd = temp;
  }
 }
}
//isEven 是具體的標準,即判斷一個數是否是爲偶數。
bool isEven(int n)
{
 return (n & 1)==0;
}

void ReOrderOddEven(int *pData, int *pEnd, int length){ ReOrder(pData, length, isEven);}

相關文章
相關標籤/搜索