Sword refers to offer Question 21-adjust the array order so that odd books are in front of even numbers

Adjust the array order so that odd books are in front of even numbers

topic

Enter an integer array and implement a function to adjust the order of the numbers in the array so that all counts are in the first half of the array, and all even numbers are in the second half of the array

initial analysis

The easiest way is of course to scan the array from the beginning, every time an even number is encountered, the number is placed at the end, that is, the number after the number must be moved forward.
Since O(n) numbers are moved every time an even number is encountered, the total time complexity is O(n^2).

Better way

Since there are only two types of numbers in the array-either odd or even. So whenever you find an even number appears before an odd number, it is okay to swap their order?

Therefore, two pointers need to be maintained: the
first pointer, which points to the first number when initialized, can only move backward.
The second pointer points to the last number when initialized and can only move forward.

Before the two pointers meet, if the first pointer is an even number and the second pointer is an odd number, then swap their positions

For example

Input array: {1, 2, 3, 4, 5}

Process:
1. At the beginning, the first pointer points to 1 and the second pointer points to 5
2. Since 1 is an odd number, the first pointer moves backward until it points to an even number 2.
3. At this time, because the second pointer points to 5, it swaps, and both move.
4. Then continue until the two meet

Illustration:
Insert picture description here
So you can get the following code:

void ReorderOddEven(int* pData,unsigned int length)
{
    
    
	if(pData==nullptr || length==0)
		return;
	int* pBegin=pData;
	int* pEnd=pData+length+1;
	
	while(pBegin<pEnd)
	{
    
    
		//向后移动pBegin 直到它指向偶数
		while(pBegin<pEnd && (*pBegin & 0x1)!=0)
			pBegin++;
		//向前移动pEnd 直到指向奇数
		while(pBegin<pEnd && (*pEnd & 0x1)==0)
			pEnd--;
		if(pBegin<pEnd)
		{
    
    
			int temp=*pBegin;
			*pBegin=*pEnd;
			*pEnd=tmp;
		}
	}
}

Expansion-modular processing

The above problem is solved and it seems to be perfect, but what if there are similar problems?

Question: If the array is divided into two parts, positive and negative, and the negative number is before the non-negative number, how to deal with it?
A: To redefine a new function, only need to change the judgment conditions of the second and third while loops.

Ask another question: What if it is divided into two parts, one part can be divisible by 3, and the front part is not divisible by 3, and the back part?
Answer again: Or redefine a new function and change it again... Interrupt: Stop and stop, is there no better way?

Looking at the above question, the answer is not wrong, so just change the conditions.
But the above is wrong, this is only the above

Since it's just a judgment condition that needs to be changed, why should I repeat the same code every time?
Why not encapsulate the conditions that need to be judged so that the remaining code can not be reused?
That's right, the answer that the formal questioner wanted!

Therefore, we only need to introduce a function pointer and split the above code into two parts: logic and operation. In this way, you only need to rewrite the logic function each time, instead of repeating a large number of calculations, and the reusability is greatly improved

void ReorderOddEven(int* pData,unsigned int length,bool (*func)(int))
{
    
    
	if(pData==nullptr || length==0)
		return;
	int* pBegin=pData;
	int* pEnd=pData+length+1;
	
	while(pBegin<pEnd)
	{
    
    
		//向后移动pBegin 直到它指向偶数
		while(pBegin<pEnd && !func(*pBegin))
			pBegin++;
		//向前移动pEnd 直到指向奇数
		while(pBegin<pEnd && func(*pEnd) )
			pEnd--;
		if(pBegin<pEnd)
		{
    
    
			int temp=*pBegin;
			*pBegin=*pEnd;
			*pEnd=tmp;
		}
	}
}

bool IsEven(int n)
{
    
    
	return (n&0x1)==0;
}

———————————————————————————————————————————————— ——————
Reference book: "Sword Finger Offer"

Guess you like

Origin blog.csdn.net/rjszz1314/article/details/104286378
Recommended