Teknologian jakaminen

LinkedList ja linkitetty lista

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. ArrayListin viat

Kun lisäät tai poistat elementtejä missä tahansa paikassa ArrayListissä, sinun on siirrettävä kaikki seuraavat elementit eteenpäin tai taaksepäin. Aika monimutkaisuus on O(n) ja tehokkuus on siksi suhteellisen alhainen kohtaus. Siksi: LinkedList, linkitetty luettelorakenne, otetaan käyttöön Java-kokoelmissa.

2. Linkitetty luettelo

2.1 Linkitetyn listan käsite ja rakenne

Linkitetty lista on fyysisesti epäjatkuva tallennusrakenne, ja tietoelementtien looginen järjestys saavutetaan linkitetyn listan viitelinkkijärjestyksen avulla.

2.2 Linkitetyn listan käyttöönotto

1. Otsikon lisäysmenetelmä addFirst()

  1. public void addFirst(int data) {
  2. ListNode node = new ListNode(data);
  3. node.next = head;
  4. head = node;
  5. }

2. Hännän lisäysmenetelmä addLast()

  1. public void addList(int data) {
  2. ListNode node = new ListNode(data);
  3. if (head == null) {
  4. head = node;
  5. }
  6. ListNode cur = head;
  7. while (cur.next != null) {
  8. cur = cur.next;
  9. }
  10. cur.next = node;
  11. }

3.addIndex()

  1. public void addIndex(int index, int data) {
  2. int len = size();
  3. // 不合法
  4. if (index < 0 || index > len) {
  5. System.out.println("index不合法");
  6. return;
  7. }
  8. // 空链表
  9. if (index == 0) {
  10. addFirst(data);
  11. return;
  12. }
  13. // 尾部插入
  14. if (index == len) {
  15. addLast(data);
  16. return;
  17. }
  18. //中间位置插入
  19. ListNode cur = head;
  20. while (index - 1 != 0) {
  21. cur = cur.next;
  22. index--;
  23. }
  24. ListNode node = new ListNode(data);
  25. node.next = cur.next;
  26. cur.next = node;
  27. }

4.contains()

  1. public boolean contains(int key) {
  2. ListNode cur = head;
  3. while (cur != null) {
  4. if (cur.val == key) {
  5. return true;
  6. }
  7. cur = cur.next;
  8. }
  9. return false;
  10. }

5.remove()

  1. public void remove(int key) {
  2. if (head == null) {
  3. return;
  4. }
  5. if (head.val == key) {
  6. head = head.next;
  7. }
  8. ListNode cur = findNodeOfKey(key);
  9. if (cur == null) {
  10. return;
  11. }
  12. ListNode del = cur.next;
  13. cur.next = del.next;
  14. }
  15. private ListNode findNodeOfKey(int key) {
  16. ListNode cur = head;
  17. while (cur.next != null) {
  18. if (cur.next.val == key) {
  19. return cur;
  20. }
  21. cur = cur.next;
  22. }
  23. return null;
  24. }

6.removeAllKey()

  1. public void removeAllKey(int key) {
  2. ListNode cur = head.next;
  3. ListNode prev = head;
  4. while (cur != null) {
  5. if (cur.val == key) {
  6. prev.next = cur.next;
  7. } else {
  8. prev = cur;
  9. }
  10. cur = cur.next;
  11. }
  12. if (head.val == key) {
  13. head = head.next;
  14. }
  15. }

7.clear()

  1. public void clear() {
  2. ListNode cur = head;
  3. while (cur != null) {
  4. ListNode curNext = cur.next;
  5. cur.next = null;
  6. cur = curNext;
  7. }
  8. head = null;
  9. }

8.size()

  1. public int size() {
  2. int count = 0;
  3. ListNode cur = head;
  4. while (cur != null) {
  5. count++;
  6. cur = cur.next;
  7. }
  8. return count;
  9. }

9.näyttö()

  1. public void display() {
  2. ListNode cur = head;
  3. while (cur != null) {
  4. System.out.print(cur.val + " ");
  5. cur = cur.next;
  6. }
  7. }

