關於快速排序的問題分析

2021-09-27 03:26:27 字數 1658 閱讀 8059

問題描述:

void

quick_sort

(int

*n,int lo,

int hi)

如上述**所示,如將lo >= hi 改為lo == hi,則程式容易崩潰。同樣是採用分治策略,歸併排序無論是使用lo == hi,或者是lo >= hi,都不會出現崩潰問題。

問題分析:

既然程式崩潰掉,說明執行過程中沒有出現符合遞迴基的情況。下面我們來列印以下快排過程中的位置變化資訊。

上述左側一列為lo值,右側為hi值。可以看出,程式執行過程中,存在lo == hi的情況(程式在這種情況下就不會崩潰)。因為排序過程中的軸點是我們隨機選取的,即使相同的輸入資料,多次測試情況下,僅有少數情況不會崩潰掉,大多數還是會崩潰的,那麼為什麼還會崩潰呢?

原因就是:mi的值是不確定的,它不像歸併排序中的二分,最終會劃分到單一元素。快排的過程中可能出現mi+1之後大於hi值了,當傳入構造軸點的函式中,返回的仍然是mi+1。如下圖標記部分所示,下次傳入quick_sort(n, mi + 1, hi);就會出現上述情況。

其實這個不僅僅是在快排過程**現,任何需要遞迴過程中,都需要明白這個問題。

問題描述:

遞迴的呼叫次序是怎樣的?

問題分析:

首先,先看乙個簡單的示例。

#include

using namespace std;

void

say(

int n)

intmain()

列印次序如下:

結果分析:

這是因為,作業系統會為每乙個執行程式建立乙個堆疊,首先主函式被壓入棧內,接著壓入在主函式中被呼叫的第乙個函式,之後以此類推。棧會儲存相應的資料資訊。當相應的函式執行結束後,對應的函式會被從棧內彈出,需要時會將相應資訊返回給呼叫自己的函式。

遞迴的過程也是如此。首先主函式先執行,主函式率先被壓入棧,然後主函式呼叫say(),say()被壓入棧…。當達到遞迴基後,對應的函式被依次彈出。

上述程式執行過程中,只呼叫了一次自己,倘若呼叫兩次呢?像快排過程中的顯式呼叫自己兩次

quick_sort

(n, lo, mi)

;quick_sort

(n, mi +

1, hi)

;

會出現怎樣的結果?

還是先來看say()這個簡單例子。結果如下圖所示。

毫無疑問,say(n-1)率先到達遞迴基,到達遞迴基後開始返回自己的結果,但是因為它底下又呼叫了自己,所以返回結果過程中又會像剛開始一樣再次執行,執行完返回,返回過程中又遇到say(n-1),自然仍要重複上述步驟,直到返回過程中也到達了遞迴基為止。

關於排序(快速排序)

package com.sw.demo.test 關於快速排序 author song public class testquicksort quicksort arr,0,arr.length 1 快速排序 for int i 0 i arr.length i 快速排序 param arr par...

快速排序分析

1.開篇 終於還是忍不住要學習一下演算法啦,該面對的還是要面對,不能逃避,不能把已經會的技能忘掉,那是一種對生命的摧殘和不仁。不要怕,只要每天都在進步,水滴石穿,終有破雲見天日的時刻。感慨寫完了,回到正題,分析快速排序。2.原理 假設要排序的陣列是a 0 a n 1 首先任意選取乙個資料 通常選用陣...

快速排序分析

首先簡單描述一下快速排序 1.快速排序樹不穩定的 由於關鍵字的比較與交換是跳躍進行的 2.時間複雜度為o n logn 最好情況為n logn 若陣列基本有序為n n 3.空間複雜度為logn 主要是遞迴造成的棧空間的使用,最好情況,遞迴樹的深度為log2n,其空間複雜度也就為o logn 最壞情況...