演算法--排序--分治與快速排序

來源:互聯網
上載者:User

標籤:pre   return   左右   標準   可能性   無法   位置   返回   public   

學習排序演算法也有一段時間,一直沒有好好整理下排序演算法的相關知識,排序在演算法中是最基礎也是最重要的,所以有必要自己進行一番整理,在提高領悟演算法本質的同時以備以後自己複習,順便也將自己領悟到的一些思想進行記錄。

下面簡單整理下快排的演算法感悟,當然,個人覺得領悟快排的核心思想分治才是學習這個演算法的最重要目的。

一、快排的思想

  1、分治思想。是的,快排最核心的思想就是:遞迴中重要的思想,分治。好吧,其實剛剛接觸分治的時候,或者說遞迴的時候,我真的真的無法真正理解,感覺就是:好像理解了,但是細想又覺得有困惑。好吧,分治的思想個人覺得最終還是要自己領悟才行的,沒有人可以幫得了你,包括我下面對分治一大堆個人理解,估計,對於你真正理解分治可能協助不大,你得自己去深入思考一下:為什麼這樣做就可以。ok,下面是個人對分治思想的一些理解:

  A、分解問題,遞迴解決。主要思想就是將問題分為幾個部分,快排這裡是兩部分,分別對這兩部分遞迴,然後,遞迴裡面又繼續遞迴分解後的兩部分(好吧,就是這裡,理解這裡,分治就理解了,但是,的確有點繞,只能靠自己去領悟了)......直到問題不能再分為止。然後,你會困惑了:利用分治,遞迴到問題不能分解為止,就可以解決問題了?

  OK,下面說說為什麼分治當遞迴到問題不能分解時就代表遞迴到頭了,也就是問題解決了:這還得回到遞迴本身,遞迴是通過遞推的關係,在到達某處已經知道結果的時候,停止遞迴,舉個例子:比方說,求階乘的簡單例子:我知道了1的階乘是1,所以,到達了1就代表我可以停止遞迴了,因為,1之後的數位階乘都可以通過1的階乘求出來,而遞迴就是實現這個遞推的過程,只不過,它看起來是像從後面反向推算到前面,實際上卻是從1的階乘開始求(因為有效運算是在找到1的階乘的結果這個返回條件之後即return語句執行結束遞迴時開始的!)。而分治與遞迴的區別或許就是分解問題的方式不同:普通遞迴是一步一步地將問題分解,好像吃蛋糕一小口一小口地吃;而分治就一下子將問題分成兩大part或者幾大part,然後再在這幾個大part裡面繼續分,就好像,吃蛋糕時,先將蛋糕切成兩大部分或幾大部分,然後在這兩大部分或幾大部分進行對應的分割(也不知道有沒有形象地說明了,尷尬,個人理解),知道分成可以最後處理的最小結果集(這個結果集已經知道結果了)

  B、好吧,上面一大坨文字廢話,其實就是想說明:分治,就是分解問題的過程,將分解後的問題進行遞迴,直到滿足遞迴停止條件。

  OK,扯太遠了,回到剛說那個問題:為什麼問題分解到不能分解就代表問題解決了呢?利用快排進行理解吧,那就還得先介紹快排的處理方法:

  2、快排的處理方法:每次讓某個元素去到它最終要到達的位置,並且,該元素的左邊元素比該元素小,右邊元素比該元素大,完成一個過程後,分別對左右兩部分進行分治遞迴。

  OK,接著上面講:為什麼分治到達了問題不能分割之後,就代表解決問題了呢?可以這樣理解:當快排中元素只有一個時,那排序本身的結果是知道的,所以這時就是對應遞迴結束的條件了;同時,前面的將某個元素移到正確位置以及左右元素的順序確定保證了問題的可遞推性(畢竟,遞迴可以解決問題的前提就是可以找出遞推關係),兩者結合,使得本來看起來不能遞迴解決的問題利用遞迴完美解決了,所以,其實快排指導思想可以概括為:

  遞迴條件的尋找+遞推關係的尋找,前者很容易,就是找到遞迴邊界,對應某個時刻結果已知道(只有一個元素排序結果肯定知道啦);後者,則是通過快排處理排序元素的辦法解決:就是這坨辦法--每次讓某個元素去到它最終要到達的位置,並且,該元素的左邊元素比該元素小,右邊元素比該元素大,完成一個過程後,分別對左右兩部分進行分治遞迴,這樣保證遞迴時遞推關係的滿足。

  so,以後如果要用遞迴解決問題--記得按照上面的思路:找遞推成立的可能性處理的辦法(數學地講,就是找遞推公示),然後,就是確立遞迴條件!

(好吧,這一大坨字,僅僅代表個人對遞迴以及分治背後的理解,各位看不懂,就算了,畢竟的確寫得不太好,繞來繞去的(尷尬),最終遞迴與分治還是要自己去領悟的)

二、下面貼上個人寫的快排代碼(java版)

//快速排序方法    public static void sortFast(int [] arr,int l,int r){        //遞迴返回條件        if(l>=r){            //只有一個元素時返回            return ;        }        //第一輪,將最後一個元素作為標準        int result = part(arr,l,r);//調用首輪排序方法,將小於arr[r]的元素放在左邊,大於該元素的元素放在右邊        //分治遞迴        sortFast(arr, l, result-1);        sortFast(arr, result, r);    }    //快速排序的輔助函數    private static int part(int [] arr,int l,int r){        //儲存r的值        int v = r;        l = l-1;        //進行遍曆操作        int tem;        for(;;){            //尋找左邊合格元素            while(++l<r){                if(arr[l]>arr[v]){                    break;                }            }                        //尋找右邊合格元素            r=r+1;            while(--r>l){                if(arr[r]<arr[v]){                    break;                }            }            //判斷兩個指標是否相遇            if(r<=l){                break;            }else{                //執行交換操作                tem = arr[l];                arr[l] = arr[r];                arr[r] = tem;            }        }        //將arr[r]放到正確的的位置中        tem = arr[v];        arr[v] = arr[l];        arr[l] = tem;        return r;    }

 

OK,快排的整理到這裡,感覺這是篇失敗的部落格,畢竟,文字太多了,而且,這些文字還是不好理解的.....好吧,遞迴和分治的領悟,的確有種可意會不可言傳的感覺。後面會陸續整理其他排序演算法,今天演算法分治和快排的整理就這麼多吧。

演算法--排序--分治與快速排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.