列表集合比棧和隊列更通常化,能夠在列表的中間和末端添加和刪除元素。html
有序列表是基於列表中元素的某種特性的。對於任何已添加到有序列表中的元素,只要給定了元素的關鍵值,同時列表已定義了元素的全部關鍵值,那麼它在列表中就會有一個固定的位置。前端
無序列表中各元素的位置並不基於元素的任何內在特性。列表中的元素是按照特殊順序放置的,只不過這種順序與元素自己無關。java
索引列表的各元素間不存在可以決定他們在列表中的順序的內在關係。每一個元素都可以從一個數字索引值獲得引用,該索引值從列表頭開始從0連續增長直到列表末端。node
索引值與數組的根本區別:索引列表的索引值老是連續的?git
Java集合API提供的列表類主要是支持索引列表。Java API沒有任何直接實現的有序列表。編程
Serializable接口的做用是實現串行化,爲了使某個對象能使用串行化進行存儲。數組
Java 序列化技術能夠將一個對象的狀態寫入一個Byte 流裏(串行化),而且能夠從其它地方把該Byte 流裏的數據讀出來(反串行化)。安全
只有Comparable對象才能存儲在有序列表。網絡
接口能夠用來派生其它接口,子接口包含父接口的全部的抽象方法數據結構
接口名能夠用來聲明一個對象引用變量。一個接口引用能夠用來引用實現了該接口的任意類的任意對象。
接口容許建立多態引用,其中被調用的方法是基於被引用時的特定對象的。
問題1解決方案:書上說的索引列表與數組的根本區別是索引列表的索引值是連續的。那麼,數組的索引值就不連續麼?能夠從0開始,下一個直接到5麼?仔細想一想是不極可能的,那麼書上的話是什麼意思呢?網上並無相關的答案,因此我想了一下以爲指的是數組能夠在容量容許的前提下跳躍式的往數組內添加元素,能夠在0索引值處添加元素,而後在5索引值處添加元素,中間的索引值內都爲零。而因此索引列表不一樣,只能連續的往裏面添加,不能中間出現斷檔。
- 索引列表爲它的元素維護了一段連續的數字索引值。
問題2解決方案:隊列用環形數組的緣由是隻在一頭出另外一頭進,而列表的添加方法比較多,其中就要求在中間進行添加,此外刪除的時候也要求既能夠刪頭又能夠刪尾的。因此,使用環形數組並不方便,頭部變量和尾部變量都在動,插中間會更麻煩。
問題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:從列表中刪除第一個元素
- 數組:須要先判斷數組是否爲空,不爲空的話索引值爲0的內容直接等於索引值爲1的內容,以此循環前移。
- 鏈表:先判斷鏈表內的元素的個數,若是爲1直接頭結點等於尾節點等於空,不爲1的話直接使鏈表的頭等於頭的下一個。
- removeLast:從列表中刪除最後一個元素
- 數組:在數組不爲空的前提下,直接使數組索引值最大的位置內爲空,計數變量減一。
- 鏈表:肯定鏈表內元素的個數,若是爲1直接頭結點等於尾節點等於空,不爲1的話就經過遍歷鏈表,從頭找到尾,肯定尾部爲空,倒第二爲尾部。
- remove:從列表中刪除某個元素
- 數組:經過find方法的輔助能夠肯定刪除元素是否在隊列中以及索引值的位置,而後在此索引值後的元素依次前移,此前數組索引值最大的位置爲空。
- 鏈表:肯定列表是否爲空或僅有一個元素、元素是否在列表中、並處理刪除元素是列表的末尾元素、首元素、仍是中間位置。若是是刪除僅有的元素就直接令頭結點等於尾結點等於空,刪除頭元素直接令頭結點等於頭結點的下一個,刪除尾元素就遍歷到倒數第二個爲尾結點,刪除的是中間的元素就直接把前一個元素與後一個元素鏈接。
- first:查看位於列表前端的元素
- 數組:先判斷數組是否有元素,再直接輸出索引值爲0的內容。
- 鏈表:先判斷鏈表內是否有元素,再直接調出頭結點的內容。
- last:查看位於列表末端的元素
- 數組:先判斷數組是否有元素,再直接輸出索引值最大的內容。
- 鏈表:先判斷鏈表內是否有元素,再直接調出尾結點的內容。
- contains:肯定列表是否含有某個元素
- 數組:經過find方法輔助就能夠(在必定程度上find方法和contains方法做用相同)。
- 鏈表:在不爲空的狀況下,遍歷一遍鏈表找尋就能夠。
- isEmpty:斷定列表是否爲空
- 數組:判斷計數變量是否爲零,爲零即列表爲空。
- 鏈表:頭結點等於尾結點等於空或是計數變量是否爲零。
- toString:
- 數組:以計數變量的值爲循環次數進行循環輸出。
- 鏈表:從頭節點開始遍歷一遍到尾結點。
- 關於數組列表的find方法:經過元素與數組內每個索引下的內容的對比,來判斷索引值的方法。
- 優勢:可使其餘方法變得簡單易懂,也能夠利用find方法來輔助其餘一堆方法。
i++
與i+1
的區別i++
與i+1
的不一樣意義,雖然以前老師說過二者意義不一樣,一直沒有在乎,直到二者在循環的時候才發現,若是用i++
的話並不會刪除目標元素,相反會把數組的末尾元素刪掉;若是用i+1
的話就會把刪除目標元素,數組的末尾元素不會被刪掉。我以爲是在第一次循環的時候,i++
並無起到自增的做用,而是把i索引值內的元素又放到i索引值內,致使最後一次循環的時候尾部元素的索引值是最大的,被後面的賦空語句直接刪掉了。而i+1
就在循環的第一次實現了自增,使得目標元素被刪掉,最大索引值和最大索引值減1存儲的都是一個元素,這樣在經過賦空語句就能夠了。
i++
版:i+1
版:問題4解決方案:相同類型的編程項目在上學期第七章就實現過,實現Comparable接口,不少同窗由於沒有寫implements Comparable<>直接寫個方法完成而扣分,印象十分深入。有了以前的經驗,在練習此次的就沒那麼難,以前的是進行一重比較,題目要求的是兩重比較,在系相同的狀況下對課程號進行排序。直接把比較後的數值輸出,而後在(有序列表)添加的方法裏面融入比較的方法。可是,在上傳到碼雲的時候看了一下別人的代碼,以爲直接肯定大小後輸出-一、1和0三個固定的數沒有差異,就沒有進行修改。在用數組和鏈表去實現的時候,發現用數組的方法就會報錯NullPointerException,找了半天也沒有發現錯誤,後來使用鏈表的方法就很成功的實現了,會繼續找數組的添加方法的bug的。
錯誤解析:檢查隊列前面的元素用的是first方法,size是用來判斷隊列裏元素的個數。
本週結對學習狀況
20172314方藝雯
20172323王禹涵
結對學習內容:鏈表和數組實現列表
第六章的內容是用數組和鏈表表示列表的,在必定還曾獨上列表和隊列、棧都有必定程度上的類似,部分代碼徹底能夠以前編寫的,惟一以爲比較噁心的就是在添加的過程當中就直接被排序。經過這幾章學的內容,對鏈表和數組有了更多的認識,應用起來也比較順手。勤能補拙,多聯繫多嘗試總沒有錯的。
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 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 |