指针首尾并进
- 快排分割数组首尾的实现方式。
- 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。
- 输入一个增序数组和一个数sum,在数组中找到两个数,使得和为sum。输入任意一对即可。
1、思路:
先随机选base,与尾交换。然后从左往右遍历,找到比base大的数,交换;从右往左遍历,找到比base小的数,交换。
QuickSort
1 #include <iostream> 2 #include <exception> 3 #include <stdlib.h> 4 #include <string.h> 5 6 using namespace std; 7 8 int RandInRange(int a, int b) 9 { 10 return rand()%(b - a + 1) + a; 11 } 12 13 void PrintArray(int data[], int length) 14 { 15 for (int i = 0; i < length; i++) 16 printf("%d ", data[i]); 17 printf("\n"); 18 } 19 20 int Partition(int data[], int length, int start, int end) 21 { 22 if (data == NULL || length <= 0 || start < 0 || end >= length) 23 throw new exception(); 24 25 int index = RandInRange(start, end); 26 int base = data[index]; 27 swap(data[start], data[index]); 28 29 while(start < end) 30 { 31 while (start < end && data[end] > base) 32 end--; 33 data[start] = data[end]; 34 while (start < end && data[start] < base) 35 start++; 36 data[end] = data[start]; 37 } 38 39 data[start] = base; 40 return start; 41 } 42 43 void QuickSort(int data[], int length, int start, int end) 44 { 45 if (start == end) 46 return; 47 int index = Partition(data, length, start, end); 48 if (index > start) 49 QuickSort(data, length, start, index - 1); 50 if (index < end) 51 QuickSort(data, length, start + 1, end); 52 } 53 54 int main() 55 { 56 int test[7] = {23, 13, 49, 6, 31, 19, 28}; 57 PrintArray(test, 7); 58 QuickSort(test, 7, 0, 6); 59 PrintArray(test, 7); 60 }
2、思路:
设置两个指针,首尾位置。首指针往后移直到遇到偶数,尾指针往前移直到遇到奇数,两者都遇到的情况下互换位置,终止条件是首尾指针碰头。
ReorderOddEven
1 void ReorderOddEven(int *pData, unsigned int length) 2 { 3 if(pData == NULL || length == 0) 4 return; 5 6 int *pBegin = pData; 7 int *pEnd = pData + length - 1; 8 9 while(pBegin < pEnd) 10 { 11 // 向后移动pBegin,直到它指向偶数 12 while(pBegin < pEnd && (*pBegin & 0x1) != 0) 13 pBegin ++; 14 15 // 向前移动pEnd,直到它指向奇数 16 while(pBegin < pEnd && (*pEnd & 0x1) == 0) 17 pEnd --; 18 19 if(pBegin < pEnd) 20 { 21 int temp = *pBegin; 22 *pBegin = *pEnd; 23 *pEnd = temp; 24 } 25 } 26 }
3、思路:
如果原数组是无序的,则先排序,O(nlogn)开销。这里已经是增序排列了,所以不需要排序。设置两个指针,一头一尾。当和大于s,尾指针往前移;当和小于s,头指针往后移。直到两指针相遇,看是否有符合要求的数出现。
FindNumbersWithSum
1 FindNumbersWithSum 2 bool FindNumbersWithSum(int data[], int length, int sum, int *num1, int *num2) 3 { 4 bool found = false; 5 if (length < 1 || num1 == NULL || num2 == NULL) 6 return found; 7 int ahead = length - 1; 8 int behind = 0; 9 while (ahead > behind) 10 { 11 long long curSum = data[ahead] + data[behind]; 12 if (curSum == sum) 13 { 14 *num1 = data[behind]; 15 *num2 = data[ahead]; 16 found = true; 17 break; 18 } 19 else if (curSum > sum) 20 ahead--; 21 else 22 behind++; 23 } 24 return found; 25 }