(1)查找3是這樣一個過程,即在某個項目組中尋找某一指定目標元素,或者肯定該組中並不存在該目標元素。對其進行查找的項目組有時也稱爲查找組。php
(2)查找方式的分類:線性查找,二分查找。html
(3)查找所要完成的目標:儘量高效的完成查找,從算法分析的角度而言,咱們但願最小化比較操做的次數,一般,查找池裏項目數目越多,爲了尋找該目標而作出的比較操做次數就越多,所以該查找池中項目的樹目定義了該問題的大小。java
(1)若是該查找池組織成了一個某類型的列表,那麼完成該查找的一個簡單方式就是從該列表頭開始一次比較每個值,直到找到該目標元素爲止。node
(2)具體的樣式圖:
git
(3)代碼實現:web
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; }
(1)前提:查找池中的項目組是已排序的。算法
(2)具體過程:二分查找是從排序列表的中間開始查找,而不是從一端或另外一端開始。若是沒有在那個中間元素找到目標元素則繼續查找。數組
(3)具體詳細的樣式圖:
網絡
(4)特色:二分查找將利用了查找池是已排序的這一事實;二分查找的每次比較都會刪除一半的可行候選項;結合了遞歸的思想。數據結構
(5)代碼實現:
public static <T extends Comparable<T>> boolean binarySearch(T[] data, int min, int max, T target) { boolean found = false; int midpoint = (min + max) / 2; // determine the midpoint if (data[midpoint].compareTo(target) == 0) found = true; else if (data[midpoint].compareTo(target) > 0) { if (min <= midpoint - 1) found = binarySearch(data, min, midpoint - 1, target); } else if (midpoint + 1 <= max) found = binarySearch(data, midpoint + 1, max, target); return found; }
(6)注:若是二分查找分爲元素爲奇數和偶數個兩種樣式,就具體的問題有具體的解決方式,若是線性表爲一個偶數個的有序列表的時候,所採用的中點能夠是中間兩個值的任意一個。
(1)對於線性查找而言,最好的情形是目標元素恰好是咱們所考察項目組中的第一個項目。
(2)線性查找算法具備線性時間複雜度O(n),由於是依次每回查找一個元素,因此複雜度是線性的——直接與待查找元素數目成比例。
(3)二分查找算法廣泛要快得多。最好的情形就是一次比較就找到了該目標——也就是說,目標元素恰好位於數組的中點。最壞的情形出如今元素不在該列表的時候,在這種情形下,在刪除全部數據以前,咱們不得不進行大約log2n次比較。所以找到位於該查找池中某一元素的預期情形是大約(log2n)/2次比較。
(4)二分查找的複雜度是對數級的,這使得它對於大型查找池很是有效率。
(1)排序是這樣一個過程,即基於某一標準,要麼以升序要麼以降序將某一組項目按照某個規定順序排列。
(2)基於效率排序算法分爲兩類:順序排序和對數排序。
(3)在順序排序裏,有三種排序方式,分別爲:選擇排序、插入排序以及冒泡排序。
(4)在對數排序中,有兩種排序方式:快速排序和歸併排序。
(1)選擇排序算法經過反覆地將某一特定值放到它在列表中的最終已排序位置,從而完成對某一列值的排序。
(2)算法實現原理圖
(1)插入排序算法經過反覆地將某一特定值插入到該列某個已排序的子集中來完成對列表值的排序。
(2)算法實現原理圖
(1)冒泡排序法是另外一種使用了兩個嵌套循環的順序排序算法,經過重複地比較相鄰元素且在必要時將它們互換,從而完成對某個列表的排序。
(2)算法實現原理圖
(1)快速排序算法經過將列表分區,而後對這兩個分區進行遞歸式排序,從而完成對整個列表的排序。
(2)算法實現原理圖
(1)歸併排序算法經過將列表遞歸式分爲兩半直至每一字列表都含有一個元素,而後將這些字列表歸併到一個排序順序中,從而完成對列表的排序。
(2)算法實現原理圖
(1)基數排序是基於隊列處理的。
問題1解決過程:包括在老師上課的時候也都講過,偶數個的話,中間兩位任意一個均可以,就這個任意一個均可以就讓我有點費解,在看了書中的解釋
在二分查找實現中,肯定中點索引的計算丟棄了任何分數部分,所以它選擇的是兩個中間值的第一個。
就這個解釋而言,並且當我僅僅看書看到這裏的時候,理解起來確定仍是不容易的,因此我繼續看了書後面的內容,在看到對數排序的歸併排序中,發現其實現的原理很是類似,其中在歸併排序的代碼實現中,個人問題在其中也有所體現:
int mid = (min + max) / 2;
while (first1 <= last1 && first2 <= last2) { if (data[first1].compareTo(data[first2]) < 0) { temp[index] = data[first1]; first1++; } else { temp[index] = data[first2]; first2++; } index++; }
從上述的代碼就能夠看出,代碼實現的過程其實就是分開比較,分類比較,先肯定一個數,比它的左邊和右邊。
問題2:在學習選擇排序法的過程當中,其中在那個Sorting
類中有swap
這個寫好的方法,其做用就是交換兩個數組位置的內容,可是在咱們以前學習單鏈表的時候,在交換節點的時候老是須要考慮各個方面的因素,那咱們能不能也寫這樣一個方法進行結點互換呢?
問題2解決過程:由於鏈表中每個結點都是連接起來的,假如盲目的斷掉某一個可能就會致使空指針的問題或者更嚴重就會致使後面全部數據的丟失,因此在以前學習的過程當中,在我學習的過程當中,都是用先賦值給一個臨時結點,而後把後面的結點插入到前面結點以前,再用後面結點鏈接到它後面的後面那個結點,這樣實現結點的交換,可是這僅僅只能實現於在相鄰的兩個結點,因此有沒有一種方法,咱們能夠實現相似於swap
的方法呢?因此我首先在網絡上尋找有沒有講解相似相關知識的博文以獲得靈感。
這是我所找到的一個博主本身畫的一張圖
其實回想一下以前本身寫過的一個程序中,彷彿本身好像也用到了相關的知識,由於我以爲交換無非就是首先須要找到要交換的元素,再計算它們之間須要進行尋找的次數,也就是它們之間的距離,經過這樣幾項元素,就能夠大體寫出僞代碼了。
個人僞代碼思路就是:(1)由於首先咱們須要定義三個形式參數(這裏我沒有考慮假如交換的元素在鏈表中出現了屢次,這個在接下來的時間裏我會再繼續解決的),三個形參分別爲list
node1
node2
,其中node1
node2
爲須要交換的兩個元素,首先要找到node1和node2,而後把node1插入到node2的後面,把node2插入到node1的前面,再刪除以前的node1和node2。
由於問題提出的時間很短,代碼實現正在初步造成中。
partition
方法,在這個方法中,它最終返回的是一個整型的right
,這個類的用處是什麼呢?問題3解決方法:首先,這個方法的兩個內層循環用於尋找位於錯誤分區的交換元素,第一個循環從左邊掃描右邊以尋找到大於分區元素的元素,第二個循環,從右邊掃描左邊以尋找到小於分區元素的元素,在尋找到以後,進行互換。
問題4:就上一個問題繼續,其中有這樣一句代碼int middle = (min + max) / 2;
,在上學期中,有學習過在計算機語言中,假如定義一個整型的變量,若是給它賦予一個double型的數字,好比小數,變量最終只取整形的部位,舉個例子相似於這樣
在這個方法中,假如是這個樣子,會不會對程序有影響?
問題4解決方法:這個程序中,有考慮到如此的狀況,因此並不會受影響。
問題1:在作pp9.2的做業中,發現本身所編寫的外循環老是走一遍就停下來了,以下:
問題1解決方法:
一開始覺得本身是否是哪裏編寫錯了,就大改了一番,本身從新多寫了一個循環,仿照冒泡排序的代碼寫了一個,錯的更厲害了,最後發現本身的錯因竟是變量的名稱沒有修改對。
修改爲以下就能夠了。
問題2:在寫pp9.3的時候,再計算時間的時候,發現本身輸出的一直是0毫秒?以下圖
問題2解決方法:由於詢問了郭愷同窗,在今天也就是十月十四日的時候,郭凱同窗說他也遇到了一樣的問題,多是由於毫秒太大使得只顯示了實數位,將其改成納秒的時候,問題也就隨之解決了
也就是說,當咱們計算毫秒的時候所用的語句是下面代碼:
long startTime = System.currentTimeMillis(); //獲取開始時間 //doSomething(); 測試的代碼段 long endTime = System.currentTimeMillis(); //獲取結束時間 System.out.println("程序運行時間:" + (endTime - startTime) + "ms"); //輸出程序運行時間
計算納秒的時候用的計算時間爲:
long startTime=System.nanoTime(); //獲取開始時間 doSomeThing(); //測試的代碼段 long endTime=System.nanoTime(); //獲取結束時間 System.out.println("程序運行時間: "+(endTime-startTime)+"ns");
上週無錯題,太秀了!
代碼調試中的問題和解決過程, 一個問題加1分
這週上了三節Java課,也發現了本身在學習當中的一些問題,但願本身能夠把握住如今能夠學習的機會,不要在之後後悔莫及的時候反思本身沒有在正確的時間作正確的事情。加油!
不忘初心,方得始終!
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | |
---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 |
第一週 | 0/0 | 1/1 | 6/6 |
第二週 | 1313/1313 | 1/2 | 20/26 |
第三週 | 901/2214 | 1/3 | 20/46 |
第四周 | 3635/5849 | 2/4 | 20/66 |
第五週 | 1525/7374 | 1/5 | 20/86 |
藍墨雲班課
Java程序設計
Java計算程序代碼執行時間的方法小結
Java實現-兩兩交換鏈表中的節點
Java數據結構和算法(九)——高級排序
數據結構常見的八大排序算法