【数据结构】_4.List接口实现类LinkedList与链表

这篇具有很好参考价值的文章主要介绍了【数据结构】_4.List接口实现类LinkedList与链表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.链表的结构与特点

1.1 链表的结构:

1.2 链表的特点:

2. 不带头单链表的模拟实现

3. 单链表OJ

3.1 题目1:移除链表元素: 

3.2 题目2:反转一个单链表

3.3 题目3:返回链表的中间结点

3.4 题目4:链表的倒数第k个结点

3.5 题目5:合并两个有序链表

3.6 题目6:链表的回文结构

3.7 题目7:链表分割

3.8 题目8:相交链表

3.9 题目9:环形链表

 3.10 题目10:环形链表Ⅱ

4. LinkedList的模拟实现

5. LinkedList的使用

6.LinkedList和ArrayList的区别


1.链表的结构与特点

1.1 链表的结构:

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

(2)现实中常见的链表有8种结构:

单向与双向,带头或不带头,循环或非循环,组合起来就有8种结构;

最常用的是:① 单向不带头非循环链表; ② 双向不带头非循环;

1.2 链表的特点:

(1)链表是由结点构成的,每个节点至少包括两个域:当前结点的数据与下一个结点的地址;

(2)链表的链式结构在逻辑上是连续的,但是物理上不一定连续;

(3)结点一般都是在堆上申请出来的;

2. 不带头单链表的模拟实现

(1)包类关系:

【数据结构】_4.List接口实现类LinkedList与链表,数据结构(Java),java,jvm,intellij-idea,数据结构

(2)MySingleList:

package TestMySingleList;
// 不带头的非循环单链表
public class MySingleList {
    static class Node{
        public int val;  //存储数据
        public Node next;  //存储下一个结点的地址
        public Node(int val){
            this.val = val;
        }
    }
    public Node head;  // 代表当前链表的头结点的引用
    public void createLink(){
        Node node1 = new Node(12);
        Node node2 = new Node(45);
        Node node3 = new Node(23);
        Node node4 = new Node(90);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        head = node1;
    }
    //成员方法1:遍历并打印链表
    public void display(){
        Node cur = head;
      while(cur!=null){
          System.out.print(cur.val+" ");
          cur=cur.next;
      }
    }
    //重载:从指定位置开始遍历打印列表
    public void display(ListNode newHead){
        ListNode cur = newHead;
        while(cur!=null){
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
    }
    //成员方法2:查找某个关键字key是否在单链表中
    public boolean contains(int key){
        Node cur = head;
        while(cur!=null){
            if(cur.val == key){
                // 若为引用类型需用equals方法
                return true;
            }
            cur=cur.next;
        }
        return false;
    }
    //成员方法3:得到链表长度(时间复杂度为O(N)
    public int size(){
        int count=0;
        Node cur = head;
        while(cur!=null){
            count++;
            cur=cur.next;
        }
        return count;
    }
    //成员方法4:头插法
    public void addFirst(int data){
        Node newNode = new Node(data);
        newNode.next = head;
        head = newNode;
    }

    //成员方法5:尾插法
    public void addLast(int data){
        Node newNode = new Node(data);
        newNode.next = null;
        // 判断链表是否为空(判断是否为首次插入)
        if(head==null){
            head = newNode;
            return;
        }
        Node cur = head;
        while(cur.next!=null){
            cur=cur.next;
        }
        cur.next = newNode;
    }
    //成员方法6:任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data) throws ListIndexOutOfException{
        if(index == 0){   // 头插
            addFirst(data);
            return;
        }
        if(index == size()) {    // 尾插
            addLast(data);
            return;
        }
        Node cur = findIndexSubOne(index);
        Node newNode = new Node(data);
        newNode.next = cur.next;
        cur.next = newNode;
    }
    // 辅助方法:判断插入位置下标是否异常
    private void checkIndex(int index){
        if(index<0||index>size()){
            throw new ListIndexOutOfException("下表位置不合法!");
        }
    }
    // 辅助方法:查询目标下标结点的前结点
    private Node findIndexSubOne(int index){
        // 查找index-1位置的结点
        Node cur = head;
        int count=0;
        while(count!=index-1){
            cur=cur.next;
            count++;
        }
        return cur;
    }
    //成员方法7:删除第一次出现关键字为key的结点
    public void remove(int key){
        if(head==null){
            return;  // 链表为空
        }
        if(head.val == key){
            head = head.next;
            return;
        }
        Node preDel = searchPrevNode(key);
        if(preDel == null){
            return;
        }
        Node del = preDel.next;
        preDel.next = del.next;
    }
    //辅助方法:查找目标key值结点的前结点
    private Node searchPrevNode(int key){
        Node cur = head;
        while(cur.next!=null){
            if(cur.next.val == key){
                return cur;
            }
            cur=cur.next;
        }
        return null; // 没有找到待删除的结点
    }
    //成员方法8:删除所有值为key的结点
    public void removeAllKey(int key){
        if(head==null){
            return;
        }
        Node cur = head.next;
        Node prev = head;
        while(cur!=null){
            if(cur.val==key){
                prev.next = cur.next;
                cur=cur.next;
            }else{
                prev = cur;
                cur = cur.next;
            }
        }
        if(head.val == key){
            head = head.next;
        }
    }
    //成员方法9:清空链表
    public void clear(){
        head =null;
    }
}

