第4章 演算法初步

2021-09-26 04:45:04 字數 3296 閱讀 1799

4.1排序

4.1.1選擇排序

o(n*n);

4.1.2插入排序

插入排序是將待插入元素乙個乙個插入到有序部分的過程

4.1.3排序題與sort應用

4.2雜湊的定義與整數雜湊

直接把輸入的數作為陣列的下標對這個數進行統計

雜湊:將元素通過乙個函式轉換為整數,使該整數盡可能唯一的代表這個元素。其中轉換函式被稱為雜湊函式。

除留餘數法:h(key)=key%mod;

除留餘數法可能會有hash值相同的,所以又用到了以下辦法:

線性勘查法:若占用,就檢查h(key)+1是否占用,如果沒被占用,就使用這個位置。否則繼續。若超過表長,就回到表首繼續。

平方勘查法:

鏈位址法(拉鍊法):把h(key)相同的key連成一條單鏈表。(map)

4.2.2字串hash初始

若為座標轉化為整數,h(p)=x*range+y;

字串轉整數:

int hashfunc(char s,int len)

return id;

}

4.3遞迴

4.3.1分治

全稱「分而治之」,分治法將原問題劃分為若干個規模較小且結構與原問題相同或類似的子問題,然後分別解決這些子問題,最後合併子問題的解。解決辦法:

(1)分解成若干個子問題

(2)解決。遞迴解決若干個子問題(當然也可以非遞迴)

(3)合併。將子問題的解合併

4.3.2遞迴

遞迴就是反覆呼叫自身函式

兩個重要的概念:

(1)遞迴邊界

(2)遞迴式(或稱遞迴呼叫)

初學者可畫出遞迴圖,將問題放在平面上

暴力法:一般不使用演算法優化、直接樸素演算法解決問題。

回溯法:當某些事實導致已經不需要遞迴子問題時,就可直接返回上一層。

4.4貪心

4.4.1簡單貪心:貪心是求解一類最優化問題的方法。他總是考慮當下最優策略,來達到全域性的結果達到最優的狀態。

4.4.2區間貪心:

區間不相交:總是先選右端最小的區間

4.5二分

4.5.1二分查詢

#includeint binarysearch(int a,int left,int right,int x)

else

}return -1;

}int main ();

printf("%d %d\n",binarysearch(a,0,n-1,6),binarysearch(a,0,n-1,9));

return 0;

}

求出序列中第乙個大於等於x元素的l位置

int binarysearch(int a,int left,int right,int x)

else

}return left;

}

求出第乙個大於x的元素的位置r

int binarysearch(int a,int left,int right,int x)

else

}return left;

}

4.5.2 二分法拓展

(1)計算根號2的近似值

(2)裝水問題

(3)木棒切割問題

4.5.3快速冪

求a的b次方

(1)若b為奇數時,a的b次方=aa的b-1次方

(2)若b為偶數時,a的b次方=a的b/2次方a的b/2次方

這顯然是遞迴的思想

求出a的b次方%m

typedef long long ll;

ll binarypow(ll a,ll b,ll m)

}

if(b%2==1)可換成if(b&1)

還要注意不能寫成binary(a,b/2,m)*binary(a,b/2,m)

快速冪的迭**法:

typedef long long ll;

ll binarypow(ll a,ll b,ll m)

a=a*a%m;

b>>=1;

} return ans;

}

效率差不多

4.6 two pointers

演算法程式設計很重要的思想

例:給定乙個遞增的正整數序列和乙個正整數m,求序列中的兩個不同位置的數a和b,使他們的和恰好為m。

while(im)

j--;

else

i++;

}

序列合併問題:

int merge(int a,int b,int c,int n,int m)
隨機快排

int randpartition(int a,int left,int right){

int p=(round(1.0*rand()/rand_max*(right-left)+left); //rand_max是stdlib中的乙個常數

swap(a[p],a[left]);

int temp=a[left];

while(lefttemp)right--;

a[left]=a[right];

while(left4.7 其他高效技巧與演算法

4.7.1打表

打表是一種典型的空間換時間的技巧,一般指的是將所有可能需要的用到的結果事先計算出來,這樣後面就可直接查表獲得。

常見的幾種打表:

(1)在程式中一次性的計算出所有需要得到的結果,之後的查詢直接取這些結果。(如fibonacci數預先算出並儲存到陣列中)

(2)在程式b中分一次或多次計算出所需要的結果,手工把結果寫在程式a中,然後在程式a中就可以使用這些結果。

(3)對一些感覺不會做的題目,先用暴力程式計算小範圍資料的結果,然後找規律,尋找蛛絲馬跡。

4.7.2活用遞推

有很多問題需要仔細考慮過程中是否存在遞推關係。

4.7.3 隨機選擇演算法

原理類似於隨機快排

演算法導論 第4章

這一章,就乙個主題,什麼是遞迴式?如何求解遞迴式?遞迴式,就是乙個函式,自己呼叫自己,但是有乙個最基本的情況,這種情況下,它就會自動返回跳出遞迴。用什麼方法?3種方法 1.代換法 2.遞迴樹方法 3.主方法 關於代換法 乙個字,猜,也就是你會蒙?怎麼蒙?需要你的經驗。也就是說,有經驗的人,一看就知道...

演算法第4章實踐報告

實踐題目 程式儲存問題 問題描述 設有n 個程式要存放在長度為l的磁帶上。程式i存放在磁帶上的長度是 li,1 i n。程式儲存問題要求確定這n 個程式在磁帶上的乙個儲存方案,使得能夠在磁帶上儲存盡可能多的程式。對於給定的n個程式存放在磁帶上的長度,計算磁帶上最多可以儲存的程式數。第一行是2 個正整...

第11章 泛型演算法 4

11.2.3 對容器元素重新排序的演算法 stdafx.h include using namespace std bool isshorter const string s1,const string s2 bool gt6 const string s stdafx.cpp include st...