20172305 2018-2019-1 《Java軟件結構與數據結構》第四周學習總結

20172305 2018-2019-1 《Java軟件結構與數據結構》第四周學習總結

教材學習內容總結

本週內容主要爲書第六章內容:

  • 列表
    • 有序列表(元素按照元素內在特性進行排序)
    • 無序列表(元素間不具備內在順序,元素按照他們在列表中的位置進行排序)
    • 索引列表(元素能夠用數字索引來引用)
  • 列表集合比棧和隊列更通常化,能夠在列表的中間和末端添加和刪除元素。html

  • 有序列表是基於列表中元素的某種特性的。對於任何已添加到有序列表中的元素,只要給定了元素的關鍵值,同時列表已定義了元素的全部關鍵值,那麼它在列表中就會有一個固定的位置。前端

  • 無序列表中各元素的位置並不基於元素的任何內在特性。列表中的元素是按照特殊順序放置的,只不過這種順序與元素自己無關。java

  • 索引列表的各元素間不存在可以決定他們在列表中的順序的內在關係。每一個元素都可以從一個數字索引值獲得引用,該索引值從列表頭開始從0連續增長直到列表末端。node

  • 索引值與數組的根本區別:索引列表的索引值老是連續的?git

  • Java集合API提供的列表類主要是支持索引列表。Java API沒有任何直接實現的有序列表。編程

  • 有序列表與無序列表之間的差異主要體如今往列表添加元素上
    • 有序列表中只需制定要添加的新元素,該元素在列表中的位置取決於其鍵值。
    • 無序列表中能夠把元素添加到列表的前端、末端或是列表中某個已有的元素後面。
  • Serializable接口的做用是實現串行化,爲了使某個對象能使用串行化進行存儲。數組

  • Java 序列化技術能夠將一個對象的狀態寫入一個Byte 流裏(串行化),而且能夠從其它地方把該Byte 流裏的數據讀出來(反串行化)。安全

  • 只有Comparable對象才能存儲在有序列表。網絡

  • 接口能夠用來派生其它接口,子接口包含父接口的全部的抽象方法數據結構

  • 接口名能夠用來聲明一個對象引用變量。一個接口引用能夠用來引用實現了該接口的任意類的任意對象。

  • 接口容許建立多態引用,其中被調用的方法是基於被引用時的特定對象的。

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

  • 問題1:數組與索引列表的索引值是否連續的問題?
  • 問題1解決方案:書上說的索引列表與數組的根本區別是索引列表的索引值是連續的。那麼,數組的索引值就不連續麼?能夠從0開始,下一個直接到5麼?仔細想一想是不極可能的,那麼書上的話是什麼意思呢?網上並無相關的答案,因此我想了一下以爲指的是數組能夠在容量容許的前提下跳躍式的往數組內添加元素,能夠在0索引值處添加元素,而後在5索引值處添加元素,中間的索引值內都爲零。而因此索引列表不一樣,只能連續的往裏面添加,不能中間出現斷檔。

    • 索引列表爲它的元素維護了一段連續的數字索引值
  • 問題2:列表用普通數組而不是環形數組的緣由?
  • 問題2解決方案:隊列用環形數組的緣由是隻在一頭出另外一頭進,而列表的添加方法比較多,其中就要求在中間進行添加,此外刪除的時候也要求既能夠刪頭又能夠刪尾的。因此,使用環形數組並不方便,頭部變量和尾部變量都在動,插中間會更麻煩。

