第二章 算法基礎

練習

2.1-1 以圖2-2為模型垮耳,說明INSERTION-SORT在數(shù)組A=[31,41,59,26,41,58]上的執(zhí)行過程栅屏。

[31,41,59,26,41,58] key = 41

[31,41,59,26,41,58] key = 59

[31,41,59,26,41,58] key = 26

[31,41,59,59,41,58] key = 26

[31,41,41,59,41,58] key = 26

[31,31,41,59,41,58] key = 26

[26,31,41,59,41,58] key = 26

[26,31,41,59,41,58] key = 41

[26,31,41,59,59,58] key = 41

[26,31,41,41,59,58] key = 41

[26,31,41,41,59,58] key = 58

[26,31,41,41,59,59] key = 58

[26,31,41,41,58,59] key = NIL

2.1-2 重寫過程INSERTION-SORT,使之按照非升序排序。

void INSERTION_SORT(int A[], int len)
{
    for (int i = 1; i < len; ++i) {
        int j = i;
        int val = A[j];
        while (j > 0 && val > A[j - 1]) {
            A[j] = A[j - 1];
            j = j - 1;
        }
        A[j] = val;
    }
}

2.1-3 考慮以下查找問題:

輸入:n個數(shù)的一個序列A={a[i]}和一個值v。

輸出:下標i使得v=A[i]或者當v不在A中出現(xiàn)時佃乘,v為特殊值NIL。

寫出線性查找的偽代碼麦锯,它掃描整個序列來查找v恕稠。使用一個循環(huán)不變式來證明你的算法是正確的。確保你的循環(huán)不變式滿足三條必要的性質(zhì)扶欣。

int search(int A[], int len, int v)
{
    for (int i = 0; i < len; ++i) {
        if (v = A[i]) return i;
    }
    return -1;
}

初始化:i的值為0鹅巍,且i < len成立。

保持:每次迭代之后i自增1料祠,當i < len時總是滿足條件骆捧,且0~i-1之間的元素是被檢查過的。

終止:要么在每次循環(huán)中滿足條件v = A[i]后終止髓绽;要么當i不小于len后終止敛苇,這時0~n - 1的元素是被檢查過的,故算法正確顺呕。

2.1-4 考慮把兩個n位二進制整數(shù)加起來的問題枫攀,這兩個整數(shù)分別存儲在兩個n元數(shù)組A和B中。這兩個整數(shù)的和應該按照二進制形式存儲在一個(n + 1)元數(shù)組C中株茶。請給出該問題的形式化描述来涨,并寫出偽代碼。

int* binary_sum(int A[], int B[], int n)
{
    int* C = new int[n + 1];
    int is_overflow = 0;
    for (int i = n - 1, k = n; i >= 0; --i, --k) {
        C[k] = A[i] + B[i] + is_overflow;
        if (C[k] > 1) is_overflow = 1;
        else is_overflow = 0;
        C[k] %= 2;
    }
    C[k] = is_overflow;
    return C;
}

練習

2.2-1 用Θ記號表示函數(shù)n^3 / 1000 - 100n^2 - 100n + 3启盛。

取最大項并且舍去常數(shù)系數(shù)得到:Θ(n^3)

2.2-2 考慮排序存儲在A數(shù)組A中的n個數(shù):首先找出A中的最小元素并將其與A[1]中的元素進行交換蹦掐。接著技羔,找出A中次小的元素并將其與A[2]中的元素進行交換。對A中前n - 1個元素按該方式繼續(xù)卧抗。該算法稱為選擇算法藤滥,寫出偽代碼。該算法維持的循環(huán)不變式是什么社裆?為什么它只需要對前n-1個元素拙绊,而不是對所有n個元素運行?用Θ記號給出選擇排序的最好情況和最快情況運行時間浦马。

void selection_sort(int A[], int len)
{
    for (int i = 0; i < len - 1; ++i) {
        int min_index = i;
        for (int j = i; j < len; ++j) {
            if (A[j] < A[min_index]) min_index = j;
        }
        std::swap(A[i], A[min_index]);
    }
}

因為前n-1個元素就位的時候时呀,第n個元素也一定會就位,所以只用處理n-1個元素晶默。

最好情況:Θ(n^2)。因為不管怎樣航攒,都要進行元素檢查磺陡,即使數(shù)組是有序的。

最壞情況:Θ(n^2)漠畜。

2.2-3 再次考慮線性查找問題币他,假定要查找的元素等可能的為數(shù)組中的任意元素,平均需要檢查輸入序列的多少元素憔狞?最壞情況又如何呢蝴悉?用Θ記號給出線性查找的平均情況和最壞運行情況。證明你的答案瘾敢。

最好的情況是第一個元素就找到拍冠,只需要常數(shù)的時間,而最壞的情況則需要遍歷整個數(shù)組才能找到簇抵,需要n的時間庆杜。于是平均需要檢查(n + 1) / 2個元素。

平均情況:Θ(n)碟摆。這里舍去了常數(shù)系數(shù)晃财。

最壞情況:Θ(n)。