3.LinkedListin simulointi

  1. / 2、无头双向链表实现
  2. public class MyLinkedList {
  3. //头插法
  4. public void addFirst(int data){ }
  5. //尾插法
  6. public void addLast(int data){}
  7. //任意位置插入,第一个数据节点为0号下标
  8. public void addIndex(int index,int data){}
  9. //查找是否包含关键字key是否在单链表当中
  10. public boolean contains(int key){}
  11. //删除第一次出现关键字为key的节点
  12. public void remove(int key){}
  13. //删除所有值为key的节点
  14. public void removeAllKey(int key){}
  15. //得到单链表的长度
  16. public int size(){}
  17. public void display(){}
  18. public void clear(){}
  19. }
  1. package DounlyLinkedList;
  2. import java.util.LinkedList;
  3. import java.util.List;
  4. public class MyDoublyLinkedList implements IList {
  5. static class ListNode {
  6. public int val;
  7. public ListNode next;
  8. public ListNode prev;
  9. public ListNode(int val) {
  10. this.val = val;
  11. }
  12. }
  13. public ListNode head;
  14. public ListNode last;
  15. @Override
  16. public void addFist(int data) {
  17. ListNode node = new ListNode(data);
  18. if (head == null) {
  19. head = node;
  20. last = node;
  21. } else
  22. node.next = head;
  23. head.prev = node;
  24. head = node;
  25. }
  26. @Override
  27. public void addLast(int data) {
  28. ListNode node = new ListNode(data);
  29. if (head == null) {
  30. head = node;
  31. last = node;
  32. }
  33. last.next = node;
  34. node.prev = last;
  35. last = node;
  36. }
  37. @Override
  38. public void addIndex(int index, int data) {
  39. int len = size();
  40. if (index < 0 || index > len) {
  41. System.out.println("index 不合法!");
  42. }
  43. if (index == 0) {
  44. addFist(data);
  45. return;
  46. }
  47. if (index == len) {
  48. addLast(data);
  49. return;
  50. }
  51. ListNode cur = findIndex(index);
  52. ListNode node = new ListNode(data);
  53. node.next = cur;
  54. cur.prev.next = node;
  55. node.prev = cur.prev;
  56. cur.prev = node;
  57. }
  58. private ListNode findIndex(int index) {
  59. ListNode cur = head;
  60. while (index != 0) {
  61. cur = cur.next;
  62. index--;
  63. }
  64. return cur;
  65. }
  66. @Override
  67. public boolean contains(int key) {
  68. ListNode cur = head;
  69. int count = 0;
  70. while (cur != null) {
  71. if (cur.val == key) {
  72. return true;
  73. }
  74. cur = cur.next;
  75. }
  76. return false;
  77. }
  78. @Override
  79. public void remove(int key) {
  80. ListNode cur = head;
  81. while (cur != null) {
  82. if (cur.val == key) {
  83. if (cur == head) {
  84. head = head.next;
  85. if (head != null) {
  86. head.prev = null;
  87. }
  88. head.prev = null;
  89. } else {
  90. cur.prev.next = cur.next;
  91. if (cur.next == null) {
  92. last = last.prev;
  93. } else {
  94. cur.next.next = cur.prev;
  95. }
  96. }
  97. return;
  98. }
  99. cur = cur.next;
  100. }
  101. }
  102. @Override
  103. public void removeAllKey(int key) {
  104. ListNode cur = head;
  105. while (cur != null) {
  106. if (cur.val == key) {
  107. if (cur == head) {
  108. head = head.next;
  109. if (head != null) {
  110. head.prev = null;
  111. }
  112. head.prev = null;
  113. } else {
  114. cur.prev.next = cur.next;
  115. if (cur.next == null) {
  116. last = last.prev;
  117. } else {
  118. cur.next.next = cur.prev;
  119. }
  120. }
  121. }
  122. cur = cur.next;
  123. }
  124. }
  125. @Override
  126. public int size() {
  127. ListNode cur = head;
  128. int count = 0;
  129. while (cur != null) {
  130. count++;
  131. cur = cur.next;
  132. }
  133. return count;
  134. }
  135. @Override
  136. public void clear() {
  137. ListNode cur = head;
  138. while (cur != null) {
  139. ListNode curNext = cur.next;
  140. cur.next = null;
  141. cur.prev = null;
  142. cur = curNext;
  143. }
  144. head = null;
  145. last = null;
  146. }
  147. @Override
  148. public void dispaly() {
  149. ListNode cur = head;
  150. while (cur != null) {
  151. System.out.print(cur.val + " ");
  152. cur = cur.next;
  153. }
  154. System.out.println();
  155. }
  156. }
  1. package DounlyLinkedList;
  2. public interface IList {
  3. void addFist(int data);
  4. void addLast(int data);
  5. void addIndex(int index, int data);
  6. boolean contains(int key);
  7. void remove(int key);
  8. void removeAllKey(int key);
  9. int size();
  10. void clear();
  11. void dispaly();
  12. }

4.LinkedListin käyttö

4.1 Mikä LinkedLis on

【kuvaa】

1. LinkedList toteuttaa List-rajapinnan

2. LinkedListin alla oleva kerros käyttää kaksoislinkitettyä luetteloa

3. LinkedList ei toteuta RandomAccess-käyttöliittymää, joten LinkedList ei tue satunnaiskäyttöä.

4. Elementtien lisääminen ja poistaminen missä tahansa kohdassa LinkedListissä on suhteellisen tehokasta ja aika monimutkaisuus on O(1)

5. LinkedList sopii paremmin lisäysskenaarioihin missä tahansa paikassa

4.2 LinkedListin käyttö

1. LinkedListin rakentaminen

