實現只有0,1,2三種元素的亂序陣列的排序

2021-07-24 22:58:36 字數 2872 閱讀 3626

待補充

題目:乙個陣列中只有0,1,2三種元素,要求對這樣的陣列進行排序。
第一眼看到這樣的題目,會舉得非常簡單,只需要兩次遍歷陣列就可以完成了。第一次遍歷,掃瞄陣列中的元素,每次遇到0則count0++,遇到1則count1++,遇到2則count2++,這樣一趟下來就能夠統計出陣列中0,1,2的個數了。然後第二次遍歷的時候,只需要對陣列進行重新賦值就可以了,從頭開始賦值count0個0,count1個1,count2個2。最終完成對陣列的排序。

既然是面試題,那麼肯定不會讓你這麼簡單就解決出來了的。面試官說,加入只能進行一次遍歷怎麼辦,然後你就不知道了。

這道題目如果只能進行一次遍歷,我們肯定會想到使用多指標。這種題目之前碰到過很多。類似折半查詢需要設定兩個指標,不過這道題目卻需要三個指標,分別指向陣列中0,1,2三個元素末尾。加入有排好序的陣列,那麼p0指向下標為1的那個0,p1指向下標為3的那個1,而p2則指向下標為5的那個2。

p0和p1從前往後掃瞄,p2從後往前掃瞄,

初始化時:

p0指向第乙個非0元素,那麼arry[p0]=1||2

p1指向第乙個非1元素,那麼arry[p1]=0||2

p2指向第乙個非2元素,那麼arry[p2]=0||1

假如:arry[p0]==2,arry[p2]==0,交換兩個元素

arry[p1]==2,arry[p2]==1,交換兩個元素

arry[p0]==1,arry[p1]==0,交換兩個元素

否則的話只可能是p0,p1,p2指向的三個數各不相同,那麼進行如下賦值

arry[p0]==0,arry[p1]==1,arry[p2]==2。

假如經過上述swap以後出現i>k的情況,將k=i。(ps:2012-10-5)

#include#include

using

namespace

std;

void printarry(int arry,int

len)

void swap(int arry,int i,int

j)void sort(int arry,int

len)

//k指向第乙個非1值

while(arry[k] == 1

)

//j指向第乙個非2值

while(arry[j] == 2

)

if(i <= j && arry[j] == 0 && arry[i] == 2

)

else

if(k <= j && arry[k] == 2 && arry[j] == 1

)

else

if(i <= k && arry[k] == 0 && arry[i] == 1

)

else

if(i < k && k

if(i>k)

} }void

main()

;

int len=sizeof(arry)/sizeof(int

); printarry(arry,len);

sort(arry,len);

printarry(arry,len);

system(

"pause");

}

原題排序只有1,2,3三個元素的陣列,不能統計1,2,3的個數。

分析這個題目,儘管也是排序,但卻不能使用快速排序的方法。只有三個元素,如果時間複雜度仍舊是o(nlogn),顯然不是最好的。那就可以使用線性的排序演算法,例如計數排序,可是題目中要求,不能夠對1,2,3進行統計個數。那該如何處理呢?請大家看下面的方法,我們首先通過例子來說明:21

1332

p1p2p3

假設,我們有三個指標:p1、p2、p3.p1從左側開始,指向第乙個非1的數字;p3從右側開始,指向第乙個非3的數字。p2從p1開始遍歷,如果是2,p2繼續遍歷,直到p2遇到1或者3:

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

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

1332

p1,p2p3

交換之後,p2繼續從p1開始,如果是2繼續遍歷,如果是1或者3,重複上面的步驟,所得如下:11

2332

p1,p2p3

根據上面的方法繼續下去11

2233

p1p3p2

p2在p3右側,演算法結束。

總結一下上面的演算法:

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

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

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

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

重複上面的步驟,直到p2在p3的右側結束。

void sort(int arr,int

len)

else

if (arr[k] == 2

) }}

基於快排劃分的思路

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

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

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

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

實現只有0,1,2三種元素的亂序陣列的排序

第一眼看到這樣的題目,會舉得非常簡單,只需要兩次遍歷陣列就可以完成了。第一次遍歷,掃瞄陣列中的元素,每次遇到0則count0 遇到1則count1 遇到2則count2 這樣一趟下來就能夠統計出陣列中0,1,2的個數了。然後第二次遍歷的時候,只需要對陣列進行重新賦值就可以了,從頭開始賦值count0...

實現只有0,1,2三種元素的亂序陣列的排序

待補充 題目 乙個陣列中只有0,1,2三種元素,要求對這樣的陣列進行排序。第一眼看到這樣的題目,會舉得非常簡單,只需要兩次遍歷陣列就可以完成了。第一次遍歷,掃瞄陣列中的元素,每次遇到0則count0 遇到1則count1 遇到2則count2 這樣一趟下來就能夠統計出陣列中0,1,2的個數了。然後第...

實現只有0,1,2三種元素的亂序陣列的排序

待補充 題目 乙個陣列中只有0,1,2三種元素,要求對這樣的陣列進行排序。第一眼看到這樣的題目,會舉得非常簡單,只需要兩次遍歷陣列就可以完成了。第一次遍歷,掃瞄陣列中的元素,每次遇到0則count0 遇到1則count1 遇到2則count2 這樣一趟下來就能夠統計出陣列中0,1,2的個數了。然後第...