問題:調整數組順序是奇數位於偶數以前。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);}