演算法導論 第二章作業

2021-07-01 18:54:06 字數 3697 閱讀 8779

//作業2. 1-2

template

void insert(t* a, int  n)

a[i + 1] = key;}}

//2. 1-3

template

void find(t* a, int  n, t v)

}if (i == -1)

v = nil;}/*

迴圈不變式:

初始化:i == -1,v還沒和任何a陣列中的元素比較,所以是-1,它為真。

保持:如果j迴圈到k時為真,那麼說明i還是-1),

j到了k+1,如果a[k + 1] != v, 那麼i還是nil。

終止:a[j] == v,此時終止,可以得到i就等於j 得知此時的a[i]是v

或者i是-1,此時賦值nil給v */

//2. 1-4

/*輸入:兩個序列a,b,每個序列為n位2進製整數

輸出:乙個存放前面兩個序列相加結果的n+1位2進製整數陣列c */

void add2(int* a, int* b, int *c, int n)

c[0] = temp;

}//2. 2-1

//o-(n^3)

//2. 2-2

template

void select(t* a, int  n)

}t temp = a[i];

a[i] = a[pos];

a[pos] = temp;}}

/*迴圈不變式:

初始化:i == 0 後面還有n個數需要排序;

保持:i == k,k前面的已經排序好了,i == k+1時,第k+1個數會找到後面的最小的數,

這個數隻可能大於等於k,因為k找到的是當時k後面的最小的那個數。迴圈成立。

終止:i==n,n個數全部排序完成。

只需要排序n-1個數的原因,前面n-1個數都是比n大的,n就是最大的,就不需要排序了。

最好的情況==最差的情況:o-(n^2) */

//2. 2-3

/*平均需要檢查的元素長度為:(n + 1)/2

最壞情況:n

平均情況==最壞情況:o-(n)

證明:查詢的元素等可能,每個元素被找的概率為1/n。

找的長度len == (1/n * 1 + 1/n * 2... 1/n * n) == (1 + 2 + 3 +... + n)/n == (n + 1) / 2;

*///2. 2-4

//直接針對某一種情況來設計演算法解決問題就可以獲得良好的最好情況執行時間

//2. 3-2

template

void merge(t* a, int p, int q, int r)

else

++p;

}if (i == n1)

}else }

delete b;

}//2. 3-3

/*n == 2: t(n) == 2 == 2*1 == 2*lg(2)

n == k時成立:t(k) == k*lg(k)。 n == k * 2時:t(2*k) == 2*t(k) + 2*k == 2*k*lg(k) + 2*k

== 2k* (lg(k) + 1) == 2k * lg(2k); n==2*k時成立。由此得證。 */

//2. 3-4

//t(n)==

//2. 3-5

template

int binaryfind(t* a, int l, int r, const t& v)

else

return -1;

}//最壞情況就是一直查到1.

//t(n) ==

//通過遞迴樹得到執行最壞結果為o-(lg(n));

//2. 3-6

//並不能縮短,insertion-sort主要佔時間的不是查詢,而是插入時需要移動大量的元素。

//2. 3-7

//使用nlog(n)的排序演算法先排好序,然後從i=0和j=n開始相加,如果大於x就--j,繼續加,小於x就++i;

//如果最後i==j就返回false,否則返回i j 值。

//2-1

/*a:每個k大小的區間,最差情況下:k(k+1)/2,一共有n/k個區間,最後得到k(k+1)/2 * n/k

== n(k+1)/2 : o-(nk);

b:每一層的代價是n,一共有lg(n/k)+1層,向上合併就得到o-(nlg(n/k))

c: nk+nlg(n/k) <= nlg(n): k <=lg(n); k的最大值就是 lg(n);

d: 在插入排序比歸併排序快的情況下,取k的最大值。

*///2-2

/*a:必須證明a'是a的一種排序。

b:j位置的元素永遠是j到a.length區間中最小的。

初始化:j == a.length。只有乙個元素,所以符合最小的條件。

保持: j不斷減小,因為a[j]是j到a.length區間中最小的,比較a[j-1]和a[j],如果a[j]小於a[j-1]就

交換兩個位置的值,j變成了原先的j-1,j還是最小的。

終止:j == i ,結果使得i這個位置的元素成為i到a.length區間最小的元素。

c:區間1到i 一直都是排序好的狀態

初始化:i=1,區間1到1只有乙個元素,已經排序好。

保持:1到i-1已經排序好了,i通過第二個for迴圈,使得i成為了i到a.length區間最小的元素,

加上前面排序好的1到i-1,區間1到i呈現已經排序好的狀態。

終止:i等於a.length-1,得到結果1到a.length-1是已經排序好的狀態,而且i-1 小於i(第二個迴圈的結果),

所以1到a.length都已經排好序了。

d:最壞情況的執行時間:o-(n(n-1)/2),效能和插入排序一樣,除了最差情況,插入排序要比氣泡排序好,因為氣泡排序的

執行時間總是o-(n^2)的。 */

//2-3

// a:o-(n+1)加法 + o-(n+1)乘法

int power(int x, int n)

void sum(int* a, int n,int x)

/*c:初始化:i == n ,y == k從0到-1,也就是沒有區間,也就是y==0;

保持:每次i+1都有y== a[n]*(x^(n-i-2)) +a[n-i-3]*(x^2)...+a[i+2]*(x^(0)),輪到i時y==a[i+1] + y*x==

a[n]*(x^(n-i-1))+...+a[i+1],符合式子。

終止:i==-1,y==a[n]*(x^n)+...+a[0],就是式子。

d:y==式子==p(x)就是正確答案。。。

*///2-4

/*a:(2,1)(3,1)(8,1)(6,1)(8,6)

b:,有n(n-1)/2對逆序對。

c:逆序對越少,插入排序用時越少。

逆序對增加的情況就是小的數被換到序列後面了,每換乙個數到後面,這個數在排序的時候要回到正確位置就需要

比較 換的距離次。

d: */

int invertion_aux(int* a, int l, int m, int r)

else

++l;

}if (i == n1)

}else }

delete b;

return sum;

}int invertion(int* a, int l, int r)

return0;}

演算法導論第二章

插入排序原始碼 1 include 2 include 3 4using namespace std 56 void insert sort inta 7 17 a i 1 key 18 19 2021 intmain 22view code 逆序輸出 1 include 2 include 3 4...

演算法導論第二章筆記

這一章首先以乙個插入排序演算法開始,以此為切入點分析演算法。書上以偽 來介紹演算法,但是在這裡我基本上會用c語言實現一遍,並用自己的語言複述一遍演算法的思想。首先附上插入排序的具體實現。void insert sort eletype arr int start int end arr j 1 te...

演算法第二章作業

分治法 就是把乙個複雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題 直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。分治法乙個主要思想是遞迴,遞迴的時間複雜度低。演算法的複雜度低,提高了演算法的質量。分治法在每一層遞迴上都有三個步驟 分解 將原問題分解為若干個...