1. 程式人生 > >演算法題:對只含有0,1,2三個元素的陣列排序,時間複雜度O(n)

演算法題:對只含有0,1,2三個元素的陣列排序,時間複雜度O(n)

題目:

將元素均為0、1、2的陣列排序,時間複雜度O(n)。

思路:

方法1:通過三個下標遍歷一遍實現的方法。

p1從左側開始,指向第一個非1的數字;p3從右側開始,指向第一個非3的數字。

p2從p1開始遍歷,如果是2,p2繼續遍歷,直到p2遇到1或者3

如果遇到1,則和p1進行交換,然後p1向右,指向第一個非1的數字

如果遇到3,則和p3進行交換,然後p3向左,指向第一個非3的數字

方法2:基於快排劃分的思路

上面的思路,是針對三個數的,如果有更多的數,怎麼處理呢?比如,4個,5個等等。下面根據快速的排序的啟發,介紹一種演算法,儘管在處理三個數的時候,比較次數會多些,但具有很好的通用性。

思路來自快排的劃分部分,快排的劃分部分:給定pivot,然後將資料劃分為<=pivot和>pivot兩部分。這樣,三個數字時,需要兩次劃分:

1.第一次,用1作為pivot,劃分1到最左邊;

2.第二次,用2作為pivot,劃分2到左邊,則得到整體的排序。

方法1的程式碼:

void sort012(vector<int> array)
{
	int p0=0;
	int p2=array.size()-1;
	int p1;
	//p0指向第一個不是0的值
	while(array[p0]==0 && p0<array.size())
	{
		p0++;
	}
	//p2指向第一個不是2的值
	while(array[p2]==2 && p2>=0)
	{
		p2--;
	}
	p1=p0;//p1從p0的位置開始遍歷
	while(p1<=p2)
	{
		if(array[p1]==1)
			p1++;
		else if(array[p1]==0)
			{
				swap(array[p0],array[p1]);	
				while(array[p0]==0 && p0<array.size())
				{
					p0++;
				}
			}
		else
			{
				swap(array[p2],array[p1]);
				while(array[p2]==2 && p2>=0)
				{
					p2--;
				}
			}
	}
}