代碼學習中的問題和解決過程

  • 問題1:有序列表的add與無序列表的addAfter、addToRear、addToFront的區別
  • 問題1的解決方案:有序列表與無序列表在添加的方法下有很大的不一樣,有序列表的添加直接按元素的內在順序進行排列,而無序列表的就比較任意能夠根據用戶的想法進行。此外,有序列表要求的是隻有Comparable對象才能夠存儲在有序列表中。

    數組表示有序列表的添加
      public void add(T element) {
        if (!(element instanceof Comparable)) {
            throw new NonComparableElementException("OrderList");
          }
    
        Comparable<T> comparableElement = (Comparable<T>) element;
        if (size() == list.length)
            expandCapacity();
        int scan = 0;
        while (scan < rear && comparableElement.compareTo(list[scan]) > 0)
            scan++;
        for (int shift = rear; shift > scan; shift--)
            list[shift] = list[shift - 1];
        list[scan] = element;
        rear++;
        modCount++;
      }
    鏈表表示有序列表的添加
    public void add(T element) {
      LinearNode<T> node = new LinearNode(element); 
    
      LinearNode<T> temp1 = null,temp2 = head;
      while(temp2 != null && node.compareTo(temp2.getElement())> 0){
          temp1 = temp2;
          temp2 = temp2.getNext();
        }
      if(temp1 == null){
          head = tail =  node;
        }
      else{
          temp1.setNext(node);
        }
      node.setNext(temp2);
      if(node.getNext() == null)
          tail = node;
    
      count++;
      modCount++;
      }

    經過compareTo方法來進行比較,經過循環遍歷隊列元素來判斷大小,而後數組把添加的索引值後面的元素進行後移,鏈表進行插入操做就行。可是,數組須要判斷容量大小,以及循環次數不是數組的容量而是元素的總量;鏈表須要肯定添加的元素以前鏈表是否有內容,沒有內容的話直接頭結點等於尾節點等於添加元素,有內容的話須要把後面的內容接上。

    數組表示無序列表的添加--頭插
    public void addToFront(T element) {
          if (size() == list.length)
              expandCapacity();
    
          for (int shift = rear; shift > 0; shift--)
              list[shift] = list[shift - 1];
          list[0] = element;
          rear++;
          modCount++;
    
      }
    
      數組表示無序列表的添加--尾插
      public void addToRear(T element) {
          if (size() == list.length)
              expandCapacity();
          list[rear] = element;
          rear++;
          modCount++;
    
      }
    
      數組表示無序列表的添加--目標元素後面
      public void addAfter(T element, T target) {
    
          if (size() == list.length)
              expandCapacity();
    
          int scan = 0;
    
          while (scan < rear && !target.equals(list[scan]))
              scan++;
    
          if (scan == rear)
              throw new ElementNotFoundException("UnorderedList");
    
          scan++;
    
          for (int shift = rear; shift > scan; shift--)
              list[shift] = list[shift - 1];
    
          list[scan] = element;
          rear++;
          modCount++;
      }
    鏈表表示無序列表的添加--頭插
    public void addToFront(T element) {
          LinearNode<T> node = new LinearNode<T>(element);
          LinearNode<T> temp = head;
          if(isEmpty())
              head = node;
          else {
              node.setNext(head);
              while(temp.getNext() != null){
                  temp = temp.getNext();
              }
              tail = temp;
              head = node;
          }
          count++;
          modCount++;
      }
      鏈表表示無序列表的添加--尾插
      public void addToRear(T element){
          LinearNode<T> node = new LinearNode<T>(element);
          if(isEmpty())
              head = node;
          else
              tail.setNext(node);
          tail = node;
          count++;
      }
      鏈表表示無序列表的添加--目標元素後面
      public void addAfter(T element, T target) {
          LinearNode<T> node = new LinearNode<T>(element);
          LinearNode<T> temp = head;
          if(temp == null){
              head = tail = node;
          }
          while((temp != null)&&(temp.getElement() == target)){
              temp = temp.getNext();
          }
          if(temp.getNext() == null){
              temp.setNext(node);
              tail = node;
          }else{
              node.setNext(temp.getNext());
              temp.setNext(node);
          }
          count++;
          modCount++;
      }
    無序列表的添加看似多實則比有序列表的簡單多了就是進行尾插、頭插、中間插三種方法。其中,尾插法相對簡單,頭插法須要把數組內的全部元素總體後移,遍歷一遍,中間插的話要考慮插後的元素來肯定後移的循環次數。
  • 問題2:列表的常見操做removeFirst、removeLast、remove、first、last、contains、isEmpty、size方法
  • 問題2的解決方法:無序列表和有序列表的共有方法

    • removeFirst:從列表中刪除第一個元素
    • 數組:須要先判斷數組是否爲空,不爲空的話索引值爲0的內容直接等於索引值爲1的內容,以此循環前移。
    • 鏈表:先判斷鏈表內的元素的個數,若是爲1直接頭結點等於尾節點等於空,不爲1的話直接使鏈表的頭等於頭的下一個。
    • removeLast:從列表中刪除最後一個元素
    • 數組:在數組不爲空的前提下,直接使數組索引值最大的位置內爲空,計數變量減一。
    • 鏈表:肯定鏈表內元素的個數,若是爲1直接頭結點等於尾節點等於空,不爲1的話就經過遍歷鏈表,從頭找到尾,肯定尾部爲空,倒第二爲尾部。
    • remove:從列表中刪除某個元素
    • 數組:經過find方法的輔助能夠肯定刪除元素是否在隊列中以及索引值的位置,而後在此索引值後的元素依次前移,此前數組索引值最大的位置爲空。
    • 鏈表:肯定列表是否爲空或僅有一個元素、元素是否在列表中、並處理刪除元素是列表的末尾元素、首元素、仍是中間位置。若是是刪除僅有的元素就直接令頭結點等於尾結點等於空,刪除頭元素直接令頭結點等於頭結點的下一個,刪除尾元素就遍歷到倒數第二個爲尾結點,刪除的是中間的元素就直接把前一個元素與後一個元素鏈接。
    • first:查看位於列表前端的元素
    • 數組:先判斷數組是否有元素,再直接輸出索引值爲0的內容。
    • 鏈表:先判斷鏈表內是否有元素,再直接調出頭結點的內容。
    • last:查看位於列表末端的元素
    • 數組:先判斷數組是否有元素,再直接輸出索引值最大的內容。
    • 鏈表:先判斷鏈表內是否有元素,再直接調出尾結點的內容。
    • contains:肯定列表是否含有某個元素
    • 數組:經過find方法輔助就能夠(在必定程度上find方法和contains方法做用相同)。
    • 鏈表:在不爲空的狀況下,遍歷一遍鏈表找尋就能夠。
    • isEmpty:斷定列表是否爲空
    • 數組:判斷計數變量是否爲零,爲零即列表爲空。
    • 鏈表:頭結點等於尾結點等於空或是計數變量是否爲零。
    • toString:
    • 數組:以計數變量的值爲循環次數進行循環輸出。
    • 鏈表:從頭節點開始遍歷一遍到尾結點。
    • 關於數組列表的find方法:經過元素與數組內每個索引下的內容的對比,來判斷索引值的方法。
    • 優勢:可使其餘方法變得簡單易懂,也能夠利用find方法來輔助其餘一堆方法。
    • 數組實現的無序列表
    • 鏈表實現的無序列表
  • 問題3:i++i+1的區別
  • 問題3解決方案:在用數組實現remove方法的時候在移動過程當中發現i++i+1的不一樣意義,雖然以前老師說過二者意義不一樣,一直沒有在乎,直到二者在循環的時候才發現,若是用i++的話並不會刪除目標元素,相反會把數組的末尾元素刪掉;若是用i+1的話就會把刪除目標元素,數組的末尾元素不會被刪掉。我以爲是在第一次循環的時候,i++並無起到自增的做用,而是把i索引值內的元素又放到i索引值內,致使最後一次循環的時候尾部元素的索引值是最大的,被後面的賦空語句直接刪掉了。而i+1就在循環的第一次實現了自增,使得目標元素被刪掉,最大索引值和最大索引值減1存儲的都是一個元素,這樣在經過賦空語句就能夠了。
    • 刪除「網絡空間安全系」的i++版:
    • 刪除「網絡空間安全系」的i+1版:
  • 問題4:PP6.17修改Course進行按系排序在按課程號排序
  • 問題4解決方案:相同類型的編程項目在上學期第七章就實現過,實現Comparable接口,不少同窗由於沒有寫implements Comparable<>直接寫個方法完成而扣分,印象十分深入。有了以前的經驗,在練習此次的就沒那麼難,以前的是進行一重比較,題目要求的是兩重比較,在系相同的狀況下對課程號進行排序。直接把比較後的數值輸出,而後在(有序列表)添加的方法裏面融入比較的方法。可是,在上傳到碼雲的時候看了一下別人的代碼,以爲直接肯定大小後輸出-一、1和0三個固定的數沒有差異,就沒有進行修改。在用數組和鏈表去實現的時候,發現用數組的方法就會報錯NullPointerException,找了半天也沒有發現錯誤,後來使用鏈表的方法就很成功的實現了,會繼續找數組的添加方法的bug的。