2.2-4 我們可以如何修改幾乎任意算法來使之具有良好的運行情況運行時間典蜕?

根據(jù)輸入數(shù)據(jù)的情況去專門設計算法断盛,也就是倒推。

練習

2.3-1 使用圖2-4作為模型愉舔,說明歸并排序在數(shù)組A = [3,41,52,26,38,57,9,49]上的操作钢猛。

[3,41,52,26,38,57,9,49]

[3,41,52,26] [38,57,9,49]

[3,41] [52,26] [38,57] [9,49]

[3] [41] [52] [26] [38] [57] [9] [49] 這里是極限狀態(tài),接下來就是merge的環(huán)節(jié)

[3,41] [26,52] [38,57] [9,49]

[3,26,41,52] [9,38,49,57]

[3,9,26,38,41,49,52,57]

2.3-2 重寫MERGE屑宠,使之不用哨兵厢洞,而是一旦數(shù)組L或者R的所有元素均被復制回A就立刻停止,然后把另一個數(shù)組的剩余部分復制回A。

void merge(std::vector<int>& A, int begin, int middle, int end)
{
    std::vector<int> temp = A;
    int i = begin;
    int j = middle + 1;
    for (int k = begin; k <= end; ++k) {
        if (i > middle) A[k] = temp[j++];
        else if (j > end) A[k] = temp[i++];
        else if (temp[i] < temp[j]) A[k] = temp[i++];
        else A[k] = temp[j++];
    }
}

2.3-3 2.3-4 TODO

2.3-5 回顧查找問題躺翻,注意到丧叽,如果序列A已經(jīng)排好序,就可以將該序列的中點與v進行比較公你。根據(jù)比較的結果踊淳,原序列中有一半就可以不用再做進一步考慮了。二分查找算法重復這個過程陕靠,每次都將序列剩余部分的規(guī)模減半迂尝。為二分查找寫出迭代或者遞歸的偽代碼。證明:二分查找的最壞情況運行時間為Θ(nlgn)剪芥。

int binary_search(std::vector<int>& A, int val)
{
    int begin = 0;
    int end = A.size() - 1;
    while (begin < end) {
        int mid = begin + (end - begin) / 2;
        if (val < A[mid]) end = mid - 1;
        else if (val > A[mid]) begin = mid + 1;
        else return mid;
    }
    return -1;
}

2.3-6 我們可以使用二分查找來把插入排序的最壞情況總運行時間改進到Θ(nlgn)嗎垄开?

在鏈表上可以做到,但是在線性表上是不行的税肪,因為線性表的插入總是需要和數(shù)組長度為線性關系的時間溉躲。

2.3-7 TODO

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市益兄,隨后出現(xiàn)的幾起案子锻梳,更是在濱河造成了極大的恐慌,老刑警劉巖净捅,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疑枯,死亡現(xiàn)場離奇詭異,居然都是意外死亡蛔六,警方通過查閱死者的電腦和手機荆永,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來古今,“玉大人屁魏,你說我怎么就攤上這事∽叫龋” “怎么了氓拼?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長抵碟。 經(jīng)常有香客問我桃漾,道長,這世上最難降的妖魔是什么拟逮? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任撬统,我火速辦了婚禮,結果婚禮上敦迄,老公的妹妹穿的比我還像新娘恋追。我一直安慰自己凭迹,他們只是感情好,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布苦囱。 她就那樣靜靜地躺著嗅绸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪撕彤。 梳的紋絲不亂的頭發(fā)上鱼鸠,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音羹铅,去河邊找鬼蚀狰。 笑死,一個胖子當著我的面吹牛职员,可吹牛的內(nèi)容都是我干的麻蹋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼焊切,長吁一口氣:“原來是場噩夢啊……” “哼哥蔚!你這毒婦竟也來了?” 一聲冷哼從身側響起蛛蒙,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎渤愁,沒想到半個月后牵祟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡抖格,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年诺苹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雹拄。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡收奔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出滓玖,到底是詐尸還是另有隱情坪哄,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布势篡,位于F島的核電站翩肌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏禁悠。R本人自食惡果不足惜念祭,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碍侦。 院中可真熱鬧粱坤,春花似錦隶糕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蜒什,卻和暖如春测秸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背灾常。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工霎冯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钞瀑。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓沈撞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雕什。 傳聞我的和親對象是個殘疾皇子缠俺,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 這一章介紹貫穿全書的框架,即設計算法的大致方法過程贷岸。以插入排序和歸并排序為例壹士,介紹描述算法的方法——偽代碼,證明正...
    Nautilus1閱讀 599評論 2 1
  • 優(yōu)秀黃埔滅鼠公司采取新技術的好處是什么 對于很多人來說偿警,老鼠應該是我們最討厭的東西了躏救,它不僅會破壞我們家中的食物和...
    卡薩京東方閱讀 238評論 0 0
  • 其實,我談不出什么地鐵“哲學”螟蒸,就只能姑且“學著”了盒使。 昨天,又在地鐵車廂里聽到了爭吵七嫌。 工作日晚高峰的地鐵車廂本...
    寒江獨釣SH閱讀 431評論 0 2