二分思想和分治法
如果你對概念很敏感,會馬上意識到這兩者的細微不同:二分搜尋每次都要捨棄一半,從留下的一半中尋找目標;而分治法把乙個大問題分成兩個或多個小問題,遞迴地求這些小問題的解,最後再把它們小心謹慎的合併起來,並且要仔細考慮合併時產生的新的情況。這當然沒有錯,但你也馬上會從這裡意識到兩者的巨大聯絡。就拿選取陣列中第k個最小的數的演算法來說,有乙個版本便是從快速排序中修改而來:劃分後,捨棄掉不存在的區間,對剩餘部分迭代(後文將進行講解),而快速排序是分治法的典型代表。
正式地把這個問題敘述為:
在o(n)時間內從陣列x[0...n-1]中找出第k個最小的元素。可以改變原陣列中元素的位置。
下面這段**就是從快速排序中修改而來,同時考慮到了隨機選擇劃分元素的問題。
int partition(int *array, int p, int r)
}swap_value(array+i+1,array+r);
return i+1;
}int random_select(int *array, int p, int r, int i)
擴充套件:(《續》習題15.2)如何從乙個3元陣列中選出第2小的?如果從1000000個中選出1000個最小元素、且輸入儲存在磁帶上呢?
分析:前者至多只需3次比較:1和2、1和2中最大的和3、1和2中最小的和3;後者是遍歷時用1000大小的最大堆儲存1000個當前最小的即可。其實前者是為了說明,如果問題只有幾步就可以解決,根本沒必要使用複雜的遞迴函式,直接解就是了;而後者是因為磁帶進行隨機i/o不方便而已,否則,直接用k=1001劃分,那麼k前面的1000個就是所求的元素。
珠璣之櫝 二分思想與分治法 排序思想
目錄 排序思想 如果你對概念很敏感,會馬上意識到這兩者的細微不同 二分搜尋每次都要捨棄一半,從留下的一半中尋找目標 而分治法把乙個大問題分成兩個或多個小問題,遞迴地求這些小問題的解,最後再把它們小心謹慎的合併起來,並且要仔細考慮合併時產生的新的情況。這當然沒有錯,但你也馬上會從這裡意識到兩者的巨大聯...
珠璣之櫝 二分思想與分治法 排序思想
目錄 排序思想 如果你對概念很敏感,會馬上意識到這兩者的細微不同 二分搜尋每次都要捨棄一半,從留下的一半中尋找目標 而分治法把乙個大問題分成兩個或多個小問題,遞迴地求這些小問題的解,最後再把它們小心謹慎的合併起來,並且要仔細考慮合併時產生的新的情況。這當然沒有錯,但你也馬上會從這裡意識到兩者的巨大聯...
珠璣之櫝 二分思想與分治法 排序思想
目錄 排序思想 如果你對概念很敏感,會馬上意識到這兩者的細微不同 二分搜尋每次都要捨棄一半,從留下的一半中尋找目標 而分治法把乙個大問題分成兩個或多個小問題,遞迴地求這些小問題的解,最後再把它們小心謹慎的合併起來,並且要仔細考慮合併時產生的新的情況。這當然沒有錯,但你也馬上會從這裡意識到兩者的巨大聯...