代碼託管

上週考試錯題總結

  • 第三章和第四章

  • 錯題1:In an array implementation of a Stack, the array is ___________ causing the implementation to have to create a new larger array and copy the contents of the stack into the new array in order to expand the capacity of the stack.()
    • A .Dynamic
    • B .Static
    • C .Flexible
    • D .Polymorphic
  • 錯誤解析:擴容的方法是在原數組已滿的前提下更換新容量更大的數組,可是在未更換以前數組的容量一直保持不變。

  • 錯題2:A reference variable can refer to any object created from any class related to it by inheritance.
    • A .true
    • B .false
  • 錯誤解析:引用變量能夠引用任何經過繼承過來與之相關的類建立的對象,就是子類與父類的關係即子類能夠用父類的任何方法對象,可是父類不能用子類的方法對象。

  • 錯題3:By using the interface name as a return type, the interface doesn’t commit the method to the use of any particular class that implements a stack.
    • A .true
    • B .false
  • 錯誤解析:使用接口名做爲返回類型,接口將不會把方法提交給任何實現堆棧的特定類。

  • 錯題4:The implementation of the collection operations should affect the way users interact with the collection.
    • A .true
    • B .false
  • 錯誤解析:集合的實現和用戶與集合的交互沒有影響。第三章和第四章不管使用數組仍是鏈表進行維護集合以及維護集合相關的方法都對集合自己毫無影響。

  • 錯題5:Inherited variables and methods can be used in the derived class as if they had been declared locally.
    • A .true
    • B .false
  • 錯誤解析:繼承的變量和方法均可以在子類中應用,經過super、extends等保留字就能夠。

  • 錯題6:A linked implementation of a stack adds and removes elements from the _______ of the linked list.
    • A .Front
    • B .Rear
    • C .Middle
    • D .None of the above
  • 錯題解析:堆棧的鏈表用頭和尾均可以當棧頂,可是用頭來充當的話會避免每次循環找到尾,再在尾部進行添加的麻煩。

  • 錯題7:Objects that are stored in a collection should contain implementation details of the underlying data structure.
    • A .true
    • B .false
  • 錯誤解析:存儲在集合中的對象應該包含底層數據結構的實現細節,集合內能夠存儲任何內容。

  • 第五章

  • 錯題1:Which of the following operations of a queue examines the element at the front of the queue?
    • A .Enqueue
    • B .isEmpty
    • C .size
    • D .first
  • 錯誤解析:檢查隊列前面的元素用的是first方法,size是用來判斷隊列裏元素的個數。

  • 第三章和第四章的內容有一部分是上學期的內容,不少都不敢肯定選項。第五章錯的錯的題目太惋惜了,爲了趕時間沒有再細細看一遍就提早交卷,結果就錯了一道特別特別簡單的題目。其實,錯題再看一遍就發現本身的選項錯哪了,都不知道本身當時爲何選別的。

