当前位置:   article > 正文

链表与模拟LinkedList的实现

链表与模拟LinkedList的实现

1. ArrayList的缺陷

ArrayList底层使用数组来存储元素

由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后 搬移,时间复杂度为O(n),效率比较低。因此ArrayList不适合做任意位置插入和删除比较多的场景。

因此:java 集合中又引入了LinkedList,即链表结构。

2. 链表

 链表的概念及结构

链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。

注意:
1.从上图可看出,链式结构在逻辑上是连续的,但是在物理上不一定连续
2.现实中的结点一般都是从堆上申请出来的
3.从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续

1. 单向或者双向

2. 带头或者不带头 

3. 循环或者非循环

3 模拟LinkedList的实现

我们先来定义一些数据:

  1. public class MySingleLinkedList {
  2. class ListNode{
  3. public int val;
  4. public ListNode nest;
  5. public ListNode(int val) {
  6. this.val = val;
  7. }
  8. }
  9. public ListNode head;//代表链表头节点
  10. }

 

如果想要全部遍历完 那么 head != null而不是head.next != null

那样会少遍历最后一个值。

1头插法:

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

 

2.尾插法:

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

 

3任意位置插入:

 

  1. public void addIndex(int index,int val) {
  2. //1.判断index的合法性
  3. try {
  4. checkIndex(index);
  5. }catch (IndexNotLegalException e) {
  6. e.printStackTrace();
  7. }
  8. //2.index == 0 || index == size()
  9. if(index == 0) {
  10. addFirst(val);
  11. return;
  12. }
  13. if(index == size()) {
  14. addLast(val);
  15. return;
  16. }
  17. //3. 找到index的前一个位置
  18. ListNode cur = findIndexSubOne(index);
  19. //4. 进行连接
  20. ListNode node = new ListNode(val);
  21. node.next = cur.next;
  22. cur.next = node;
  23. }
  24. private ListNode findIndexSubOne(int index) {
  25. int count = 0;
  26. ListNode cur = head;
  27. while (count != index-1) {
  28. cur = cur.next;
  29. count++;
  30. }
  31. return cur;
  32. }

 

4查找是否包含关键字val是否在单链表当中 

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

5删除出现一次关键字为val的节点 

  1. public void remove(int val){
  2. if(head == null){
  3. return;
  4. }
  5. if (head.val==val){
  6. head = head.next;
  7. return;
  8. }
  9. ListNode cur = head;
  10. while (cur.next != null){
  11. if (cur.next.val==val){
  12. ListNode del =cur.next;
  13. cur.next=del.next;
  14. }
  15. cur=cur.next;
  16. }
  17. }

6删除所有值为key的节点 

如果要删的是head.val,可以使代码走完在走一遍就行 或者把if改成while语句。

  1. public void removeAllKey(int val) {
  2. //1. 判空
  3. if(this.head == null) {
  4. return;
  5. }
  6. //2. 定义prev 和 cur
  7. ListNode prev = head;
  8. ListNode cur = head.next;
  9. //3.开始判断并且删除
  10. while(cur != null) {
  11. if(cur.val == val) {
  12. prev.next = cur.next;
  13. //cur = cur.next;
  14. }else {
  15. prev = cur;//prev = prev.next;
  16. //cur = cur.next;
  17. }
  18. cur = cur.next;
  19. }
  20. //4.处理头节点
  21. if(head.val == val) {
  22. head = head.next;
  23. }
  24. }

7 清空链表 

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

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/523667
推荐阅读
相关标签
  

闽ICP备14008679号