交換算法引起的快速排序錯誤
阿新 • • 發佈:2017-11-12
可靠 col 通過 中間變量 可靠性 什麽 color 減法 出現
前兩天手寫快速排序,最後得到的結果是錯誤的而且還錯的非常奇怪。輸入的待排序數組是:
int a[10] = {2,6,4,8,0,1,5,9,3,7};
最後得到的結果是:
0 0 2 0 0 0 6 0 8 0
上網看了看別人的代碼,發現我寫的快速排序的算法邏輯是沒有錯誤的,難道是交換元素時用的算法不對?
我用的交換算法是異或交換,就是不用中間變量那種:
void swap( int *a, int *b ) { *a = *a + *b; *b = *a - *b; *a = *a - *b; }
然後將其換成使用中間變量的交換算法:
voidswap( int *a, int *b ) { int temp; temp = *a; *a = *b; *b = temp; }
然後結果就對了,但是一直想不明白為什麽。最後通過在紙上演算一遍才恍然大悟。
例如我這個輸入:
2 6 4 8 0 1 5 9 3 7
中間的比較交換過程略去不表,然後它會到達這麽一個狀態:
0 /1 / 2 / 8 4 6 5 9 3 7
^
^
解釋一下,第一輪排序將2放到屬於它的位置,然後分成左邊的序列0 1和右邊的序列8 4 6 5 9 3 7。第二輪對左邊的0 1進行排序,將0放置到屬於它的位置(沒動)。第三輪對1進行排序,問題就出在這裏,由於只有一個元素,但按照算法也要進行一次交換,如果使用不借助中間變量的交換算法(加減法、異或法),傳遞給void swap( int *a, int *b )的a, b指向的是同一地址,也就是說實際上是這樣的:
void swap( int *a, int *a ) { *a = *a + *a; *a = *a - *a; //*a==0,永世不得翻身 *a = *a - *a; }
其實在第二輪時,0與0交換就出現了這個問題,但是由於它是0沒有表現出來。
以前總覺得不用中間變量的交換算法稍微有那麽點帥,看來還是得想好了再用。可靠性最重要啊。
交換算法引起的快速排序錯誤