20172310《程序設計與數據結構》(下)實驗三:查找與排序實驗報告

20172310《程序設計與數據結構》(下)實驗三:查找與排序實驗報告

報告封面

  • 課程:《軟件結構與數據結構》
  • 班級: 1723
  • 姓名: 仇夏
  • 學號:20172310
  • 實驗教師:王志強老師
  • 實驗日期:2018年11月19日-2018年11月24日
  • 必修選修: 必修

實驗三-查找與排序-1

實驗要求內容

定義一個Searching和Sorting類,並在類中實現linearSearch(教材P162 ),SelectionSort方法(P169),最後完成測試。
要求很多於10個測試用例,提交測試用例設計狀況(正常,異常,邊界,正序,逆序),用例數據中要包含本身學號的後四位
提交運行結果圖。html

實驗過程及結果

  • 此次的測試讓咱們用的Junit編寫的,其實這方面的知識已經忘得差很少了,因而又翻出老師給的博客從新學習了一遍。
    在查找中出現的異常我寫了兩種,一種是不相匹配,得出的結果不正確,第二種是越界問題,輸入的索引值已經超出給定數組的容量;
    在排序中出現的錯誤有不相匹配,以前我其實看着兩個基本同樣的數組非常疑惑,爲何這是false,

通過仔細地觀察,最後發現是由於末尾最後少了一個空格(掩面)。另外一種錯誤是數組的類型是Comparable型的,進行不了排序。
java



實驗三-查找與排序-2

實驗要求內容

重構你的代碼
把Sorting.java Searching.java放入 cn.edu.besti.cs1723.(姓名首字母+四位學號) 包中(例如:cn.edu.besti.cs1723.G2301)
把測試代碼放test包中
從新編譯,運行代碼,提交編譯,運行的截圖(IDEA,命令行兩種)git

實驗過程及結果

  • 命令行怎麼寫來着?看來本身的知識記得不牢呀。
  • 本身從新找資料學習了一下——main函數命令行參數的使用
    public static void main(String...args)是本身在IDEA中寫的main命令行的代碼。




實驗三-查找與排序-3

實驗要求內容

參考http://www.cnblogs.com/maybe2030/p/4715035.html 在Searching中補充查找算法並測試
提交運行結果截圖算法

實驗過程及結果

  • 本身補充了一下斐波那契查找算法、分塊查找、二叉樹查找和哈希查找等查找算法
  • 相關代碼

這個實驗中我遇到了一些問題,遇到的相關問題會在下面詳寫。數組

實驗三-查找與排序-4

實驗要求內容

補充實現課上講過的排序方法:希爾排序,堆排序,二叉樹排序等(至少3個)
測試實現的算法(正常,異常,邊界)
提交運行結果截圖
(3分,若是編寫多個排序算法,即便其中三個排序程序有瑕疵,也能夠酌情得滿分)數據結構

實驗過程及結果

  • 部分的排序算法以前的課本學習中已經完成過
  • 希爾排序
public static void ShellSort(Comparable[] data)
    {
        int i= 0, temp = 0, j = 2;
        for (int incr = data.length / j; incr > 0; incr /= j)
        {
            for (int x = incr; x < data.length; x++)
            {
                temp = (int) data[x];
                for (i = x - incr; i >= 0; i -= incr)
                {

                    if (temp < (int) data[i])
                        data[i + incr] = data[i];
                    else
                        break;
                }
                data[i + incr] = temp;
            }
        }
    }
  • 堆排序,其中調用了以前學習堆時完成的ArrayHeap類
public static <T extends Comparable<T>>String HeapSort(T[] data) {
        ArrayHeap temp = new ArrayHeap();

        // copy the array into result heap
        for (int i = 0; i < data.length; i++)
            temp.addElement(data[i]);

        // place the sorted elements back into the array
        int count = 0;
        String result = "";
        while (!(temp.isEmpty()))
        {
            data[count] = (T) temp.removeMin();
            result += data[count] + " ";
            count++;
        }

        return result;
    }
  • 關於二叉樹排序,我並無從新寫一個方法,而是直接在tester程序中直接實例化一個linkedBinarySearchTree類中,用找到最小元素來實現函數




實驗三-查找與排序-5

實驗要求內容

編寫Android程序對各類查找與排序算法進行測試
提交運行結果截圖
推送代碼到碼雲
(加分3,加到實驗中)學習

實驗過程及結果

