20182304 《數據結構與面向對象程序設計》第八週學習總結
教材學習內容總結
- 查找:在某個項目組中尋找某一指定元素目標或肯定某一指定元素目標不在項目組中
- 線性查找
- 從頭開始依次比較每個值直至結尾,若找到指定元素返回索引值,不然返回false
- 線性查找的平均時間複雜度爲O(n)
- 二分查找
- 在一個已排序的組中,從列表的中間開始查找,若是中間元素不是要找的指定元素,則削減一半查找範圍,從剩餘一半的查找範圍中繼續以與以前相同的方式進行查找,屢次循環直至找到目標元素或肯定目標元素不在查找範圍中
- 特色:二分查找要求所查找的組必須是有序的。每次比較都會減小一半的查找元素,在元素較多時,查找效率相對較高
- 二分查找的平均時間複雜度爲O(log2n)
- 咱們課上另外學了三種查找方法,哈希線性查找、哈希鏈表查找、二叉樹查找,這幾個查找方法效率相對更高,可是算法實現比較複雜
- 二叉樹查找就是利用鏈表造成一個二叉樹,比父節點大的在右邊,比父節點小的在左邊,查找時順着二叉樹向下查找
- 哈希線性查找:線性探測再散列,若關鍵字對應地址非空,向後移位直到找到空地址存入,查找步驟與之相同
- 哈希鏈表查找:將存儲空間定義爲鏈表數組,每個存儲空間都表明一個鏈表的表頭,若出現衝突,直接延長鏈表的長度,查找順序與存入順序相同.用二維數組也能夠實現該算法
- 排序:排序是按某種標準將一列數據項按肯定的次序重排的過程
- 算法穩定性:相同元素排序後前後次序是否發生變化
- ASL(平均查找性能分析):查找全部元素須要進行的比較次數之和/元素總個數
- 選擇排序
- 原理:經過反覆將某一特定值放到它在列表中的最終已排序位置來實現排序
- 冒泡排序:
- 原理:經過反覆比較相鄰元素的大小並在必要時進行互換,最終實現排序
- 插入排序:
- 原理:重複地將一個具體的值插入到表中已有序的子序列中
- 選擇排序、插入排序、冒泡排序都有着相近的效率,時間複雜度皆爲O(n^2)
- 快速排序:
- 王老師講解的時候將快速排序比喻爲確立一箇中軸線(一個元素),進行分區,將其餘元素按照與這個元素比較的結果放在不一樣的兩個分區,當指針相遇時,一輪排序結束,把這個元素放回去,進行下一輪排序
- 快速排序每次要將列表分紅兩個分區,所以平均要進行log2n次分區,而每次分區後要進行n次比較操做,所以平均時間複雜度爲O(nlogn)
- 快速排序時遇到相同元素時可能須要進行交換,相同元素次序改變了,於是致使不穩定,因此快速排序並非一個穩定的算法。
- 歸併排序:
- 經過將列表進行遞歸式分區直至最後每一個列表中都只剩餘一個元素後,將全部列表從新按順序重組完成排序。
- 歸併排序的平均時間複雜度爲O(nlogn)
教材學習中的問題和解決過程
- 問題1:書上查找程序類的static修飾是什麼,有什麼意義
public static boolean binarySearch2(Comparable[] data, int min, int max, int target)
{
boolean found = false;
int mpoint = (min + max) / 2;
if (data[mpoint].compareTo(target) == 0)
found = true;
else if (data[mpoint].compareTo(target) > 0) {
if (min < mpoint)
found = binarySearch2(data, min, mpoint - 1, target);
} else if (max > mpoint)
found = binarySearch2(data, mpoint + 1, max, target);
return found;
}
- 問題1解決方案:static爲靜態方法:使用時不須要實例化該類的一個對象,能夠直接經過類名來激活的方法。能夠經過在方法聲明中使用static修飾符將方法聲明爲靜態的。
- 問題2:這幾種排序算法時間複雜度和查找效率有什麼特色?
- 問題2解決方案:選擇排序、插入排序、冒泡排序都有着相近的效率,時間複雜度皆爲O(n^2),可是插入排序的最優情形依賴於初始數據的狀況,能夠爲O(n)。經過對比能夠發現,快速排序比大部分排序算法都要快。儘管在某些特殊的狀況下存在比快速排序快的算法,可是通常狀況下,快速排序速度相對是更快的(平均時間複雜度爲O(nlogn))。可是快速排序存在穩定性較差的問題,若是須要一個穩定性較好且排序較快的排序算法,能夠選擇使用歸併排序,可是歸併排序一樣存在缺點,由於它須要一個額外的數組,所以對內存空間有必定的要求。
代碼調試中的問題和解決過程
public static String SelectionSort(int List[]) {
int ab;
long startTime = System.nanoTime();
for (int i = 0; i < List.length - 1; i++) {
int temp = i;
for (int j = i + 1; j < List.length; j++) {
if (List[i] > List[j]) {
if (List[temp] > List[j]) {
temp = j;
}
countC++;
}
countC++;
}
ab = List[i];
List[i] = List[temp];
List[temp] = ab;
}
long endTime = System.nanoTime();
TimeS = endTime - startTime;
- 問題1解決方案:以選擇排序法舉例,咱們能夠經過
System.nanoTime()
,獲取當前系統時間差進行計算。
- 問題2:使用遞歸二分查找,老是出現疑似地址越位
//遞歸
public static boolean binarySearch2(Comparable[] data, int min, int max, int target)
{
boolean found = false;
int mpoint = (min + max) / 2;
if (data[mpoint].compareTo(target) == 0)
found = true;
else if (data[mpoint].compareTo(target) > 0) {
if (min < mpoint)
found = binarySearch2(data, min, mpoint - 1, target);
} else if (max > mpoint)
found = binarySearch2(data, mpoint + 1, max, target);
return found;
}
- 問題2解決方案:通過單步調試,發現程序遞歸條件出現問題,每次遞歸傳輸的值不變,致使程序遞歸出現死循環。修正每次遞歸的值後解決問題
(html
)java
)git
上週考試錯題總結
- 無
結對及互評
點評模板:
- 博客中值得學習的或問題:
- 代碼中值得學習的或問題:
基於評分標準,我給本博客打分:15分。算法
參考示例編程
點評過的同窗博客和代碼
- 本週結對學習狀況
- 20182302
- 結對學習內容
- 學習哈希兩種查找的具體代碼實現
- 概括不一樣查找方式的時間複雜度
- 上週博客互評狀況
其餘(感悟、思考等,可選)
- 有些算法理解起來簡單,實踐起來難度確實很大的。鏈表和數組使用時都須要特殊注意,不然很容易就會發生地址越界。
學習進度條
目標 |
5000行 |
30篇 |
400小時 |
|
第五週 |
1600/2900 |
2/11 |
20/110 |
|
第六週 |
981 /3881 |
2/12 |
25/135 |
|
第七週 |
1700/5518 |
3/15 |
45/180 |
|
第八週 |
700/6200 |
2/17 |
20/200 |
|
嘗試一下記錄「計劃學習時間」和「實際學習時間」,到期末看看能不能改進本身的計劃能力。這個工做學習中很重要,也頗有用。
耗時估計的公式:Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。數組
參考:軟件工程軟件的估計爲何這麼難,軟件工程 估計方法數據結構
計劃學習時間:20小時性能
實際學習時間:20小時學習
改進狀況:設計
(有空多看看現代軟件工程 課件
軟件工程師能力自我評價表)
參考資料