20172318 2018-2019-1 《程序設計與數據結構》第5周學習總結

20172318 2018-2019-1 《程序設計與數據結構》第5周學習總結

教材學習內容總結

排序與查找

  • searching:查找
    • 查找是這樣一個過程,即在某個項目組中尋找某一指定目標元素,或者肯定該指定
      目標並不存在。
    • 高效的查找會使該過程所作的比較操做次數最小化·
    • searchpool:查找池要查找的一組元素項。
  • staticmethod 靜態方法:經過類名來調用的一種方法,該類名不能引用實例數據。也稱
    爲類方法。
    • 在方法聲明中,經過使用static修飾符就能夠把它聲明爲靜態的·
  • generic method:泛型方法
    • 與建立泛型類類似,咱們也能夠建立泛型方法。即,不是建立一個引用泛型參數的類,而是建立一個引用泛型的方法。泛型參數只應用於該方法。要建立一個泛型方法,只需在方法頭的返回類型前插入一個泛型聲明便可:
  • linearsearch:線性查找:一種查找方式,從列表項的一端開始,按線性方式進行,直到找到要查找的元素,或達到了列表的末端(代表沒有找到要查找的元素)。html

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;
    }
  • 二分查找法
    • binarysearch:二分查找對己排序列表的查找,其中每次比較操做,均可以去除人約一
      半的剩餘可行候選元素。
    • 二分查找將利用了查找池是已排序的這一事實·
    • 二分查找的每次比較都會刪除一半的可行候選項。
    • logarithmic algorithm對數算法:複雜度爲0(g2n)的算法,如二叉查找。
    • logarithmic sort:對數排序、種排序算法,若是要給n個元素進行排序,須要大約nlog2n
      次比較操做。java

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;
    }
  • 二分查找的複雜度是對數級的,這使得它對於大型查找池很是有效率·git

  • sorting:排序
    • 排序是這樣一個過程,即基於某一標準,將某一組項目接照某個規定順序排列「
  • selectionsort:選擇排序:算法經過反覆地將某一特定值放到它在列表中的最終已排序位置從而完成
    對某一列表值的排序
public static <T extends Comparable<T>> 
        void selectionSort(T[] data)
    {
        int min;
        T temp;
        
        for (int index = 0; index < data.length-1; index++)
        {
            min = index;
            for (int scan = index+1; scan < data.length; scan++)
                if (data[scan].compareTo(data[min])<0)
                    min = scan;
            
            swap(data, min, index);
        }
    }

private static <T extends Comparable<T>> 
        void swap(T[] data, int index1, int index2)
    {
        T temp = data[index1];
        data[index1] = data[index2];
        data[index2] = temp;
    }
  • insertionsort:插入排序:插入排序算法經過反覆地將某一特定值插入到該列表某個已排序的子集中來完成對
    列表值的排序·
public static <T extends Comparable<T>> 
        void insertionSort(T[] data)
    {
        for (int index = 1; index < data.length; index++)
        {
            T key = data[index];
            int position = index;
            
            // shift larger values to the right 
            while (position > 0 && data[position-1].compareTo(key) > 0)
            {
                data[position] = data[position-1];
                position--;
            }
            
            data[position] = key;
        }
    }
  • bubble sort:冒泡排序:冒泡排序算法經過重複地比較相鄰元素且在必要時將它們互換,從而完成對某個列
    表的排序。
public static <T extends Comparable<T>> 
        void bubbleSort(T[] data)
    {
        int position, scan;
        T temp;
        
        for (position =  data.length - 1; position >= 0; position--)
        {
            for (scan = 0; scan <= position - 1; scan++)
            {
                if (data[scan].compareTo(data[scan+1]) > 0)
                    swap(data, scan, scan + 1);
            }
        }
    }
  • quicksort:快速排序:快速排序算法經過將列表分區,而後對這兩個分區進行遞歸式排序,從而完成對整
    個列表的排序·
    • partition:分區快速排序算法使用的未排序元素的一個集合,其中的元素個部小於或大
      於選定的某個元素。
    • partitionelement:分區元素快速排序算法用來把未排序元素分隔成兩個不一樣分區的
      元素。
public static <T extends Comparable<T>> 
        void quickSort(T[] data)
    {
        quickSort(data, 0, data.length - 1);
    }
    
private static <T extends Comparable<T>> 
        void quickSort(T[] data, int min, int max)
    {
        if (min < max)
        {
            int indexofpartition = partition(data, min, max);
            
            quickSort(data, min, indexofpartition - 1);
            
            quickSort(data, indexofpartition + 1, max);
        }
    }
    
private static <T extends Comparable<T>> 
        int partition(T[] data, int min, int max)
    {
        T partitionelement;
        int left, right;
        int middle = (min + max) / 2;
        
        partitionelement = data[middle];
        swap(data, middle, min);
        
        left = min;
        right = max;
        
        while (left < right)
        {
            while (left < right && data[left].compareTo(partitionelement) <= 0)
                left++;
            
            while (data[right].compareTo(partitionelement) > 0)
                right--;
            
            if (left < right)
                swap(data, left, right);
        }
        
        swap(data, min, right);
        
        return right;
    }
  • mergesort:歸併排序:算法經過將列表遞歸式分紅兩半直至每一子列表都含有一個元素,而後將
    這些子列表歸併到一個排序順序中,從而完成對列表的排序·
public static <T extends Comparable<T>>
        void mergeSort(T[] data)
    {
        mergeSort(data, 0, data.length - 1);
    }
    