實驗過程當中遇到的問題及解決方案

  • 問題1:對「斐波那契查找算法」難以理解。.net

  • 問題1的解決方案:

    在介紹斐波那契查找算法以前,咱們先介紹一下很它緊密相連而且你們都熟知的一個概念——黃金分割。
      黃金比例又稱黃金分割,是指事物各部分間必定的數學比例關係,即將總體一分爲二,較大部分與較小部分之比等於總體與較大部分之比,其比值約爲1:0.618或1.618:1。
      0.618被公認爲最具備審美意義的比例數字,這個數值的做用不只僅體如今諸如繪畫、雕塑、音樂、建築等藝術領域,並且在管理、工程設計等方面也有着不可忽視的做用。所以被稱爲黃金分割。
      你們記不記得斐波那契數列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….(從第三個數開始,後邊每個數都是前兩個數的和)。而後咱們會發現,隨着斐波那契數列的遞增,先後兩個數的比值會愈來愈接近0.618,利用這個特性,咱們就能夠將黃金比例運用到查找技術中。

我知道斐波那契數列的一些特性,可是我都難以理解怎麼來運用它,它又有什麼優點呢?

  • 理解查找原理:「斐波那契查找與折半查找很類似。比較的key值與第mid=(low+high)/2位置的元素比較」
    • 基本思想:
      • 1.假設有待查找數組array[n]和斐波那契數組F[k],而且n知足n>=F[k]-1&&n < F[k+1]-1,則它的第一個拆分點middle=F[k]-1
      • 2.開始表中記錄的個數爲某個斐波那契數小1,即m=F(k)-1(就是指表中的初始數在知足第一條的狀況下,去斐波那契數列中找到這個m,並記錄);
      • 3.而後再將k值與第F(k-1)位置的記錄;
    • 進行比較(及mid=low+F(k-1)-1),比較結果也分爲三種
      • 相等,mid位置的元素即爲所求
      • 若是 >,low=mid+1,k-=2;(low=mid+1後待查找的元素在[mid+1,high]範圍內,該範圍內的元素個數爲n-(F(k-1))= Fk - 1 - F(k-1)=Fk-F(k-1)-1=F(k-2)-1個,因此k-=2)
      • 若是 <,high=mid-1,k-=1.(low=mid+1說明待查找的元素在[low,mid-1]範圍內,k-=1 說明範圍[low,mid-1]內的元素個數爲F(k-1)-1個,因此k-=1)
// 假設有待查找數組array[n]和斐波那契數組F[k],而且n知足n>=F[k]-1&&n < F[k+1]-1,則它的第一個拆分點middle=F[k]-1
        // 尋找k值,k值要求k值能使得F[k]-1剛好大於或等於n
        int k = 0;
        while (n > F[k] - 1)//計算n位於斐波那契數列的位置
            k++;

        int[] temp;//將數組data擴展到F[k]-1的長度
        temp = new int[F[k] - 1];
        for (int x = 0; x < data.length; x++) {
            temp[x] = data[x];
        }

        for (int i = n; i < F[k] - 1; ++i)
            temp[i] = data[n - 1];

        while (low <= high) {
            int mid = low + F[k - 1] - 1;
            if (key < temp[mid]) {
                high = mid - 1;
                k -= 1;
            } else if (key > temp[mid]) {
                low = mid + 1;
                k -= 2;
            } else {
                if (mid < n)
                    return mid; //若相等則說明mid即爲查找到的位置
                else
                    return n - 1; //若mid>=n則說明是擴展的數值,返回n-1
            }
        }
        return -1;
  • 斐波那契數列的優點:
    • 複雜度分析:最壞狀況下,時間複雜度爲O(logn),且其指望複雜度也爲O(logn),和對半查找法的時間複雜度相同;
    • 且對半查找法咱們從信息論的信息熵的相關知識能看出,對半查找法在執行步數上仍然比斐波那契二分查找法更少;
    • 可是從代碼算法來看,斐波那契二分查找法在覈心算法上,只有賦值與減法運算,對半查找法卻有除法運算。
      關於二分法中,斐波那契查找算法對於對半查找法優點的理解
  • 問題2:在寫分塊查找時,調用了以前寫的順序查找,而後往定義的最大元素組成的數組中添加元素是一直出現錯誤。以後發現本身定義的是T[] maxlist,而後調用方法將元素變爲Integer

可是仍是出現了

發現不會報錯了,可是數組中卻存儲不進元素,一直是null。

  • 問題2的解決方案:最後又只好重寫一個順序查找方法
public static <T> boolean linearSearch2(int[] data, int min, int max, int target)
   {
        int index = min;
        boolean found = false;

        while (!found && index <= max)
        {
            if ( data[index]==target)
                found = true;
            index++;
        }

        return found;
    }

感想或其餘

這篇博客是實驗完成了一週以後纔開始寫的,但對此次實驗個人印象仍是很深入的,主要是本身往常寫代碼的時候遇到的問題都向別人或多或少尋求了幫助,而此次寫分塊查找的算法時,我是按照 [Data Structure & Algorithm] 七大查找算法這篇博客裏的思路寫的,和別人的思路有些不同。這是這個學期的最後一個實驗了,(^o^)/~,不過接下來的小組做業挺難的。

參考資料

相關文章
相關標籤/搜索