menetelmäselittää
LinkedList()Väitteetön rakenne
public LinkedList(kokoelmaLuo lista käyttämällä elementtejä muista keräyssäiliöistä
  1. import java.util.LinkedList;
  2. import java.util.List;
  3. public class Test {
  4. public static void main(String[] args) {
  5. List<Integer> list1 = new LinkedList<>();
  6. List<String> list2 = new java.util.ArrayList<>();
  7. list2.add("javaSE");
  8. list2.add("javaWeb");
  9. list2.add("javaEE");
  10. List<String> list3 = new LinkedList<>(list2);
  11. }
  12. }

2. Johdatus muihin LinkedListin yleisiin menetelmiin

menetelmäselittää
boolen lisäys(E e)takatulppa e
void add(int-indeksi, E-elementti)Lisää e indeksikohtaan
boolean addAll(kokoelma c)Lisää elementit c:hen loppuun
E poista (int index)Poista indeksin sijaintielementti
boolen poisto (objekti o)Poista ensimmäinen havaittu
E get(int index)Hanki alaindeksin sijaintielementti
E-joukko(int-indeksi, E-elementti)Aseta alaindeksin hakemiston sijaintielementiksi elementti
void clear ()Asia selvä
boolean sisältää (Objekti o)Selvitä, onko o lineaaritaulukossa
int indexOf(objekti o)Palauta indeksi, jossa ensimmäinen o sijaitsee
int lastIndexOf(Object o)Palauttaa viimeisen o:n alaindeksin
Lista alilista(int fromIndex, int toIndex)Sieppaa osa luettelosta
  1. public static void main(String[] args) {
  2. LinkedList<Integer> list = new LinkedList<>();
  3. list.add(1); // add(elem): 表示尾插
  4. list.add(2);
  5. list.add(3);
  6. list.add(4);
  7. list.add(5);
  8. list.add(6);
  9. list.add(7);
  10. System.out.println(list.size());
  11. System.out.println(list);
  12. // 在起始位置插入0
  13. list.add(0, 0); // add(index, elem): 在index位置插入元素elem
  14. System.out.println(list);
  15. list.remove(); // remove(): 删除第一个元素,内部调用的是removeFirst()
  16. list.removeFirst(); // removeFirst(): 删除第一个元素
  17. list.removeLast(); // removeLast(): 删除最后元素
  18. list.remove(1); // remove(index): 删除index位置的元素
  19. System.out.println(list);
  20. // contains(elem): 检测elem元素是否存在,如果存在返回true,否则返回false
  21. if(!list.contains(1)){
  22. list.add(0, 1);
  23. }
  24. list.add(1);
  25. System.out.println(list);
  26. System.out.println(list.indexOf(1)); // indexOf(elem): 从前往后找到第一个elem的位置
  27. System.out.println(list.lastIndexOf(1)); // lastIndexOf(elem): 从后往前找第一个1的位置
  28. int elem = list.get(0); // get(index): 获取指定位置元素
  29. list.set(0, 100); // set(index, elem): 将index位置的元素设置为elem
  30. System.out.println(list);
  31. // subList(from, to): 用list中[from, to)之间的元素构造一个新的LinkedList返回
  32. List<Integer> copy = list.subList(0, 3);
  33. System.out.println(list);
  34. System.out.println(copy);
  35. list.clear(); // 将list中元素清空
  36. System.out.println(list.size());
  37. }

3. LinkedListin läpikäynti

  1. public static void main(String[] args) {
  2. LinkedList<Integer> list = new LinkedList<>();
  3. list.add(1); // add(elem): 表示尾插
  4. list.add(2);
  5. list.add(3);
  6. list.add(4);
  7. list.add(5);
  8. list.add(6);
  9. list.add(7);
  10. System.out.println(list.size());
  11. // foreach遍历
  12. for (int e:list) {
  13. System.out.print(e + " ");
  14. }
  15. System.out.println();
  16. // 使用迭代器遍历---正向遍历
  17. ListIterator<Integer> it = list.listIterator();
  18. while(it.hasNext()){
  19. System.out.print(it.next()+ " ");
  20. }
  21. System.out.println();
  22. // 使用反向迭代器---反向遍历
  23. ListIterator<Integer> rit = list.listIterator(list.size());
  24. while (rit.hasPrevious()){
  25. System.out.print(rit.previous() +" ");
  26. }
  27. System.out.println();
  28. }

5. Ero ArrayListin ja LinkedListin välillä

eroArrayListLinkedList
Säilytystilallatulee olla fyysisesti jatkuvaaLoogisesti jatkuva, ei välttämättä fyysisesti jatkuva
satunnainen pääsyTuki O(1)Ei tuettu: O(N)
Pään tulppaTarve siirtää elementtejä, alhainen hyötysuhde O(N)Muokkaa vain viitteen osoitinta, aika monimutkaisuus on O(1)
lisääKun tilaa ei ole tarpeeksi, tarvitaan laajennustaEi käsitettä kapasiteetista
SovellusskenaariotTehokas elementtien varastointi + toistuva pääsyToistuva lisäys ja poistaminen missä tahansa paikassa