第一篇:基于分治法的快速排序
實(shí)驗(yàn)2.基于分治法的快速排序算法
實(shí)驗(yàn)內(nèi)容
本實(shí)驗(yàn)要求基于算法設(shè)計(jì)與分析的一般過程(即待求解問題的描述、算法設(shè)計(jì)、算法描述、算法正確性證明、算法分析、算法實(shí)現(xiàn)與測(cè)試),針對(duì)快速排序算法從實(shí)踐中理解分治法的思想、求解策略及步驟。
實(shí)驗(yàn)?zāi)康?/p>
? 理解分治法的核心思想以及分治法求解過程;
? 從算法分析與設(shè)計(jì)的角度,對(duì)快速排序算法有更進(jìn)一步的理解。
環(huán)境要求
對(duì)于環(huán)境沒有特別要求。對(duì)于算法實(shí)現(xiàn),可以自由選擇C, C++, Java,甚至于其他程序設(shè)計(jì)語(yǔ)言。
實(shí)驗(yàn)步驟
步驟1:理解問題,給出問題的描述。
步驟2:算法設(shè)計(jì),包括策略與數(shù)據(jù)結(jié)構(gòu)的選擇
步驟3:描述算法。希望采用源代碼以外的形式,如偽代碼、流程圖等; 步驟4:算法的正確性證明。需要這個(gè)環(huán)節(jié),在理解的基礎(chǔ)上對(duì)算法的正確性給予證明; 步驟5:算法復(fù)雜性分析,包括時(shí)間復(fù)雜性和空間復(fù)雜性;
步驟6:算法實(shí)現(xiàn)與測(cè)試。附上代碼或以附件的形式提交,同時(shí)貼上算法運(yùn)行結(jié)果截圖;步驟7:技術(shù)上、分析過程中等各種心得體會(huì)與備忘,需要言之有物。
說明:步驟1-6在“實(shí)驗(yàn)結(jié)果”一節(jié)中描述,步驟7在“實(shí)驗(yàn)總結(jié)”一節(jié)中描述。
實(shí)驗(yàn)結(jié)果
問題描述
快速排序是一種劃分交換排序,其基本思想是:通過一趟掃描將待排序的元素分割成獨(dú)立的三個(gè)序列:第一個(gè)序列中所有元素均不大于基準(zhǔn)元素、第二個(gè)序列是基準(zhǔn)元素、第三個(gè)序列中所有元素均不小于基準(zhǔn)元素。由于第二個(gè)序列已經(jīng)處于正確位置,因此需要再按此方法對(duì)第一個(gè)序列和第三個(gè)序列分別進(jìn)行排序,整個(gè)排序過程可以遞歸進(jìn)行,最終可使整個(gè)序列變成有序序列。算法設(shè)計(jì)
快速排序采用分治策略
快速排序的基本思想是基于分治策略的,利用分治法可將快速排序的基本思想描述如下:設(shè)當(dāng)前排序的序列為R【low:high】,其中l(wèi)ow<=high,如果序列的規(guī)模足夠小則直接進(jìn)行排序,否則分三步處理:
A分解B求解子問題C合并 描述算法
void QuickSort(int R[],int low,int high){
int pivotpos; //劃分后的基準(zhǔn)元素所對(duì)應(yīng)的位置
if(low pivotpos=Partition(R,low,high); QuickSort(R,low,pivotpos-1); //對(duì)左區(qū)間遞歸排序 QuickSort(R,pivotpos+1,high); //對(duì)右區(qū)間遞歸排序 } } 正確性證明 原始序列: 49 38 65 97 76 13 27 第一次掃描: [27 38 13] 49 [76 97 65] 以27為基準(zhǔn)元素 得到的序列: [13] 27 [38] 以76為基準(zhǔn)元素 得到的序列:[65] 76 [97] 最終序列為:、27、38、49、65、76、97 算法復(fù)雜性分析 最壞情況O(n2) ìO(1)n=1?T(n)=í??T(n-1)+O(n)n>1最好情況O(nlogn) 平均情況:O(nlogn) 1nT(n)=?(T(n-k)+T(k-1))+nnk=1 ìO(1)n=1?T(n)=í??2T(n/2)+O(n)n>1空間復(fù)雜性: 由于快速排序算法是遞歸執(zhí)行,需要一個(gè)棧來存放每一層遞歸調(diào)用的必要信息,其最大容量應(yīng)與遞歸調(diào)用的深度一致。最好情況下,若每次劃分較為均勻,則遞歸樹的高度為O(logn),故遞歸所需棧空間為O(logn)。最壞情況下,遞歸樹的高度為O(n),所需的棧空間同為O(n).平均情況下,所需棧空間為O(logn)。 算法實(shí)現(xiàn)與測(cè)試 實(shí)驗(yàn)總結(jié) 在學(xué)數(shù)據(jù)結(jié)構(gòu)這門課時(shí),我們就學(xué)過多種排序,像冒泡排序,遞歸排序,堆棧排序,歸并排序,快速排序等。這次的基于分治法的快速排序相對(duì)能熟悉一些,關(guān)鍵是依據(jù)所選的基準(zhǔn)元素對(duì)序列進(jìn)行劃分即可。 崗位排序法、崗位分類法、因素比較法、要素計(jì)點(diǎn)法等崗位評(píng)價(jià)的方法各有特色,并不存在最佳方案 1.崗位評(píng)價(jià)法的種類 崗位排序法、崗位分類法、因素比較法、要素計(jì)點(diǎn)法 2.崗位評(píng)價(jià)法之一:崗位排序法 崗位排序法是目前國(guó)內(nèi)外廣泛應(yīng)用的一種崗位評(píng)價(jià)方法,這種方法是一種整體性的崗位評(píng)價(jià)方法。崗位排序法是根據(jù)一些特定的標(biāo)準(zhǔn)例如工作的復(fù)雜程度、對(duì)組織的貢獻(xiàn)大小等對(duì)各個(gè)崗位的相對(duì)價(jià)值進(jìn)行整體的比較,進(jìn)而將崗位按照相對(duì)價(jià)值的高低排列出一個(gè)次序的崗位評(píng)價(jià)方法。 排序時(shí)基本采用兩種做法。 一、直接排序,即按照崗位的說明根據(jù)排序標(biāo)準(zhǔn)從高到低或從低到高進(jìn)行排序。 二、交替排序法,即先從所需排序的崗位中選出相對(duì)價(jià)值最高的排在第一位,在選出相對(duì)價(jià)值最低的排在倒數(shù)第一位,然后再?gòu)氖O碌膷徫恢羞x出相對(duì)價(jià)值最高的排在第二位,接下去再選出剩下的崗位中相對(duì)價(jià)值最低的排在倒數(shù)第二位,依此類推。 崗位排序法的主要優(yōu)點(diǎn)是簡(jiǎn)單、容易操作、省時(shí)省力,適用于較小規(guī)模、崗位數(shù)量較少、新設(shè)立崗位較多,評(píng)價(jià)這對(duì)崗位了解不是很充分的情況。但是這種方法也有一些不完善之處,首先這種方法帶有一些主觀性,評(píng)價(jià)者多依據(jù)自己對(duì)崗位的主觀感覺進(jìn)行排序;其次,對(duì)崗位進(jìn)行排序無(wú)法準(zhǔn)確得知崗位之間的相對(duì)價(jià)值關(guān)系。 3.崗位評(píng)價(jià)法之二:崗位分類法 所謂崗位分類法,就是通過制定出一套崗位級(jí)別標(biāo)準(zhǔn),將崗位與標(biāo)準(zhǔn)進(jìn)行比較,并歸到各個(gè)級(jí)別中去。崗位分類法好像一個(gè)有很多層次的書架,每一層都代表著一個(gè)等級(jí),比如說把最貴的書放到最上面一層,最便宜的書放到最下面一層,而每個(gè)崗位則好像是一本書,我們的目標(biāo)是將這些書分配到書架的各個(gè)層次上去,這樣的結(jié)果我們就可以看到不同價(jià)值的崗位分布情況。因此,首先我們需要建立一個(gè)很好的書架,也就是崗位級(jí)別的標(biāo)準(zhǔn)。如果這個(gè)標(biāo)準(zhǔn)建立的不合理,那么就可能會(huì)出現(xiàn)書架中有的層次擠滿了很多書,而有的層次則沒有書,這樣擠在一起的書就很難區(qū)分出來。 崗位分類法的關(guān)鍵是建立一個(gè)崗位級(jí)別體系。建立崗位級(jí)別體系包括確定等級(jí)的數(shù)量和為每一個(gè)等級(jí)建立定義與描述。等級(jí)的數(shù)量沒有什么固定的規(guī)定,只要根據(jù)需設(shè)定,便于操作并能有效的區(qū)分崗位即可。對(duì)每一定等級(jí)的定義和描述要依據(jù)一定的要素進(jìn)行,這些要素可以根據(jù)組織的需要來選定。最后就是要將組織中的各個(gè)崗位歸到合適的級(jí)別中去。 崗位分類法是一種簡(jiǎn)便易理解和操作的崗位評(píng)價(jià)方法。適用于大型組織,對(duì)大量的崗位進(jìn)行評(píng)價(jià)。同時(shí)這種方法的靈活性較強(qiáng),在組織中崗位發(fā)生變化的情況,可以迅速的將組織中新出現(xiàn)的崗位歸類到合適的類別中去。 但是,這種方法也有一定的不足,那就是對(duì)崗位等級(jí)的劃分和界定存在一定的難度,有一定的主觀性。如果崗位級(jí)別劃分的不合理,將會(huì)影響對(duì)全部崗位的評(píng)價(jià)。另外,這種方法對(duì)崗位的評(píng)價(jià)也是比較粗糙的,只能得出一個(gè)崗位歸在哪個(gè)等級(jí)中,到底崗位之間的價(jià)值的量化關(guān)系是怎樣的也不是很清楚,因此在用到薪酬體系中時(shí)會(huì)遇到一定的困難。同時(shí)崗位分類法適用性有點(diǎn)局限,即適合崗位性質(zhì)大致類似,可以進(jìn)行 明確的分組,并且改變工作內(nèi)容的可能性不大的崗位。 4.崗位評(píng)價(jià)法之三:因素比較法 因素比較法是一種量化的崗位評(píng)價(jià)方法,它實(shí)際上是對(duì)崗位排序法的一種改進(jìn)。這種方法與崗位排序法的主要區(qū)別是:崗位排序法是從整體的角度對(duì)崗位進(jìn)行比較和排序,而因素比較法則是選擇多種報(bào)酬因素,按照各種因素分別進(jìn)行排序。 分析基準(zhǔn)崗位,找出一系列共同的報(bào)酬因素。這些報(bào)酬因素是應(yīng)該能夠體現(xiàn)出崗位之間的本質(zhì)區(qū)別的一些因素,例如責(zé)任、工作的復(fù)雜程度、工作壓力水平、工作所需的教育水平和工作經(jīng)驗(yàn)等。將每個(gè)基準(zhǔn)崗位的工資或所賦予的分值分配到相應(yīng)的報(bào)酬因素上。 因素比較法的一個(gè)突出優(yōu)點(diǎn)就是可以根據(jù)在各個(gè)報(bào)酬因素上得到的評(píng)價(jià)結(jié)果計(jì)算出一個(gè)具體的報(bào)酬金額,這樣可以更加精確的反映出崗位之間的相對(duì)價(jià)值關(guān)系。一般在下列條件下因素比較法較為適用:需要一種量化方法,愿花大量的費(fèi)用引入一種崗位評(píng)價(jià)體系;這種復(fù)雜方法的運(yùn)用不會(huì)產(chǎn)生理解問題或雇員的接受問題,并且希望把工資結(jié)構(gòu)和基準(zhǔn)崗位的相對(duì)等級(jí)或勞動(dòng)力市場(chǎng)上通行的工資更緊密聯(lián)系起來。 應(yīng)用因素比較法時(shí),應(yīng)該注意兩個(gè)問題:一個(gè)是薪酬因素的確定要比較慎重,一定要選擇最能代表崗位間差異的因素;第二個(gè)問題是由于市場(chǎng)上的工資水平經(jīng)常發(fā)生變化,因此要及時(shí)調(diào)整基準(zhǔn)崗位的工資水平。但是由于我國(guó)處于經(jīng)濟(jì)體制的轉(zhuǎn)軌時(shí)期,多種薪酬體制并存;同時(shí)國(guó)內(nèi)薪酬體制透明度較低,勞動(dòng)力市場(chǎng)價(jià)格處于混沌狀態(tài),因而使用因素比較法的基礎(chǔ)數(shù)據(jù)不足。目前因素比較法在國(guó)內(nèi)基本未得到使用。 5.崗位評(píng)價(jià)法之四:要素計(jì)點(diǎn)法 要素計(jì)點(diǎn),就是選取若干關(guān)鍵性的薪酬因素,并對(duì)每個(gè)因素的不同水平進(jìn)行界定,同時(shí)給各個(gè)水平賦予一定的分值,這個(gè)分值也稱作是“點(diǎn)數(shù)”,然后按照這些關(guān)鍵的薪酬因素對(duì)崗位進(jìn)行評(píng)價(jià),得到每個(gè)崗位的總點(diǎn)數(shù),以此決定崗位的薪酬水平。要素計(jì)點(diǎn)法首先選擇薪酬要素,并將這些薪酬要素建立起一個(gè)結(jié)構(gòu)化的量表。專家委員會(huì)根據(jù)這個(gè)評(píng)定量表對(duì)崗位在各個(gè)要素上進(jìn)行評(píng)價(jià),得出崗位在各個(gè)要素上的分值,并匯總成總的點(diǎn)數(shù),再根據(jù)總點(diǎn)數(shù)處在哪個(gè)崗位級(jí)別的點(diǎn)數(shù)區(qū)間內(nèi),確定崗位的級(jí)別。要素計(jì)點(diǎn)法主要的缺點(diǎn)是操作過程較為復(fù)雜,而且提前要與員工進(jìn)行充分的溝通,以對(duì)要素理解達(dá)成共識(shí)。 要素計(jì)點(diǎn)法在下述情況下可能是最合適的:工作崗位資料穩(wěn)定、清晰、完整,工資決策需要明確無(wú)誤,是采用量化方法所費(fèi)額外成本物有所值;而排列大量的極不相同的工作崗位的需要使考慮運(yùn)用一系列通用因素成為必然。 數(shù)據(jù)結(jié)構(gòu)——冒泡排序(第19講,第9章) 一、復(fù)習(xí)回顧 什么是排序:排序是把一個(gè)無(wú)序的數(shù)據(jù)元素序列整理成有規(guī)律的按排序關(guān)鍵字遞增(或遞減)排列的有序序列的過程。 /************************************************(已經(jīng)學(xué)過的排序方法有:直接插入排序、希爾排序、直接插入排序:順序的把待排序序列中的各個(gè)記錄按其關(guān)鍵字的大小,插入到已排序的序列的適當(dāng)位置。 希爾排序:(縮小增量排序),不斷把待排序的記錄分成若干個(gè)小組,對(duì)同一組內(nèi)的記錄進(jìn)行排序,在分組時(shí),始終保持當(dāng)前組內(nèi)的記錄個(gè)數(shù)超過前面分組排序時(shí)組內(nèi)的記錄個(gè)數(shù)。) ************************************************/ 二、第一小節(jié)(目標(biāo):理解掌握冒泡思想) 1、給出冒泡排序的定義(25分鐘) 將待排序序列中第一個(gè)記錄的關(guān)鍵字R1.key與第二個(gè)記錄的關(guān)鍵字R2.key作比較,如果R1.key>R2.key,則交換記錄R1和R2在序列中的位置,否則不交換;然后繼續(xù)對(duì)當(dāng)前序列中的第二個(gè)記錄和第三個(gè)記錄作同樣的處理,依此類推,知道序列中倒數(shù)第二個(gè)記錄和最后一個(gè)記錄處理完為止,我們稱這樣的過程為一次冒泡排序。 2、請(qǐng)學(xué)生上臺(tái)做排序練習(xí)(15分鐘做題+10分鐘講解)(鞏固排序思想的掌握) 第一題: 38 5 19 26 49 97 1 66 第一次排序結(jié)果:5 19 26 38 49 1 66 [97] 第二次排序結(jié)果:5 19 26 38 1 49 [66 97] 第三次排序結(jié)果:5 19 26 1 38 [49 66 97] 第四次排序結(jié)果:5 19 1 26 [38 49 66 97] 第五次排序結(jié)果:5 1 19 [26 38 49 66 97] 第六次排序結(jié)果:1 5 [19 26 38 49 66 97] 第七次排序結(jié)果:1 [5 19 26 38 49 66 97] 最后結(jié)果序列: 1 5 19 26 38 49 66 97 第二題: 8 7 6 5 4 3 2 1 數(shù)據(jù)結(jié)構(gòu)——冒泡排序(第19講,第9章) 答 第一次排序: 7 6 5 4 3 2 1 [8] 第二次排序: 6 5 4 3 2 1 [7 8] 第三次排序: 5 4 3 2 1 [6 7 8] 第四次排序: 4 3 2 1 [5 6 7 8] 第五次排序: 3 2 1 [4 5 6 7 8] 第六次排序: 2 1 [3 4 5 6 7 8] 第七次排序: 1 [2 3 4 5 6 7 8] 最后結(jié)果序列: 1 2 3 4 5 6 7 8 第二題: 1 2 3 4 5 6 7 8 第一次排序: 1 2 3 4 5 6 7 [8] 第二次排序: 1 2 3 4 5 6 [7 8] 第三次排序: 1 2 3 4 5 [6 7 8] 第四次排序: 1 2 3 4 [5 6 7 8] 第五次排序: 1 2 3 [4 5 6 7 8] 第六次排序: 1 2 [3 4 5 6 7 8] 第七次排序: 1 [2 3 4 5 6 7 8] 最后結(jié)果序列: 1 2 3 4 5 6 7 8] 從練習(xí)題中引出:一次冒泡排序的結(jié)果:使關(guān)鍵字最大的記錄排在了序列的最后一個(gè)位置上。(這很重要,要強(qiáng)調(diào)) 比較后兩題的題目區(qū)別和排序過程區(qū)別,作為課間思考題。(第二題是一組逆序數(shù)據(jù),每一個(gè)排序都進(jìn)行了數(shù)據(jù)交換,共進(jìn)行了8-1=7次冒泡;第三題是一組正序數(shù)據(jù),進(jìn)行完一次排序后就發(fā)現(xiàn),沒有任何數(shù)據(jù)交換發(fā)生,后面進(jìn)行的第二次到第七次冒泡的過程完全一樣。) 三、第二小節(jié) 3、冒泡排序終止的條件(20分鐘) 課堂思考題:考慮任何一組序列最多進(jìn)行多少次冒泡排序就可保證順序一定已經(jīng)排好了。 思考:如果序列初始順序是逆序,需要進(jìn)行多少次排序(要記住,數(shù)據(jù)結(jié)構(gòu)——冒泡排序(第19講,第9章) 每次冒泡排序的結(jié)果:可以保證最大的記錄在最后一個(gè)位置上)。如果序列初始順序是正序,需要進(jìn)行多少次排序就可以保證數(shù)據(jù)序列順序。如何使排序過程適可而止?既排好序又不多余進(jìn)行? 當(dāng)計(jì)算機(jī)對(duì)一組數(shù)據(jù)進(jìn)行排序之前,并不知道該組數(shù)據(jù)是什么順序,因此,必須要進(jìn)行至少一次的比較和排序,當(dāng)某一比較和排序進(jìn)行完之后發(fā)現(xiàn)沒有任何數(shù)據(jù)交換發(fā)生,證明任何相鄰的兩數(shù)都符合目標(biāo)順序要求,因此,也不必再進(jìn)行下一下比較排序了。 結(jié)論:當(dāng)進(jìn)行某次冒泡排序時(shí),若沒有任何兩個(gè)記錄交換位置,則表明序列已排好,此時(shí)排序可結(jié)束。 4、用文字(偽碼)描述冒泡排序算法(15分鐘)思考方法: 首先是對(duì)數(shù)組的相鄰的兩數(shù)比較,根據(jù)比較結(jié)果確定是否交換位置;這種比較進(jìn)行的次數(shù)比數(shù)據(jù)列中數(shù)據(jù)個(gè)數(shù)少1; (此兩步完成了一次冒泡排序) 對(duì)一個(gè)序列來說,共進(jìn)行多少次冒泡排序呢?最多和上面第二步的比較次數(shù)一樣,但也可提前結(jié)束,只要在某一遍冒泡中沒有發(fā)生數(shù)據(jù)交換即可。如何確實(shí)是否發(fā)生數(shù)據(jù)交換,在程序中,可以考慮設(shè)置一個(gè)標(biāo)志位,當(dāng)發(fā)生數(shù)據(jù)交換時(shí),更改標(biāo)志位,每次重新進(jìn)行冒泡排序之前可以檢查標(biāo)志位,如果沒有發(fā)生改變,則可證明上一次冒泡已經(jīng)沒有數(shù)據(jù)交換發(fā)生,也就是說數(shù)據(jù)序列已經(jīng)排好,可以停止進(jìn)行冒泡排序。 冒泡算法函數(shù) { 設(shè)置標(biāo)志位; //以下循環(huán)用來控制冒泡排序進(jìn)行的次數(shù) 數(shù)據(jù)結(jié)構(gòu)——冒泡排序(第19講,第9章) for循環(huán)(對(duì)n個(gè)數(shù)據(jù)的序列進(jìn)行n-1次冒泡,但是如果沒有交換發(fā)生則跳出該循環(huán)){ //以下循環(huán)用來對(duì)該數(shù)據(jù)序列進(jìn)行一次冒泡排序 for(單次冒泡排序需要進(jìn)行n-1次){ 比較相鄰兩數(shù)的大小; if(前大后小){ 交換 } else //前小后大 { 位置不變 } } } } 5、回顧總結(jié)冒泡排序的思想(10分鐘)本節(jié)課: 1.首先回顧了什么是排序; 2.然后介紹了冒泡排序的思想;(每次冒一個(gè)泡泡,把最大的冒到最后)3.我們通過三道練習(xí)題對(duì)一組無(wú)序數(shù)據(jù)進(jìn)行了排序; 4.通過練習(xí)題我們看出來,數(shù)據(jù)初始序列越接近目標(biāo)序列,冒泡的次數(shù)越少;因此我們總結(jié)出了冒泡排序最多進(jìn)行的次數(shù)和終止的條件; 5.最后,我們根據(jù)冒泡排序的思想用文字描述了冒泡函數(shù)的構(gòu)成方法; 四、課后作業(yè) 1、用冒泡排序法對(duì)數(shù)字序列進(jìn)行排序(要寫出6次排序步驟) 55 48 37 10 90 84 答 55 48 37 10 60 84 90 48 37 10 55 60 84 90 37 10 48 55 60 84 90 10 37 48 55 60 84 90 數(shù)據(jù)結(jié)構(gòu)——冒泡排序(第19講,第9章) 10 37 48 55 60 84 90 2、用C語(yǔ)言描述冒泡排序算法。 Void BubbleSort(elemtype x[],int n)//傳入序列和序列數(shù)字個(gè)數(shù) { int i,j,flag=1;elemtype temp;for(i=1;i 《算法導(dǎo)論》學(xué)習(xí)總結(jié)——快速排序 曾經(jīng)在程序員雜志上看到快速排序的作者,Hoare,曾經(jīng)的圖靈獎(jiǎng)獲得者啊,牛光閃閃的。不過當(dāng)時(shí),對(duì)快速排序什么的,印象不算深刻,畢竟沒好好學(xué)。記得當(dāng)時(shí)雜志上說到的是,快速排序,應(yīng)該是目前最快的內(nèi)部排序算法(雖然獨(dú)立到語(yǔ)言上,C++的sort會(huì)比調(diào)用快速排序快)。現(xiàn)在就進(jìn)入快速排序的美好復(fù)習(xí)吧。 與歸并排序類似,快排也用分治模式。主要是三個(gè)步驟: 1)分解:將數(shù)組A[p....r]劃分為2個(gè)子數(shù)組A[p....q-1]和A[q+1....r],使前一個(gè)每個(gè)元素都小于A[q],后一個(gè)數(shù)組,每個(gè)元素都大于A[q](q在劃分過程中計(jì)算) 2)解決:遞歸調(diào)用快速排序,對(duì)2個(gè)子數(shù)組進(jìn)行排序 3)合并:因?yàn)?個(gè)子數(shù)組是就地排序,所以合并不用操作,數(shù)組已排序 看到這個(gè)合并,就想到啊,和歸并比,一個(gè)從小到大,一個(gè)從大到小,差距就是這么大,快排么得合并開銷,一下就省了很多啊,說明,方向很重要啊,如同那句,同樣一個(gè)B,S與N的差別,大家都懂的。 快速排序的實(shí)現(xiàn)代碼如下: ? ? ? ? ? ? ? ? //================= // Name : Qsort.cpp // Author : xia // Copyright : NUAA // Description : 快速排序的實(shí)現(xiàn) //================= #include #include #include ?? #include ?? #include ?? ?? using namespace std;?? const int MAX = 1000;?? ?? void WriteToFile(vector ?? {//將v寫入文件,純看排序結(jié)果是否正確,也可以寫個(gè)test() ?? int i;?? ofstream result(“Qsort.txt”);?? if(result.fail())?? { ?? cout << “ open data error ” << endl;?? exit(EXIT_FAILURE);?? } ?? for(i=0;i ?? result << v[i] << “ ”;?? } ?? result.close();?? } ?? int Partion(vector ?? int x=A[r];//x都感覺沒用 ?? int i=p-1; ?? for(int j=p;j ?? if(A[j] <= x)?? { ?? i++; ?? swap(A[i],A[j]);?? } ?? } ?? swap(A[i+1],A[r]);?? return i+1;?? } ?? void Qsort(vector ?? if(p < r)?? { ?? int q = Partion(A,p,r);?? Qsort(A,p,q-1);?? Qsort(A,q+1,r);?? } ?? } ?? int main(int argc, char **argv)?? { ?? vector int i; ?? for(i=0;i< MAX;i++)?? v.push_back(i); ?? random_shuffle(v.begin(),v.end());//打亂 ?? ?? Qsort(v,0,v.size()-1);?? WriteToFile(v);?? ?? return 0;?? } 說到代碼,很慚愧的,http://)由于以下兩個(gè)原因: 1)做格式化時(shí),結(jié)果常常是扭曲的,所以得不到正確的隨機(jī)數(shù)(如某些數(shù)的出現(xiàn)頻率要高于其它數(shù)) 2)rand()只支持整型數(shù);不能用它來產(chǎn)生隨機(jī)字符,浮點(diǎn)數(shù),字符串或數(shù)據(jù)庫(kù)中的記錄 所以采用了STL函數(shù)random_shuffle(),先隨機(jī)生成0到MAX-1的隨機(jī)數(shù),用random_shuffle()打亂,再進(jìn)行排序。 另外,其實(shí)Hoare老師用的快排并不是如上代碼所示,也就是說,最原始的快速排序,是這樣滴: int HoarePartion(vector ?? int x=A[p];?? int i=p-1;?? int j=r+1;?? while(1)?? { ?? while(A[--j] > x)??; ?? while(A[++i] < x)??;?? if(i ?? swap(A[i],A[j]);?? else ?? return j;?? } ?? } ?? ?? void Qsort(vector if(p < r)?? { ?? int q = HoarePartion(A,p,r);?? Qsort(A,p,q);?? Qsort(A,q+1,r);?? } ?? } 也可以參考:http://tayoto.blog.hexun.com/25048556_d.html,區(qū)別只是我的代碼直接while里面用A[--j],可讀性不高,因?yàn)橹鴮?shí)不喜歡do-while結(jié)構(gòu)。 對(duì)于最原始的快排,嚴(yán)蔚敏老師的《數(shù)據(jù)結(jié)構(gòu)》是這樣實(shí)現(xiàn)的: int Partion(vector int pivotkey;?? pivotkey = v[low];?? while(low < high)??? { ??? while(low < high && v[high] >= pivotkey)??? high--;??? v[low] = v[high]; ??? while(low < high && v[low] <= pivotkey)??? low ++; ??? v[high] = v[low];??? } ??? v[low] = pivotkey;??? return low;??? } ??? void quickSort(vector ??? if(left < right)??? { ??? int i = Partion(number , left, right); ??? quickSort(number, left, i-1);// 對(duì)左邊進(jìn)行遞歸 ??? quickSort(number, i+1, right);// 對(duì)右邊進(jìn)行遞歸 ??? } ??? } 當(dāng)然,區(qū)別都只是在劃分的過程,畢竟分治,才是快排的精髓嘛,不過這倆大同小異。 快排的運(yùn)行時(shí)間,顯然與劃分是否對(duì)稱有關(guān),要是直接劃分出來,是一個(gè)最不均衡的二叉樹,那就夠喝一壺的了,跟插入排序似的。下面網(wǎng)址有說法,是快排隱藏的二叉排序樹思想,其實(shí)可以參考,雖然只是個(gè)人理解http://bbs.chinaunix.net/viewthread.php?tid=1011316。其實(shí)說到二叉,堆排序不也是嗎?區(qū)別只是堆排序顯式的建堆,也就構(gòu)成了一筆不小的開銷,如果考慮隱藏排序二叉樹的話,倒是可以理解為毛快排快于堆排。 由于快排平均情況下效果顯然很良好,那么怎么得到平均情況就是個(gè)值得思考的問題,所以書上給出了,在劃分的時(shí)候,隨機(jī)獲取一個(gè)數(shù)作為樞軸,而不是用我們的A[low]。于是我們得到了快排的隨機(jī)化版本如下: int Partion(vector ??? int x=A[r];??? int i=p-1; ??? for(int j=p;j ??? if(A[j] <= x)??? { ??? i++; ??? swap(A[i],A[j]);??? } ??? } ??? swap(A[i+1],A[r]);??? return i+1;??? } ??? int RandomPartion(vector int i= p + rand()%(r-p+1);//i<-RANDOM(p,r) ??? swap(A[r],A[i]);??? return Partion(A,p,r);??? } ??? void RandomQsort(vector ??? if(p < r)??? { ??? int q = RandomPartion(A,p,r);??? RandomQsort(A,p,q-1);??? RandomQsort(A,q+1,r);??? } ??? } 與常規(guī)快排的區(qū)別,就是在劃分的時(shí)候,獲取一個(gè)隨機(jī)數(shù)下標(biāo),再用其數(shù)組中的值作為樞軸,當(dāng)然,這樣就充分考慮平均性能了。 還有一種改進(jìn)RANDOM-QUICKSORT的方法,就是根據(jù)從子數(shù)組更仔細(xì)地選擇的(而不是隨機(jī)選擇的元素)作為樞軸來劃分。常用的做法是三數(shù)取中。可以參考: http://blog.csdn.net/zhanglei8893/article/details/6266915 本章最后還提到個(gè)很蛋疼的Stooge排序,實(shí)現(xiàn)如下: void StoogeSort(vector ??? if(A[i] > A[j])??? swap(A[i],A[j]);??? if(i+1 >=j)??? return; ??? int k =(j-i+1)/3; ??? StoogeSort(A,i,j-k);//前2/ 3??? StoogeSort(A,i+k,j);//后2/3 ??? StoogeSort(A,i,j-k);//又前2/3 ??? // StoogeSort(A,i,i+k-1);// 如果采用1/3排不出來啊 ??? } 對(duì)于數(shù)組A[i...j],STOOGE-SORT算法將這個(gè)數(shù)組劃分成均等的3份,分別用A, B, C表示。第8、9行從宏觀上來看它進(jìn)行了兩趟,結(jié)果是最大的1/3到了C,最小的1/3到了B,從宏觀上來看,整個(gè)數(shù)組的三個(gè)大塊就有序了,再進(jìn)行遞歸,整個(gè)數(shù)組就有序了。第8和第9行,可以看做一個(gè)冒泡過程。 不過從運(yùn)行時(shí)間的測(cè)試來講,很不給力(具體數(shù)據(jù)就不列了)。STOOGE-SORT最壞情況下的運(yùn)行時(shí)間的遞歸式 T(n)= 2T(2n/3)+Θ(1)由主定律可以求得T(n)=n^2.71,相比插入排序、快速排序的Θ(n^2)和 堆排序、合并排序的Θ(nlgn),不給力啊。參考自:http://blog.csdn.net/zhanglei8893/article/details/6235294。 本章最后,練習(xí)7-4還提出個(gè)尾遞歸的概念,起因是QuickSort的第二次遞歸調(diào)用不是必須的,可以用迭代控制結(jié)構(gòu)來替代。如: QUICKSORT'(A, p, r)1 while p < r 2 do ? Partition and sort left subarray.3 q ← PARTITION(A, p, r)4 QUICKSORT'(A, p, q-1)5 p ← q + 1 具體 有效性的證明可以參考:http://blog.csdn.net/zhanglei8893/article/details/6236792,需要說明的是,當(dāng)數(shù)組正序時(shí),其遞歸深度和棧深度都為Θ(n)。 第五種,排序考核法 這也是目前比較流行的輔助性考核方式,就是建立排行榜,來自于傳統(tǒng)的金榜提名,與社會(huì)上各類排行榜類似,發(fā)揮刺激作用,如各類體育競(jìng)賽的獎(jiǎng)牌榜就是這種方式的典范。一般也會(huì)與獎(jiǎng)罰掛鉤。最典型的是末尾淘汰制,一般用于上山型人員。 銷售系統(tǒng)的各類排行榜: 月度回款排行榜 月度銷售額冠軍 月度大客戶冠軍 還可以倒數(shù)排名,如全勤倒數(shù)排名、回款倒數(shù)排名 其他: 月度合理化建議排行榜,月度某類行動(dòng)排行榜 第六種,關(guān)鍵業(yè)績(jī)指標(biāo)法(KPI) 這就是目前最為流行的比較系統(tǒng)的績(jī)效考核方法。KPI已經(jīng)成為企業(yè)界的流行縮寫了。 KPI是一種關(guān)鍵績(jī)效指標(biāo)的縮寫,有兩種說法: 一種美式說法,關(guān)鍵績(jī)效指標(biāo)即,Key Performance Indicator。這是來自美國(guó)哈佛大學(xué)商學(xué)院的說法。 另一種是來自英式,Key Process Indication。 現(xiàn)在,國(guó)內(nèi)主要采用美式說法。這種方法的優(yōu)點(diǎn)在于,對(duì)于考核的指標(biāo)進(jìn)行了歸類,并對(duì)其中影響力最強(qiáng)的指標(biāo)突出了出來,避免了指標(biāo)的雜亂無(wú)章和如海的繁雜指標(biāo)體系。何謂關(guān)鍵? 我們認(rèn)為,關(guān)鍵指標(biāo)主要是有兩類: 一類是與崗位職責(zé)相關(guān)的指標(biāo); 一類是與上級(jí)要求完成任務(wù)的指標(biāo)。 如何選取? 一般的做法是,用SMART原則選取可以執(zhí)行的目標(biāo),從關(guān)鍵成功領(lǐng)域和關(guān)鍵價(jià)值樹中尋找關(guān)鍵績(jī)效指標(biāo)。 這種做法在大企業(yè)中已經(jīng)形成共識(shí),并頗為盛行。 對(duì)于廣大的中小企業(yè),不要搞這么復(fù)雜,只要抓住“關(guān)鍵”二字即可:目前公司最為關(guān)注的、上級(jí)領(lǐng)導(dǎo)最為關(guān)心的,就是“關(guān)鍵”; 屬于自身核心職責(zé)的、崗位中最為基本的,就是“關(guān)鍵”。 指標(biāo)分類 選多少指標(biāo)合適? 國(guó)富創(chuàng)新管理咨詢公司擁有了9年的實(shí)踐經(jīng)驗(yàn),為350多家企業(yè)提供了績(jī)效考核的咨詢,涉及行業(yè)20多個(gè),一般先幫助企業(yè)建立完善系統(tǒng)的指標(biāo)庫(kù),然后根據(jù)上述“關(guān)鍵”定義抽取KPI。 咨詢經(jīng)驗(yàn)告訴我們,一個(gè)崗位上的KPI不宜過多,大概在5-7個(gè),占其崗位考核指標(biāo)庫(kù)的30%。一般而言,30%以上的抽樣基本上能夠反映一個(gè)崗位的關(guān)鍵狀態(tài)了。 一般情況下,一個(gè)人數(shù)較多、事情比較復(fù)雜的部門,部門經(jīng)理的KPI為5-7個(gè);而一個(gè)人數(shù)較少、事務(wù)單一的部門,部門經(jīng)理的KPI可能就是1-3個(gè)。指標(biāo)太多了,增加了考核的難度和工作量,不容易堅(jiān)持。 確定KPI的關(guān)鍵要求: 首先,要確定上級(jí)或公司對(duì)于這個(gè)崗位的最重要要求(因?yàn)椴煌碾A段,公司領(lǐng)導(dǎo)對(duì)于一個(gè)崗位的關(guān)鍵要求也會(huì)略有不同)。 其次,將這種要求的結(jié)果定義加以明確。 第三,深入了解該崗位的核心職責(zé)及其對(duì)于首要任務(wù)的影響度。 第四,反復(fù)溝通該指標(biāo)成為目標(biāo)的可行性(是否符合SMART原則)。 例如,營(yíng)銷總監(jiān)的指標(biāo)第七種,平衡計(jì)分卡法(BSC) 這是目前最為流行的績(jī)效考核方法,跨國(guó)公司和國(guó)內(nèi)的大中型企業(yè)基本上都采取了這種方法。 這應(yīng)該是目前最為綜合型的一種方法。它擁有明顯的綜合性,或者叫做平衡性,基本上是綜合了KPI、記分制、多方面考核的要素而集成的。 平衡計(jì)分卡的英文簡(jiǎn)稱為BSC,是Balanced Score Card的縮寫,源自哈佛大學(xué)教授卡普蘭與諾朗頓研究院(Nolan Norton Institute)的首席執(zhí)行官David 諾頓于上世紀(jì)90年代提出來的。 一些專家認(rèn)為,BSC太復(fù)雜,對(duì)于基礎(chǔ)數(shù)據(jù)的依賴性太強(qiáng),建議中小企業(yè)不要用,我覺得,這是偏見,或者研究不到位造成的。 該方法強(qiáng)調(diào)了“平衡”,尤其強(qiáng)調(diào)財(cái)務(wù)指標(biāo)與非財(cái)務(wù)指標(biāo)的平衡,核心是要求管理者不應(yīng)僅僅突出財(cái)務(wù)指標(biāo)的完成,還要照顧其他指標(biāo)的完成,要求管理者在選取KPI的時(shí)候,不要一味的關(guān)注財(cái)務(wù)指標(biāo)或其他指標(biāo)。 在BSC的發(fā)明者看來,要首先公司的戰(zhàn)略目標(biāo),需要關(guān)注四類指標(biāo),這四類指標(biāo)相互制約,構(gòu)建協(xié)同型組織,直接影響著戰(zhàn)略目標(biāo)的達(dá)成,因此,他們稱由此四類指標(biāo)組成的指標(biāo)樹為“戰(zhàn)略地圖”。 這四類指標(biāo)包括: 財(cái)務(wù)類指標(biāo):這是基礎(chǔ)性指標(biāo),公司存在的根基。 客戶類指標(biāo):將滿足客戶需求行為指標(biāo)化,關(guān)注客戶滿意。 內(nèi)部運(yùn)營(yíng)指標(biāo):這是對(duì)于內(nèi)部管理的評(píng)價(jià)。 學(xué)習(xí)與成長(zhǎng)指標(biāo):這是對(duì)于公司長(zhǎng)遠(yuǎn)發(fā)展投入的評(píng)價(jià)。 大家可以看到,這種比較系統(tǒng)的評(píng)價(jià)體系,明顯具有戰(zhàn)略性,照顧了長(zhǎng)遠(yuǎn)性,這是以往任何一種評(píng)價(jià)體系都沒有照顧到的,至少?zèng)]有將這些指標(biāo)有機(jī)的結(jié)合在一起。 這是一次革命性的突破。 一個(gè)注重長(zhǎng)遠(yuǎn)利益的公司一般愿意采用這種評(píng)價(jià)方式。 指標(biāo)體系可以不完美,但是可以起步走。 一個(gè)規(guī)模比較小的企業(yè),也可以對(duì)聘來的總經(jīng)理以及中高層管理者進(jìn)行BSC的考核,避免他們只關(guān)心某些指標(biāo),比如營(yíng)銷總監(jiān),不僅考核他經(jīng)濟(jì)業(yè)績(jī)指標(biāo)的完成,還要考核他對(duì)于制度建設(shè)、團(tuán)隊(duì)建設(shè)的指標(biāo),包括你在內(nèi)部管理上建立了什么樣的制度(內(nèi)部運(yùn)營(yíng))、你給員工進(jìn)行了什么樣的培訓(xùn)(學(xué)習(xí)與成長(zhǎng))、你的任期內(nèi),客戶滿意度提升多少(客戶類)。BSC基本上是KPI的高級(jí)分類方法。 值得注意的是,這四類指標(biāo)不是同樣的權(quán)重,可以根據(jù)公司的戰(zhàn)略目標(biāo)要求和階段任務(wù),選擇不同的權(quán)重。 因此,BSC的平衡性是任何一種考核法不能比擬的: 關(guān)注了長(zhǎng)遠(yuǎn)目標(biāo)(成長(zhǎng))和短期目標(biāo)(財(cái)務(wù))的平衡; 關(guān)注了財(cái)務(wù)目標(biāo)(財(cái)務(wù))和非財(cái)目標(biāo)(其他)的平衡; 關(guān)注了內(nèi)部目標(biāo)(運(yùn)營(yíng))和外部目標(biāo)(客戶)的平衡。 有人問:周博士,這些指標(biāo)如何選取呢? 其實(shí),這種指標(biāo)的選取與KPI指標(biāo)的選取是一樣的,只是KPI的高級(jí)分類方法,不過,它更注重這些指標(biāo)對(duì)于戰(zhàn)略目標(biāo)的支撐度。 運(yùn)用BSC方法需要注意的關(guān)鍵點(diǎn): 首先,公司四大類指標(biāo)的權(quán)重取決于公司戰(zhàn)略目標(biāo)的重點(diǎn),部門指標(biāo)的權(quán)重取決于部門的任務(wù)重點(diǎn)和職責(zé)。 其次,要通過深入溝通注意目標(biāo)值的上下平衡,與上級(jí)的目標(biāo)值保持一致,以便形成公司的戰(zhàn)略地圖。 建議:下面指標(biāo)的總和要大于總目標(biāo),避免完不成第三,提前做好宣傳和相關(guān)技術(shù)的訓(xùn)練,通過各類通俗易懂的方式讓所有員工都清晰的理解這種方法的合理性。 第四,最好是與外部咨詢顧問一起選取相關(guān)指標(biāo)并構(gòu)建BSC體系,因?yàn)槠渲行枰托牡拇罅繙贤ǎ残枰獙I(yè)的技術(shù),如指標(biāo)權(quán)重的選擇、指標(biāo)值的測(cè)算、相關(guān)數(shù)據(jù)的采集。案例:某司法培訓(xùn)學(xué)校 第八種,經(jīng)濟(jì)附加值考核法(EVA) EVA是經(jīng)濟(jì)附加值英文名稱Economic Value Added,的縮寫簡(jiǎn)稱,是由美國(guó)學(xué)者Stewart提出的一套考核方法,主要用于股東對(duì)經(jīng)營(yíng)層的考核。 它是基于稅后營(yíng)業(yè)凈利潤(rùn)和產(chǎn)生這些利潤(rùn)所需資本投入總成本的一種考績(jī)效考核方法,側(cè)重于財(cái)務(wù)評(píng)價(jià)。 這是目前比較高級(jí)的一種考核方法,國(guó)資委對(duì)于央企采取了這樣的考核方法。 其實(shí),這也不像聽起來那么高端,我們公司內(nèi)訓(xùn)體系長(zhǎng)期實(shí)施的凈利潤(rùn)考核方法就是這種的變種,只是對(duì)于收入數(shù)據(jù)和成本數(shù)據(jù)的要求比較嚴(yán)格。從定義上看,EVA指標(biāo)所考核的是一種在扣除了資本成本之后的營(yíng)業(yè)利潤(rùn)。它不再是我們所說的會(huì)計(jì)利潤(rùn),而成為一種經(jīng)濟(jì)利潤(rùn)(即扣除了機(jī)會(huì)成本)。所以,EVA指標(biāo)與傳統(tǒng)的會(huì)計(jì)指標(biāo)不同,它是一種從投資者的角度,追求利益最大化的指標(biāo)體系。 它的一般計(jì)算公式是: EVA=稅后利潤(rùn)-資本費(fèi)用 其中:稅后利潤(rùn)=營(yíng)業(yè)利潤(rùn)-所得稅額。 資本費(fèi)用=總資本×平均資本費(fèi)用率 其中:平均資本費(fèi)用率=資本或股本費(fèi)用率×資本構(gòu)成率+負(fù)債費(fèi)用率×負(fù)債構(gòu)成率。 目前,我國(guó)使用如此考核方法的主要是些控股型的超大型企業(yè),核心群體是中央企業(yè),因其計(jì)算復(fù)雜、操作復(fù)雜,對(duì)于會(huì)計(jì)手段和數(shù)據(jù)收集的要求比較高,很多企業(yè)不敢使用,我建議中小企業(yè)的企業(yè)家聽聽就可以了,以后規(guī)模大了或者上市以后再說。 而且,該方法強(qiáng)調(diào)財(cái)務(wù)指標(biāo)體系,對(duì)其他指標(biāo)有所忽略,因此,局限性比較明顯,主要適合于投資控股型企業(yè)。 以上方法往往是混合使用,選擇不能偏廢,一定要將主動(dòng)權(quán)把握在于自己手中,周博士推薦使用的是混合型考核,并與國(guó)富團(tuán)隊(duì)一起開發(fā)了混合型的國(guó)富考核方法,這種方法尤其適用于我國(guó)的中小企業(yè),大型企業(yè)也可使用。 績(jī)效管理的9大關(guān)鍵點(diǎn): 關(guān)鍵點(diǎn)1:績(jī)效管理體系建設(shè)要內(nèi)部人員與外部專家相結(jié)合。 關(guān)鍵點(diǎn)2:績(jī)效管理也是一把手工程,高層要有真正的決心 關(guān)鍵點(diǎn)3:績(jī)效考核的具體操作部門要深入掌握工具和政策 關(guān)鍵點(diǎn)4:通過多層次溝通,統(tǒng)一思想、建立對(duì)話語(yǔ)言平臺(tái) 關(guān)鍵點(diǎn)5:指標(biāo)及指標(biāo)體系要與當(dāng)事人反復(fù)磨合,深入了解指標(biāo)產(chǎn)生的源頭關(guān)鍵點(diǎn)6:避免棘輪效應(yīng)的負(fù)效應(yīng) 關(guān)鍵點(diǎn)7:深入研究指標(biāo)提取方法,注意對(duì)于人與事務(wù)的分類合理化 關(guān)鍵點(diǎn)8:不能完全依賴模式,要實(shí)現(xiàn)經(jīng)驗(yàn)要素與客觀要素的相結(jié)合關(guān)鍵點(diǎn)9:一定要與薪酬獎(jiǎng)罰、任職任用相結(jié)合。第二篇:崗位排序法
第三篇:冒泡排序法教案
第四篇:《算法導(dǎo)論》學(xué)習(xí)總結(jié)——快速排序
第五篇:績(jī)效考核方法_排序考核法