(3)ListIndexOutOfException:

package TestMySingleList;

public class ListIndexOutOfException extends RuntimeException{
    public ListIndexOutOfException(){

    }
    public ListIndexOutOfException(String message){
        super(message);
    }
}

3. 单链表OJ

3.1 题目1:移除链表元素: 

题目链接:203. 移除链表元素 - 力扣(LeetCode)

代码: 

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if(head==null){
            return null;
        }
        ListNode prev = head;
        ListNode cur = prev.next;
        while(cur!=null){
            if(cur.val==val){
                prev.next = cur.next;
                cur = cur.next;
            }else{
                prev = cur;
                cur = cur.next;
            }
        }
        if(head.val == val){
            head = head.next;
        }
        return head;
    }
}

3.2 题目2:反转一个单链表

题目链接:206. 反转链表 - 力扣(LeetCode)

解题思路:将原列表头结点head.next置为null,依次取头结点的下一个结点对头结点进行头插;

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null){
            return null;
        }
        if(head.next == null){
            return head;
        }
        ListNode cur = head.next;
        head.next = null;
        while(cur!=null){
            ListNode curNext = cur.next;
            // 头插法
            cur.next=head;
            head = cur;  // 更新头结点
            cur = curNext; 
        }
        return head;
    }
}

3.3 题目3:返回链表的中间结点

题目链接:876. 链表的中间结点 - 力扣(LeetCode)

解题思路:定义快慢指针,快指针每次走两步,慢指针每次走一步,当快指针到达链表末尾时,慢指针就指向链表中间结点位置;

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
}

注:(1)当链表结点数为奇数时,while循环截止条件是fast.next为空;当链表结点数为偶数时,while循环截止条件是fast为空;

(2)while循环的判断条件逻辑与前后条件不能顺序颠倒,因为当fast为空时,fast.next可能触发空指针异常;

3.4 题目4:链表的倒数第k个结点

题目链接:链表中倒数第k个结点_牛客题霸_牛客网

解题思路:定义快慢指针,令慢指针slow标记待找结点。

当fast指向尾结点时,倒数第k个结点即slow比fast慢k-1步;

故而,令fast走k-1步,slow开始走,两个指针开始同时前进,当fast.next为空(fast行至尾结点)时,slow所指节点就是待找结点;

代码:

