待補充
題目:乙個陣列中只有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原題排序只有1,2,3三個元素的陣列,不能統計1,2,3的個數。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");
}
分析這個題目,儘管也是排序,但卻不能使用快速排序的方法。只有三個元素,如果時間複雜度仍舊是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的個數了。然後第...