為什麼快速排序比堆排序要快?
阿新 • • 發佈:2019-01-07
今天作演算法排序實驗,發現相同的資料規模,快速排序比堆排序的效率高很多,並且隨著資料規模的擴大,二者的差距不斷擴大,快速排序的優勢越來越明顯。快速排序的時間複雜度近似線性增長,堆排序則要大很多。究其原因,應該有以下幾個方面:
在堆排序(小根堆)的時候,每次總是將最小的元素移除,然後將最後的元素放到堆頂,再讓其自我調整。這樣一來,有很多比較將是被浪費的,因為被拿到堆頂的那個元素幾乎肯定是很大的,而靠近堆頂的元素又幾乎肯定是很小的,最後一個元素能留在堆頂的可能性微乎其微,最後一個元素很有可能最終再被移動到底部。在堆排序裡面有大量這種近乎無效的比較。隨著資料規模的增長,比較的開銷最差情況應該在(線性*對數)級別,如果資料量是原來的10倍,那麼用於比較的時間開銷可能是原來的10log10倍。
堆排序的過程中,需要有效的隨機存取。比較父節點和位元組點的值大小的時候,雖然計算下標會很快完成,但是在大規模的資料中對陣列指標定址也需要一定的時間。而快速排序只需要將陣列指標移動到相鄰的區域即可。在堆排序中,會大量的隨機存取資料;而在快速排序中,只會大量的順序存取資料。隨著資料規模的擴大,這方面的差距會明顯增大。在這方面的時間開銷來說,快速排序只會線性增長,而堆排序增加幅度很大,會遠遠大於線性。
在堆排序(小根堆)的時候,每次總是將最小的元素移除,然後將最後的元素放到堆頂,再讓其自我調整。這樣一來,有很多比較將是被浪費的,因為被拿到堆頂的那個元素幾乎肯定是很大的,而靠近堆頂的元素又幾乎肯定是很小的,最後一個元素能留在堆頂的可能性微乎其微,最後一個元素很有可能最終再被移動到底部。在堆排序裡面有大量這種近乎無效的比較。隨著資料規模的增長,比較的開銷最差情況應該在(線性*對數)級別,如果資料量是原來的10倍,那麼用於比較的時間開銷可能是原來的10log10倍。
堆排序的過程中,需要有效的隨機存取。比較父節點和位元組點的值大小的時候,雖然計算下標會很快完成,但是在大規模的資料中對陣列指標定址也需要一定的時間。而快速排序只需要將陣列指標移動到相鄰的區域即可。在堆排序中,會大量的隨機存取資料;而在快速排序中,只會大量的順序存取資料。隨著資料規模的擴大,這方面的差距會明顯增大。在這方面的時間開銷來說,快速排序只會線性增長,而堆排序增加幅度很大,會遠遠大於線性。
在快速排序中,每次資料移動都意味著該資料距離它正確的位置越來越近,而在堆排序中,類似將堆尾部的資料移到堆頂這樣的操作只會使相應的資料遠離它正確的位置,後續必然有一些操作再將其移動,即“做了好多無用功”。
附:相關文章連結: