一 題目:調整數組順序使奇數位於偶數前面
題目:輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有奇數位於數組的前半部分,所有偶數位於數組的后半部分。
二 解題思路
如果不考慮時間復雜度,最簡單的思路應該是從頭掃描這個數組,每碰到一個偶數時,拿出這個數字,並把位於這個數字后面的所有數字往前挪動一位。挪完之后在數組的末尾有一個空位,這時把該偶數放入這個空位。由於每碰到一個偶數就需要移動O(n)個數字,因此總的時間復雜度是O(n2)。
這里可以參考快速排序的思想,快速排序的基本思想是:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的。
三 代碼實現
void Swap(int *p, int *q) { int temp = *p; *p = *q; *q = temp; } void ResetArray(int a[], int nLen) {
if (NULL == a || nLen <= 0)
{
return;
} int *left = a; int *right = &a[nLen -1]; while (left < right) { while(*left % 2 && (left < right)) { left ++; } while ((*right % 2) == 0 && (left < right)) { right --; } Swap(left++, right--); } } void main() { int a[] = {1,2,3,4,5,6,7,8,9}; ResetArray(a, 9); return; }
四 可擴展實現
如果把題目改成把數組中的數分為兩部分,能被3整除的數都在不能被3整除的數的前面。面對需求的變化,我們發現代碼變化的部分很小,因此從可擴展性的角度考慮,我們可以改寫上面的代碼如下,這里利用回調函數來實現。
typedef bool (*Proc)(int *); bool CmpCondition_1(int *p) { if (*p % 2) { return true; } return false; } bool CmpCondition_2(int *p) { if (*p % 3) { return false; } return true; } void ResetArray(int a[], int nLen, Proc fun) { if (NULL == a || nLen <= 0 || NULL == fun) { return; } int *left = a; int *right = &a[nLen -1]; while (left < right) { while(fun(left) && (left < right)) { left ++; } while (!fun(right)&& (left < right)) { right --; } Swap(left++, right--); } } void PrintArry(int *a, int nLen) { for (int i = 0;i < nLen; i ++) { cout << a[i] << " "; } cout << endl; } void main() { int a[] = {1,2,3,4,5,6,7,8,9}; cout <<"原始數組:"; PrintArry(a, 9); ResetArray(a, 9,CmpCondition_1); cout <<"奇數放前面,偶數方面:"; PrintArry(a, 9); ResetArray(a, 9,CmpCondition_2); cout <<"被3整除的放前面:"; PrintArry(a, 9); return; }