import java.util.*;
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        // 判断 k 位置是否合法
        if(k<=0 || head==null){
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        // fast 走 k-1 步
        while(k-1!=0){
            fast=fast.next;
            if(fast==null){
                return null;
            }
            k--;
        }
        // slow 开始和 fast 一起走
        while(fast.next!=null){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

3.5 题目5:合并两个有序链表

题目链接:21. 合并两个有序链表 - 力扣(LeetCode)

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode newHead = new ListNode(0);
        ListNode tmp = newHead;
        // 两链表均有数据
        while(list1!=null && list2!=null){
            if(list1.val < list2.val){
                tmp.next = list1;
                list1 = list1.next;
                tmp = tmp.next;
            }else{
                tmp.next = list2;
                list2 = list2.next;
                tmp = tmp.next;
            }
        }
        // 链表2已经走完,直接将链表1其余部分拼接到tmp结点后即可
        if(list1 != null){
            tmp.next = list1;
        }
        // 链表1已经走完,将链表2其余部分拼接到tmp结点后
        if(list2 != null){
            tmp.next = list2;
        }
        return newHead.next;
    }
}

3.6 题目6:链表的回文结构

题目链接:链表的回文结构_牛客题霸_牛客网

解题思路:寻找链表中间结点,将链表后半部分反转。从链表首位开始依次对应判断是否相等;

代码:

import java.util.*;

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class PalindromeList {
    public boolean chkPalindrome(ListNode head) {
        if(head == null){
            return false;
        }
        if(head.next == null){
            return true;
        }
        ListNode fast = head;
        ListNode slow = head;
        // 找中间结点
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        // 翻转
        ListNode cur = slow.next;  // cur代表当前需要翻转的结点
        while(cur != null){
            ListNode curNext = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curNext;
        }
        // slow从后往前, head从前往后 依次对应比较
        while(slow != head){
            if(head.val != slow.val){
                return false;
            }
            if(head.next == slow){
                return true;
            }
            slow = slow.next;
            head = head.next;
        }
        return true;
    }
}

注:在head与slow分别开始从两端对应比较时,对于结点个数为偶数个的链表,直接判断head与slow是否相遇会导致head与slow错过,需要增加一个判断:head.next是否为slow,如果是则说明是回文序列;

3.7 题目7:链表分割

题目链接:链表分割_牛客题霸_牛客网

代码:

import java.util.*;

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Partition {
    public ListNode partition(ListNode pHead, int x) {
        ListNode bs = null;   // 前半段首结点
        ListNode be = null;   // 前半段尾结点
        ListNode as = null;   // 后半段首结点
        ListNode ae = null;   // 后半段尾结点
        ListNode cur = pHead;
        while(cur != null){
            if(cur.val < x){
                if(bs == null){
                    // 前半段首次插入
                    bs = cur;
                    be = cur;
                }else{
                    be.next = cur;
                    be = be.next;
                }
            }
            else{
                if(as == null){
                    // 后半段首次插入
                    as = cur;
                    ae = cur;
                }else{
                ae.next = cur;
                ae = ae.next;
                }
            }
            cur = cur.next;
        }
        // 可能不是同时存在小于x和大于x数据的情况
        // 前半段为空直接返回后半段
        if(bs == null){   
            return as;
        }
        // 前半段不为空,则与后半段连接即可
        be.next = as;
        // 后半段不为空时,将后半段指针域置空
        if(as != null){
           ae.next = null; 
        }
        return bs;
    }
}

3.8 题目8:相交链表

题目链接:160. 相交链表 - 力扣(LeetCode)

解题思路:定义两头结点指针,确定长短链表;

为了保证指针能同时到达两链表相交结点位置,令长链表头结点指针向前走两链表长度之差步;

