課程:《程序設計與數據結構》
班級: 1723
姓名: 王禹涵
學號:20172323
實驗教師:王志強
實驗日期:2018年11月20日
必修/選修: 必修html
查找與排序-1
定義一個Searching和Sorting類,並在類中實現linearSearch(教材P162 ),SelectionSort方法(P169),最後完成測試。
要求很多於10個測試用例,提交測試用例設計狀況(正常,異常,邊界,正序,逆序),用例數據中要包含本身學號的後四位
提交運行結果圖。java
查找與排序-2
重構你的代碼
把Sorting.java Searching.java放入 cn.edu.besti.cs1723.(姓名首字母+四位學號) 包中(例如:cn.edu.besti.cs1723.G2301)
把測試代碼放test包中
從新編譯,運行代碼,提交編譯,運行的截圖(IDEA,命令行兩種)git
查找與排序-3
參考http://www.cnblogs.com/maybe2030/p/4715035.html 在Searching中補充查找算法並測試
提交運行結果截圖算法
查找與排序-4
補充實現課上講過的排序方法:希爾排序,堆排序,二叉樹排序等(至少3個)
測試實現的算法(正常,異常,邊界)
提交運行結果截圖數組
查找與排序-5
編寫Android程序對各類查找與排序算法進行測試
提交運行結果截圖
推送代碼到碼雲數據結構
測試的代碼(參照上學期的資源)性能
public void testSearch1() { assertEquals(true, SearchingSorting.linearSearch(search1, 0, 6, 2323)); }
左下角反映了測試經過與否單元測試
第二部分看似簡單,其實花費了我很多時間。
首先把代碼類放在一個新的包內,另外一個測試類其實應該放在專門的test包內,而不該該隨便就在src下建一個test包,這點在單元測試的講解中有提到過,即學習
test目錄中放的也是Java代碼,但IDEA不知道test中放的是源代碼。在命令行中咱們知道要設置
SOURCEPATH
環境變量,在IDEA中咱們右鍵單擊test目錄,在彈出的菜單中選擇Mark Directory as->Test Sources Root
就能夠了測試
另外一個在命令行上測試,我重寫了測試方法,沒有再用JUnit測試,由於屢次使用cmd運行都提示找不到或沒法加載主類,重寫以後,找到編譯文件所在的位置java SSTest1
。特別奇怪的一個地方是,我只能在編譯文件所在的包外運行該代碼,若是是在包內又會報錯。
須要理解幾種查找算法,這部分比較困難,可是須要本身作的地方不難,由於代碼基本都給了出來。重點須要新學的是斐波拉契查找和插值查找
int InsertionSearch(int a[], int value, int low, int high) { int mid = low+(value-a[low])/(a[high]-a[low])*(high-low); if(a[mid]==value) return mid; if(a[mid]>value) return InsertionSearch(a, value, low, mid-1); if(a[mid]<value) return InsertionSearch(a, value, mid+1, high); }
其餘地方都和折半查找相似,主要是定位查找點的方法int mid = low+(value-a[low])/(a[high]-a[low])*(high-low);
很差理解
value = 2; low = 0; high = 19; mid = 1;
此時a[mid] = a[1] = 2,就查找到了須要的元素。
我想這個算法的核心在於(high - low)
反映了要查找的數組的長度,(value-a[low])/(a[high]-a[low])
定位了查找點大體在數組幾分之幾的位置上(由於數組內的元素分佈是比較均勻的)。
代碼分析
寫出這代碼的核心思想是什麼我還沒法理解,只能跟着代碼走一遍。首先他須要將數組內的元素複製到一個斐波那契數長度的數組中,多出來的位置所有填充原數組的最後一位。而後經過變換mid的值不斷縮小查找的範圍,若是查找值小於temp[mid]的值,說明待查找的元素在[low,mid-1]範圍內,反之說明待查找的元素在[mid+1,high]範圍內。這裏恰好前面一部分與後面一部分的比值約爲0.618,將數組擴展到F[k]-1長度也是出於此考慮,以後相似於二分查找不斷縮小範圍逼近查找值。但最後的值有可能在擴展的數組中,須要返回n-1(爲何最多隻會找到擴展數組的第一個位置尚未弄明白)
題目給出的三種排序算法,堆排序在以前的項目中已經有了實現的方法,二叉樹排序也不困難,只須要將數組內的元素依次序添加進二叉樹中,而後按照中序輸出的方法也能達到排序的效果。主要是希爾排序沒有遇到過
代碼實現
public static void sort(Integer[] data){ if(data == null || data.length <= 1){ return; } //增量 int incrementNum = data.length/2; while(incrementNum >=1){ for(int i=0;i<data.length;i++){ //進行插入排序 for(int j=i;j<data.length-incrementNum;j=j+incrementNum){ if(data[j]>data[j+incrementNum]){ int temple = data[j]; data[j] = data[j+incrementNum]; data[j+incrementNum] = temple; } } } //設置新的增量 incrementNum = incrementNum / 2; } String str = ""; for (int n = 0; n < data.length; n++){ str += data[n] + " "; } System.out.println(str); }
從算法的實現能夠看出,希爾排序是有些相似與間隔排序的,它經過設置增量,將相同間隔的元素放在一堆而後排好序,再將增量擴大,直至全部元素都在一個數組中且進行排序,這時即排序完成
這部分還算比較簡單,就把以前的代碼移動到AS裏,不過同時還須要移動一大堆的相關文件過去。我比較省事地只添加了兩個按鈕,一鍵就調用全部的排序或者查找方法。而後textview.setView()中輸出一大堆返回信息,如圖
問題1:進行插值查找時,查找一個數組中不存在的數,出現以下的錯誤
問題1解決方案:debug以後發如今進行分區域的時候,會出現low>high的狀況,而程序沒有能處理這種狀況的能力。參照斐波那契查找代碼中對於出現low>high狀況的處理,在外部加上一個while循環,當出現low>high時,直接return -1
這樣一來錯誤狀況就處理掉了。
問題2:int型與Interger型的區別
問題2解決方案:之前歷來沒有考慮到過這個問題(多是沒有認真學習的緣由),總之到此次實驗時才發覺他倆好像是有點小小的區別,由於第一部分的實驗新創的數組都是Comparable型的,但後來由於實驗須要有一些方法有須要轉換成int型,因此數值的比較方法也須要大改。按理說data[min].compareTo(data[j]) > 0
就須要改爲data[min] > data[j]
可是改爲Interger型這些都不須要改變。因此查了一下他倆的一些區別
Integer 類和 int 的區別
①、Integer 是 int 包裝類,int 是八大基本數據類型之一(byte,char,short,int,long,float,double,boolean)
②、Integer 是類,默認值爲null,int是基本數據類型,默認值爲0;
③、Integer 表示的是對象,用一個引用指向這個對象,而int是基本數據類型,直接存儲數值。
Interger型至關因而一個包裝盒,裏面包含的是int型的對象,因此可使用CompareTo的方法。
此次實驗相對來講理論的學習很重要,要優於本身動手寫代碼。經過此次實驗,我對幾種查找和排序算法都有了更深入的瞭解,同時還了解了一些沒有接觸過的查找算法。比較意外的一個收穫是,我對一些數據類型的瞭解也更加深入了
《Java程序設計與數據結構教程(第二版)》