查找是在某個項目組中尋找到某一指定目標元素,或者肯定該指定目標並不存在。html
高效的查找會使該過程所作的比較操做次數最小化。java
靜態方法(類方法)能夠經過類名調用,不能引用實例變量,能夠引用靜態變量。Java程序的main方法必須用static修飾符(聲明爲靜態)來修飾,解釋器不用實例化含有main的類的對象,就能夠調用main方法。git
泛型方法建立一個引用泛型的方法,只需在方法頭的返回類型前插入一個泛型聲明便可。含有返回類型和參數類型的方法,就可使用泛型參數。泛型聲明必須位於返回類型以前,這樣泛型才能夠做爲返回類型的一部分。算法
線性查找時間複雜度O(n)從列表頭開始依次比較每個值,直至找到該目標,結果是要麼找到目標,要麼到達列表尾並得出該組中不存在該目標的結論。編程
二分查找時間複雜度O(logn)從排序列表的中間開始查找,若是中間元素不是目標元素,則繼續取半搜索。在每一次比較操做後,將排除剩餘待搜索的一半數據。數組
選擇排序算法經過反覆的將某一特定值放到它在列表中的最終已排序位置,從而完成對某一列值的排序。安全
插入排序算法經過反覆地將某一特定值插入到該列表某個已排序的字集中來完成對列表值的排序。數據結構
冒泡排序算法經過重複地比較相鄰元素且在必要時(彼此不符順序)將它們互換,從而完成対值的排序。
性能
快速排序經過使用任意選定的分區元素將該列表分區,而後對分區元素的任一邊的子列表進行遞歸排序。
學習
歸併排序算法是經過將列表遞歸式分紅兩半直至每一子列表都只含有一個元素,而後將這些子列表歸併到一個排序順序中,從而完成對列表的排序。
基數排序是基於隊列處理的,經過排序關鍵字的部份,將要排序的元素分配至某些隊列中,經過出隊入隊以達到排序的做用。
追問(2.) 泛型的上下限有什麼做用?
- 和泛型的下限表示方法相似,<? extends T>表示的是泛型的上限。super表示包括T在內的任何T的父類,extends表示包括T在內的任何T的子類。 「有界類型」的泛型避免了強制類型轉換的同時保留了安全性能,使得轉換有了必定的限制。在必定程度上提升了代碼的靈活性,隨便用相關的類。
追問(3.)<T extends Comparable<T>>
和 <T extends Comparable<? super T>>或<T extends Comparable<? extends T>>
有什麼不一樣?
- 少了?和super,二者的意義會有很大的變化,前者表示的是類型T必須實現Comparable接口,而且這個接口的類型是T。只有實現接口的T的實例纔會相互比較,然後者是表示類型T必須實現Comparable接口,而且接口的類型是T或者是T的任一父類或子類。
建立具備繼承關係的類,一個是Anima類,另外一個是Cat類。可是在Animal中實現了Comparable
sort1(Animal)
結果是正常按照年齡進行排序,sort1(cat)
結果會報錯。僅由於Animal實現了接口Comparable
sort2(Animal)
和sort2(Cat)
的結果均按照年齡進行排序。(比較的參數類型不一樣在後者的狀況下也能夠進行比較,大大的提升了代碼的靈活性與自由度。)追問(4.)若是在子類中實現Comparable接口的話是否能夠改善sort1比較的差別?
- 若是父類實現了接口,那麼子類就繼承了相關的接口不能從新實現接口;相反只能重寫父類CompareTo的方法來達到進行子類的比較。
問題2解決方案:泛型方法的定義和普通方法定義不一樣的地方在於須要在修飾符和返回類型之間加一個泛型類型參數的聲明,代表在這個方法做用域中誰纔是泛型類型參數,規定了泛型的範圍,從這一點能夠看出罰你性能高的優點就是提升了代碼的靈活性。
- 泛型類,是在實例化類的時候指明泛型的具體類型;泛型方法,是在調用方法的時候指明泛型的具體類型。
問題3解決方案:
public static <T> boolean linearSearch(T[] data, int min, int max, T target) { int index = min; boolean found = false; while (!found && index <= max) { found = data[index].equals(target); index++; } return found; }
針對這串代碼個人第一想法就是用二分查找替代這種線性查找,可是不符合老師的要求。整串代碼可以優化的部分就是while循環裏面的!found
、index <= max
、found = data[index].equals(target)
、index++
四部分,我以爲能夠把!found
和found = data[index].equals(target)
進行合併,這樣能夠i吉安少一條語句的運行,但實質上並無進行變化一樣的判斷與測試看似兩條語句變一條語句,其程度遍複雜了,要執行一次比較,在進行一次布爾型的判斷。而老師給出的答案是設立一個哨兵,也就是數組索引值爲0的位置加入目標元素,若是在未遍歷到頭就結束的話就能判斷數組內含有該元素,並且找到該元素;若是到哨兵的位置找到的話,那就說明沒有該元素,也就是不用判斷index <= max
示例答案中並無判斷是否到了尾部的相關代碼。(示例代碼並沒與在複雜度上解決該問題,可是在性能上有所提升。針對這一結果也是醉了)
data[0] = target; for (index = data.length-1; !data[indax].equals(target);--index){ } return index == 0? false:true;
在第一次改寫的時候沒有動內外循環,只是把數組交換的索引值改了,結果就報數組越界異常(ArrayIndexOutOfBoundsException)。實際上是由於在增長間隔的時候外循環仍是在一個個的遍歷,致使數組的越界。
第二次稀裏糊塗的改了個內層循環的條件結果是能夠進行排序,可是末尾的兩個元素或是三個元素(間隔次數不一樣)始終不排序,考慮到多是間隔不爲1的時候尾部兩個元素或是三個元素沒有排序,在達到間隔爲1的時候有直接跳出沒排致使的(感受本身第二次修改的時候好迷)。
第三次進行了大修改,由於考慮到間隔次數是在遞減正好替換以數組長度爲外層循環條件,再在內外層循環之間進行一個遍歷的循環使交換的時候能多進行幾回,而內層循環在經歷過第二次排序後發如今間隔次數未達到1的狀況下數組元素始終有小於間隔次數的元素沒有進行排列,而此刻的索引值最大就是數組長度減去間隔次數。
我的以爲在進行間隔數減少的過程當中包含了冒泡排序的過程,而僅使用冒泡排序就能夠達到排序的目的,間隔排序效率並不高,實現的過程還特別麻煩,一堆循環的疊加,以爲這種排序方法除非是進行間隔幾個元素的狀況下進行排列的類型,其他狀況下好像用處並不大。
問題2解決方案:時間代碼在放假的時候就看了一部分,接觸的相關類都是像Calendar計算多少天、多少年的類以及SimpleDateFormat進行格式化輸出時間的類和LocalDate記錄日期的類。而System.nanoTime()在上網查找以後發現是以long形式輸出系統計時器的當前值,而後兩個值進行相減就能夠表示出運行時間。在類的開頭可結尾各方一個進行記錄在相減就能夠了。
time++
如何在遞歸方法中實現?問題3解決方案:對於含有遞歸方法的相關代碼,若是把記錄次數的代碼放的位置稍有不對就會形成不斷的輸出或是一直歸零,針對選擇排序、插入排序和冒泡排序徹底在方法題中添加些代碼,在循環體中進行那個自增計數就能夠了。而快速排序和歸併排序就不行,一直在不斷輸出,經過借鑑侯澤洋同窗的博客,發現能夠建立全局變量來實現就輸出一次,在遞歸方法中進行自增,在調用遞歸的方法中進行輸出;或是從新設定一個方法,使以前的遞歸方法被調用,這樣再進行以前的實現步驟就行。
本週結對學習狀況
20172314方藝雯
20172323王禹涵
結對學習內容:查找和排序
第六章的內容是用數組和鏈表表示列表的,在必定還曾獨上列表和隊列、棧都有必定程度上的類似,部分代碼徹底能夠以前編寫的,惟一以爲比較噁心的就是在添加的過程當中就直接被排序。經過這幾章學的內容,對鏈表和數組有了更多的認識,應用起來也比較順手。勤能補拙,多練習多嘗試總沒有錯的。
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 | |
第一週 | 0/0 | 1/1 | 15/15 | |
第二週 | 703/703 | 1/2 | 20/35 | |
第三週 | 762/1465 | 1/3 | 20/55 | |
第四周 | 2073/3538 | 1/4 | 40/95 | |
第五週 | 981/4519 | 2/6 | 40/135 |