令两链表头结点指针开始同步前进并对应判断是否引用相同并返回两引用任意其一即可;

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public int size(ListNode head){
        int len=0;
        ListNode cur =head;
        while(cur!=null){
            len++;
            cur = cur.next;
        }
        return len;
    }
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        // 求两个链表长度并确定长短链表
        int lenA = size(headA);
        int lenB = size(headB);
        int len = lenA - lenB;
        ListNode headLong = headA;
        ListNode headShort = headB;
        if(len < 0){ // 链表B比链表A长
            headLong = headB;
            headShort = headA;
            len = lenB - lenA;
        }
        // 令长链表头结点指针走两链表之差长度的距离
        while(len != 0){
            headLong = headLong.next;
            len--;
        }
        // 两链表头结点指针开始同步前进
        while(headLong != headShort){
            headLong = headLong.next;
            headShort = headShort.next;
        }
        // 判断是否两指针走完链表都未相遇,同时等于空值而相等
        if(headLong == headShort && headLong == null){
            return null;
        }
        return headLong;
    }
}

3.9 题目9:环形链表

题目链接:141. 环形链表 - 力扣(LeetCode)

代码:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                return true;
            }
        }
        return false;
    }
}

注:判断是否带环的方法是快指针每次走两步慢指针走一步,两个指针相差的距离最大是一个环的长度,不会出现套圈的情况。而使用快指针每次三或四步等,慢指针走一步,可能会出现两指针永远无法相遇的情况;

 3.10 题目10:环形链表Ⅱ

题目链接:142. 环形链表 II - 力扣(LeetCode)

(与上一题的区别在于,如果有环则返回链表开始入环的第一个结点)