private static <T extends Comparable<T>>
        void mergeSort(T[] data, int min, int max)
    {
        if (min < max)
        {
            int mid = (min + max) / 2;
            mergeSort(data, min, mid);
            mergeSort(data, mid+1, max);
            merge(data, min, mid, max);
        }
    }
    
    
    @SuppressWarnings("unchecked")
private static <T extends Comparable<T>>
        void merge(T[] data, int first, int mid, int last)
    {
        T[] temp = (T[])(new Comparable[data.length]);
        
        int first1 = first, last1 = mid;  // endpoints of first subarray
        int first2 = mid+1, last2 = last;  // endpoints of second subarray
        int index = first1;  // next index open in temp array
        
        while (first1 <= last1 && first2 <= last2)
        {
            if (data[first1].compareTo(data[first2]) < 0)
            {
                temp[index] = data[first1];
                first1++;
            }
            else
            {
                temp[index] = data[first2];
                first2++;
            }
            index++;
        }
        
        while (first1 <= last1)
        {
            temp[index] = data[first1];
            first1++;
            index++;
        }
        
        while (first2 <= last2)
        {
            temp[index] = data[first2];
            first2++;
            index++;
        }
        
        for (index = first; index <= last; index++)
            data[index] = temp[index];
   }
  • radixsort:基數排序:一種排序算法,使用排序密鑰而不是直接地進行比較元素,來實現元素排序
    • 基數排序是基於隊列處理的。算法

  • sequentialsort:順序排序:一種排序算法,一般使用嵌套循環,須要大約n2次比較來給n
    個元素排序。數組

  • targetelement:目標元素:在查找操做中要尋找的元素。
  • viablecandidates:可行候選:查找池中的元素,在這些元素中可能找到目標元素。數據結構

教材學習中的問題和解決過程

  • 問題1:各個排序法的時間和空間複雜度
  • 問題1解決方案:學習

  • 問題2:各個排序法的應用場景
  • 問題2解決方案:
    (1)若n較小(如n≤50),可採用直接插入或直接選擇排序。
     當記錄規模較小時,直接插入排序較好;不然由於直接選擇移動的記錄數少於直接插人,應選直接選擇排序爲宜。
    (2)若文件初始狀態基本有序(指正序),則應選用直接插人、冒泡或隨機的快速排序爲宜;
    (3)若n較大,則應採用時間複雜度爲O(nlgn)的排序方法:快速排序、堆排序或歸併排序。
     快速排序是目前基於比較的內部排序中被認爲是最好的方法,當待排序的關鍵字是隨機分佈時,快速排序的平均時間最短;
     堆排序所需的輔助空間少於快速排序,而且不會出現快速排序可能出現的最壞狀況。這兩種排序都是不穩定的。
     若要求排序穩定,則可選用歸併排序。但前面介紹的從單個記錄起進行兩兩歸併的排序算法並不值得提倡,一般能夠將它和直接插入排序結合在一塊兒使用。先利用直接插入排序求得較長的有序子序列,而後再兩兩歸併之。由於直接插入排序是穩定 的,因此改進後的歸併排序還是穩定的。
    ---------------------
    做者:Seven17000
    來源:CSDN
    原文:https://blog.csdn.net/mbuger/article/details/67643185?utm_source=copy
    版權聲明:本文爲博主原創文章,轉載請附上博文連接!測試

代碼調試中的問題和解決過程

  • 問題1:pp9.2運行出現ui

  • 問題1解決方案:這是一個很是常見的異常,從名字上看是數組下標越界錯誤,解決方法就是查看爲何下標越界。
    for (int j = 0;j<=data.length-i;j++) {
    這是我錯誤的條件,後來我發現應該這樣寫for (int j = 0;j<=data.length-1-i;j++) {
    最後測試成功.net

  • 問題2:如何獲取程序執行時間?
  • 參考了博客java獲取程序執行時間
    第一種是以毫秒爲單位計算的。

//僞代碼

long startTime=System.currentTimeMillis(); //獲取開始時間

doSomeThing(); //測試的代碼段

long endTime=System.currentTimeMillis(); //獲取結束時間

System.out.println("程序運行時間: "+(end-start)+"ms");

//僞代碼

long startTime=System.currentTimeMillis(); //獲取開始時間

doSomeThing(); //測試的代碼段

long endTime=System.currentTimeMillis(); //獲取結束時間

System.out.println("程序運行時間: "+(end-start)+"ms");
第二種是以納秒爲單位計算的。

//僞代碼

long startTime=System.nanoTime(); //獲取開始時間

doSomeThing(); //測試的代碼段

long endTime=System.nanoTime(); //獲取結束時間

System.out.println("程序運行時間: "+(end-start)+"ns");

//僞代碼

long startTime=System.nanoTime(); //獲取開始時間

doSomeThing(); //測試的代碼段

long endTime=System.nanoTime(); //獲取結束時間

System.out.println("程序運行時間: "+(end-start)+"ns");

上週考試錯題總結

上週無錯題

代碼託管

點評過的同窗博客和代碼

  • 本週結對學習狀況
    • 20172312
    • 課本內容總結詳細,圖片較少
    • 結對學習內容
      • 課本第九章

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 0/0 1/1 8/8
第二週 500/500 1/2 15/ 23
第三週 802/1302 1/3 12/35
第四周 1530/2832 2/5 15/50
第五週 1165/3997 1/6 10/60

參考資料

相關文章
相關標籤/搜索