<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 排序 本章先簡單介紹了插入排序,然后著重講述快速排序。 **插入排序** ~~~ // 版本1 void InsertSort(int a[], int n) { for(int i=1; i<n; ++i) for(int j=i; j>0 && a[j-1]>a[j]; --j) swap(a[j-1], a[j]); } // 版本2 void InsertSort1(int a[], int n) { for(int i=1; i<n; ++i) { int t = a[i]; int j = i; for(; j>0 && a[j-1]>t; --j) a[j] = a[j-1]; a[j] = t; } } ~~~ **快速排序** > > 我們在這里規定:小于等于pivot的元素移到左邊,大于pivot的元素移到右邊。 **實現1:單向移動版本** 這個版本的關鍵是設置一快一慢兩個指針,慢指針左側都是小于等于pivot(包含慢指針所在位置), 慢指針到快指針之間的值是大于pivot,快指針右側的值是還未比較過的。示意圖如下: ~~~ 小于等于pivot | 大于pivot | ? slow fast ~~~ 快指針一次一步向前走,遇到大于pivot什么也不做繼續向前走。遇到小于等于pivot的元素, 則慢指針slow向前走一步,然后交換快慢指針指向的元素。一次劃分結束后, 再遞歸對左右兩側的元素進行快排。代碼如下: ~~~ // 數組快排 void QSort(int a[], int head, int end) { if(a==NULL || head==end) return; int slow = head, fast = head + 1; int pivot = a[head]; while(fast != end) { if(a[fast] <= pivot) swap(a[++slow], a[fast]); ++fast; } swap(a[head], a[slow]); QSort(a, head, slow); QSort(a, slow+1, end); } ~~~ 排序數組a只需要調用QSort(a, 0, n)即可。該思路同樣可以很容易地在鏈表上實現: ~~~ // 單鏈表快排 void qsort(Node *head, Node *end){ if(head==NULL || head==end) return; Node *slow = head, *fast = head->next; int pivot = head->data; while(fast != end){ if(fast->data <= pivot){ slow = slow->next; swap(slow->data, fast->data); } fast = fast->next; } swap(head->data, slow->data); qsort(head, slow); qsort(slow->next, end); } ~~~ 排序頭指針為head的單鏈表只需調用qsort(head, NULL)即可。 **實現2:雙向移動版本** 版本1能能夠快速完成對隨機整數數組的排序,但如果數組有序, 或是數組中元素相同,快排的時間復雜度會退化成O(n2?),性能變得非常差。 一種緩解方案是使用雙向移動版本的快排,它每次劃分也是使用兩個指針, 不過一個是從左向右移動,一個是從右向左移動,示意圖如下: ~~~ 小于等于pivot | ? | 大于pivot i j ~~~ 指針j不斷向左移動,直到遇到小于等于pivot,就交換指針i和j所指元素 (指針i一開始指向pivot);指針i不斷向右移動,直到遇到大于pivot的, 就交換指針i和j所指元素。pivot在這個過程中,不斷地換來換去, 最終會停在分界線上,分界線左邊都是小于等于它的元素,右邊都是大于它的元素。 這樣就避免了最后還要交換一次pivot的操作,代碼也變得美觀許多。 ~~~ int partition(int a[], int low, int high){ int pivot = a[low], i=low, j=high; while(i < j){ while(i<j && a[j]>pivot) --j; if(i < j) swap(a[i], a[j]); while(i<j && a[i]<=pivot) ++i; if(i < j) swap(a[i], a[j]); } return i; } void quicksort(int a[], int first, int last){ if(first<last){ int k = partition(a, first, last); quicksort(a, first, k-1); quicksort(a, k+1, last); } } ~~~ 當然,如果對于partition函數,你如果覺得大循環內的兩個swap還是做了些無用功的話, 也可以把pivot的賦值放到最后一步,而不是在這個過程中swap來swap去的。代碼如下: ~~~ int partition(int a[], int low, int high){ int pivot = a[low], i=low, j=high; while(i<j){ while(i<j && a[j]>pivot) --j; if(i<j) a[i++] = a[j]; while(i<j && a[i]<=pivot) ++i; if(i<j) a[j--] = a[i]; } a[i] = pivot; return i; } ~~~ 如果數組基本有序,那隨機選擇pivot(而不像上面那樣選擇第一個做為pivot) 會得到更好的性能。在partition函數里,我們只需要在數組中隨機選一個元素, 然后將它和數組中第一個元素交換,后面的劃分代碼無需改變, 就可以達到隨機選擇pivot的效果。 **進一步優化** 對于小數組,用插入排序之類的簡單方法來排序反而會更快,因此在快排中, 當數組長度小于某個值時,我們就什么也不做。對應到代碼中, 就是修改quicksort中的if條件: ~~~ if(first < last) 改為 if(last-first > cutoff) ~~~ 其中cutoff是一個小整數。程序結束時,數組并不是有序的, 而是被組合成一塊一塊隨機排列的值,并且滿足這樣的條件: 某一塊中的元素小于它右邊任何塊中的元素。我們必須通過另一種排序算法對塊內進行排序。 由于數組是幾乎有序的,因此插入排序比較適用。 這種方法結合了快排和插入排序,讓它們去做各自擅長的事情,往往比單純用快排要快。 深入閱讀:Don Knuth的《The Art of Computer Programming, Volume 3: Sorting and Searching》;Robert Sedgewick的《Algorithms》; 《Algorithms in C》,《Algorithms in C++》,《Algorithms in Java》。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看