代码:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                break;
            }
        }
        // 链表无环
        if(fast == null || fast.next == null){
            return null;
        }
        // 此时fast和slow在相遇点
        // 将slow置回头结点
        slow = head;
        // 令slow从头结点出发,fast从相遇点出发,二者再次相遇点即为环的入口点
        while(fast != slow){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

4. LinkedList的模拟实现

LinkedList底层就是一个双向链表;

(1)包类关系:

【数据结构】_4.List接口实现类LinkedList与链表,数据结构(Java),java,jvm,intellij-idea,数据结构 

(2)MyLinkedList:

package TestMyLinkedList;

public class MyLinkedList {
    static class ListNode{
        public int val;
        public ListNode prev;
        public ListNode next;

        public ListNode(int val){
            this.val = val;
        }
    }
    public ListNode head;
    public ListNode last;
    // 遍历并打印链表
    public void display(){
        ListNode cur = head;
        while(cur != null){
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }
    // 求链表长度
    public int size(){
        ListNode cur = head;
        int len=0;
        while(cur!=null){
            cur = cur.next;
            len++;
        }
        return len;
    }
    // 查找关键字key是否包含在链表中
    public boolean contains(int key){
        ListNode cur = head;
        while(cur != null){
            if(cur.val == key){
                return true;
            }
        }
        return false;
    }
    // 尾插 O(1)
    public void addLast(int data){
        ListNode newNode = new ListNode(data);
        if(head == null){
            head = newNode;
            last = newNode;
        }else{
            last.next = newNode;
            newNode.prev = last;
            last = newNode;
        }
    }
    // 头插
    public void addFirst(int data){
        ListNode newNode = new ListNode(data);
        if(head==null){
            head = newNode;
            last = newNode;
        }else{
            newNode.next = head;
            head.prev = newNode;
            head = newNode;
        }
    }
    // 任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index, int data){
        if(index<0 || index>size()){
            throw new ListIndexOutOfException();
        }
        if(index == 0){
            addFirst(data);
            return;
        }
        if(index == size()){
            addLast(data);
            return;
        }
        ListNode newNode = new ListNode(data);
        ListNode cur = findIndex(index);
        ListNode preCur = cur.prev;
        preCur.next = newNode;
        newNode.prev = preCur;
        newNode.next = cur;
        cur.prev = newNode;
    }
    // 辅助方法:查询目标下标结点
    private ListNode findIndex(int index){
        ListNode cur = head;
        while(index!=0){
            cur = cur.next;
            index--;
        }
        return cur;
    }
    // 删除第一次出现关键词key的结点
    public void remove(int key){
        if(head == null){
            return;
        }
        if(head.val == key){
            head = head.next;
            return;
        }
        if(last.val == key){
            last = last.prev;
            last.next =null;
            return;
        }
        ListNode del = findKey(key);
        ListNode preDel = del.prev;
        ListNode delNext = del.next;
        preDel.next = delNext;
        delNext.prev = preDel;
    }
    // 辅助方法:查找关键词为key的结点
    public ListNode findKey(int key){
        ListNode cur = head;
        while(cur!=null){
            if(cur.val == key){
                return cur;
            }
            cur =cur.next;
        }
        return null;
    }
    // 删除链表中所有值为key的结点
    public void removeAllKey(int key){
        ListNode cur = head;
        while(cur!= null) {
            if (cur.val == key) {
                // 删除的是头结点
                if (cur == head) {
                    head = head.next;
                    // 只有一个结点
                    if (head != null) {
                        head.prev = null;
                    }
                } else {
                    // 删除的不是头结点
                    cur.prev.next = cur.next;
                    // 删除的不是尾结点
                    if (cur.next != null) {
                        cur.next.prev = cur.prev;
                    } else {
                        // 删除的是尾巴结点
                        last = last.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }
    // 清空列表
    public void clear(){
        ListNode cur = head;
        ListNode curNext = cur.next;
        while(cur!=null){
            cur.val = 0;
            cur.next = null;
            cur.prev = null;
            cur = curNext;
        }
        head = null;
        last = null;
    }
}

(3)ListIndexOtOfException:

package TestMyLinkedList;

public class ListIndexOutOfException extends RuntimeException{
    public ListIndexOutOfException(){

    }
    public ListIndexOutOfException(String message){
        super(message);
    }
}

注:其中删除所有值为key的结点方法removeAllKey也可以写为:

/ 删除链表中所有值为key的结点
    public void removeAllKey(int key){
        if(head == null){
            return;
        }
        while(head.val == key){
            head = head.next;
            if(head == null){
                return;
            }
        }
        if(last.val == key){
            last = last.prev;
            last.next = null;
            return;
        }
        ListNode cur = head;
        while(cur!=null){
            ListNode del = findKey(cur, key);
            if(del!=null) {
                ListNode preDel = del.prev;
                ListNode delNext = del.next;
                preDel.next = delNext;
                delNext.prev = preDel;
            }
            cur = cur.next;
        }
    }
    public ListNode findKey(ListNode node, int key){
        ListNode cur = node;
        while(cur != null){
            if(cur.val == key){
                return cur;
            }
            cur = cur.next;
        }
        return null;
    }

5. LinkedList的使用

Linkedlist的方法与ArrayList基本一致,此处不再详细举例,请参考ArrayList文章:

CSDN

注:(1)LinkedList使用其他集合容器构造方法含义:

【数据结构】_4.List接口实现类LinkedList与链表,数据结构(Java),java,jvm,intellij-idea,数据结构

(2)LinkedList的迭代器遍历法:文章来源地址https://www.toymoban.com/news/detail-608768.html

ListIterator<String> it =linkedList.listIterator();
        while(it.hasNext()){
            // 有下一个则打印下一个并向下走一步
            System.out.print(it.next());
        }
        ListIterator<String> it2 = linkedList.listIterator(linkedList.size());
        while(it2.hasPrevious()){
            // 有前一个则打印前一个并向前走一步
            System.out.print(it2.previous());
        }

6.LinkedList和ArrayList的区别

不同点 ArrayList LinkedList
存储空间上 物理上一定连续 逻辑上连续,但物理上不一定联系
随机访问 支持:O(1) 不支持:O(N)
头插 需要搬移元素,效率低:O(N) 只需要修改引用的指向,时间复杂度为O(1)
插入 空间不够时需要扩容 没有容量的概念
应用场景 元素高效存储+频繁访问 任意位置插入和删除频繁

到了这里,关于【数据结构】_4.List接口实现类LinkedList与链表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】 List与顺序表及接口的实现

    在集合框架中, List是一个接口,继承自Collection。 Collection也是一个接口,该接口中规范了后序容器中常用的一些方法,具体如下所示: Iterable也是一个接口,表示实现该接口的类是可以逐个元素进行遍历的,具体如下: List 的官方文档 站在数据结构的角度来看, List就是一

    2024年02月12日
    浏览(39)
  • 【数据结构 | 入门】线性表与链表 (问题引入&实现&算法优化)

    🤵‍♂️ 个人主页: @计算机魔术师 👨‍💻 作者简介:CSDN内容合伙人,全栈领域优质创作者。 本文是浙大数据结构学习笔记专栏 这里我们引入一个问题,最常见的多项式,我们如何使用编程将多项式表示出来呢? 我们可以使用数组来表示,但是会随着一个问题,如下图底

    2024年01月21日
    浏览(71)
  • 【数据结构】 LinkedList的模拟实现与使用

    LinkedList 的官方文档 LinkedList的底层是双向链表结构(链表后面介绍),由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引用将节点连接起来了,因此在在任意位置插入或者删除元素时,不需要搬移元素,效率比较高。 我们在这里创建一个 MyLinke

    2024年02月11日
    浏览(46)
  • 数据结构 模拟实现LinkedList单向不循环链表

    目录 一、链表的简单介绍 二、链表的接口 三、链表的方法实现 (1)display方法 (2)size得到单链表的长度方法 (3)addFirst头插方法 (4)addLast尾插方法 (5)addIndex指定位置插入方法 (6)contains方法 (7)remove删除第一个key值节点的方法 (8)removeAllKey删除所有值为key的方法

    2024年02月03日
    浏览(57)
  • 数据结构模拟实现LinkedList双向不循环链表

    目录 一、双向不循环链表的概念 二、链表的接口 三、链表的方法实现 (1)display方法 (2)size方法 (3)contains方法 (4)addFirst方法 (5)addLast方法 (6)addIndex方法 (7)remove方法 (8)removeAllKey方法 (9)clear方法 四、最终代码 双向不循环链表中的节点有三个域,一个是存

    2024年02月03日
    浏览(41)
  • 数据结构 模拟实现LinkedList双向不循环链表

    目录 一、双向不循环链表的概念 二、链表的接口 三、链表的方法实现 (1)display方法 (2)size方法 (3)contains方法 (4)addFirst方法 (5)addLast方法 (6)addIndex方法 (7)remove方法 (8)removeAllKey方法 (9)clear方法 四、最终代码 双向不循环链表中的节点有三个域,一个是存

    2024年02月03日
    浏览(41)
  • java -- 简单的数据结构、List接口和Collections类

    数据结构 : 数据用什么样的方式组合在一起。 数据存储的常用结构有:栈、队列、数组、链表 栈: stack ,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作。 采用该结构的集合,对元素

    2023年04月10日
    浏览(52)
  • [Collection与数据结构] 链表与LinkedList (一):链表概述与单向无头非循环链表实现

    上篇文章我们已经对顺序表进行了实现,并且对ArrayList进行了使用,我们知道ArrayList底层是使用数组实现的. 由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时, 就需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比较低 ,因此ArrayList不适合做

    2024年04月26日
    浏览(64)
  • 《数据结构与算法》之队列与链表复习

    我们在上一次学习了堆栈的数据结构以后,可以了解到它是受限制的操作,比如我们操作只能在栈顶,现在我们要学习的东西叫做队列,它也是受限制的一种数据结构,它的特点是队头只出数据,而队尾只入数据, 它的结构就和它的名字,像我们平时排队一样先来的人肯定要

    2024年02月08日
    浏览(66)
  • Java中List接口两个实现,ArrayList类和LinkedList类的常用方法(一)

    要了解List接口,就不得不说起Java的集合框架。 (该图来自菜鸟教程) Java 集合框架主要包括两种类型的容器,集合Collection和图Map。 Collection接口代表了 单列集合 ,它包含了一组Object元素,每个元素都有一个值。 (这里有个“泛型擦除”的概念,在此不提及有兴趣可自行了

    2024年01月19日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包