結對與互評

點評(王禹涵)

  • 博客中值得學習的或問題:
    • 博客中對於問題的圖片放得很到位,解釋的很好。
  • 代碼中值得學習的或問題:
    • 問題及解決方案說得很到位,建議圖片能夠小點。
  • 基於評分標準,我給本博客打分:6分。
    • 得分狀況以下:
    • 正確使用Markdown語法(加1分)
    • 模板中的要素齊全(加1分)
    • 教材學習中的問題和解決過程, 一個問題加1分
    • 代碼調試中的問題和解決過程, 一個問題加1分
    • 感想,體會不假大空的加1分
    • 點評認真,能指出博客和代碼中的問題的加1分

點評(方藝雯)

  • 博客中值得學習的或問題:
    • 圖片運用恰當,很清晰的解釋了問題和相關內容。
  • 基於評分標準,我給本博客打分:9分。
  • 得分狀況以下:
    • 正確使用Markdown語法(加1分)
    • 模板中的要素齊全(加1分)
    • 教材學習中的問題和解決過程, 二個問題加2分
    • 代碼調試中的問題和解決過程, 三個問題加3分
    • 感想,體會不假大空的加1分
    • 點評認真,能指出博客和代碼中的問題的加1分

互評對象

感悟

第六章的內容是用數組和鏈表表示列表的,在必定還曾獨上列表和隊列、棧都有必定程度上的類似,部分代碼徹底能夠以前編寫的,惟一以爲比較噁心的就是在添加的過程當中就直接被排序。經過這幾章學的內容,對鏈表和數組有了更多的認識,應用起來也比較順手。勤能補拙,多聯繫多嘗試總沒有錯的。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 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

參考資料

相關文章
相關標籤/搜索