IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 链表——java实现 -> 正文阅读

[数据结构与算法]链表——java实现

1.链表概念

链表:

  • 链表是一种递归的数据结构,
  • 由许多个结点(node)组成,每个节点含有一个泛型的元素和指向另一个链表的引用
  • 链表可以为空

结点:

class Node{
	Item item;
    Node next;
}

构造一个链表:

构造一些结点,将第一个结点中的引用指向第二个结点,将第二个结点中的引用指向第三个结点,。。。循环下去就得到一个多结点链表;

Node first = new Node();
Node second = new Node();
Node third = new Node();
...

first.next = second;
second.next = third
...

数组的缺点:

  • 需要在使用前知道数组的长度;
  • 需要大块连续的内存
  • 插入删除元素的效率低、速度慢
  • 空间通常有限制的

链表:离散型数据结构,由于是通过引用指向下一个结点,所以在内存中各节点的顺序不必连续

相对于内存连续型容器(如数组)的优缺点:

  • 优势:增删元素速度快,插入和删除元素仅需要改动变动元素的引用即可,
  • 劣势:查找慢,内存不连续,故需要从第一个结点开始遍历,比如要查找第五个元素,则需要从第一个结点开始遍历

链表种类(3种):

  • 单链表:

  • 双链表:

  • 循环链表:

    • 循环单链表
    • 循环双链表

在这里插入图片描述

2.链表操作

链表的核心操作包括:插入、删除、查找(遍历)

2.1链表的插入、删除

  • 在表头插入、删除

    插入:只需将要插入的结点指向原链表的第一个结点即可;

在这里插入图片描述

Node newFirst = new Node();
newFirst.next = oldFirst;
	删除:删除表头只需要将首结点指向为下一个结点即可;

在这里插入图片描述

first = first.next
  • 在表尾插入、删除

    插入:只需要将原链表中尾结点重新指向要插入的结点即可

    Node newEnd = new Node();
    oldEnd.next = newEnd;
    

    删除:删除表尾的结点,需要找到倒数第二个结点,将该结点指向null;

  • 在其他位置插入、删除:

2.2遍历

遍历数组:

forint i= 0; i < arr.length; i++{
	// arr[i]
}

遍历链表:

for (Node node = first; node != null; ndoe = ndoe.next){
	// node.term
}

单链表操作:

在这里插入图片描述

2.3 实现代码

以下用单链表实现对链表的增删操作:

public class SingleLinkedList<T> {
    private Integer size = 0;
    private Node head;

    /**
     * 将结点添加到末尾
     * @param element 要添加的元素
     * @return 是否添加成功
     */
    public boolean add(T element){
        Node node = new Node(element);
        if (head == null) {
            head = node;
        } else {
            Node tmp = head;
            while (tmp.next != null) {
                tmp = tmp.next;
            }
            tmp.next = node;
        }
        size++;

        return true;
    }

    /**
     * 将元素插入指定指定的下标位置
     * @param index  插入的下标
     * @param element   插入的元素
     * @return 是否添加成功
     */
    public boolean add(int index, T element){
        if(index >= size || index < 0){     //异常下标
            throw new IndexOutOfBoundsException("size:" + size + " index: " + index );
        }
        Node newNode = new Node(element);
        if (index == 0){    //插入到表头的位置
            newNode.next = head;
            head = newNode;
        } else {
            Node tmp = head;
            for (int i = 0; i < index - 1; i++) {
                tmp = tmp.next;
            }
            newNode.next = tmp.next;
            tmp.next = newNode;
        }
        size++;

        return true;
    }

    /**
     * 默认删除链表最后一个结点, 并返回值
     */
    public T remove(){
        if (head == null) {//空链表
            throw new RuntimeException("链表为空!无法删除!");
        }
        if (size < 2) {//单元素链表
            T tmp = head.item;
            head = null;
            size--;
            return tmp;
        }
        Node tmp = head;
        while (tmp.next.next != null){
            tmp = tmp.next;
        }
        T returnVal = tmp.next.item;
        tmp.next = null;
        size--;

        return returnVal;
    }

    /**
     * 删除指定下标的结点
     * @param index 要删除的结点下标
     * @return 返回已经删除元素
     */
    public T remove(Integer index){
        if (head == null) {
            throw new RuntimeException("链表为空!无法删除!");
        }
        if(index >= size || index < 0) {
            throw new IndexOutOfBoundsException("size: " + size + " index: " + index);
        }
        Node tmp = head;
        for (int i = 0; i < index - 1; i++) {
            tmp = tmp.next;
        }
        Node returnNode = tmp.next; //即将删除的结点
        tmp.next = tmp.next.next;
        returnNode.next = null;

        return returnNode.item;
    }

    /**
     * 遍历打印链表
     */
    public void print(){
        Node tmp = head;
        while (tmp != null){
            System.out.print(tmp.item + " ");
            tmp = tmp.next;
        }
    }

    /**
     * 内部类:结点
     */
    class Node {
        T item;
        Node next;

        public Node(T item) {
            this.item = item;
        }

        public T getItem() {
            return item;
        }

        public void setItem(T item) {
            this.item = item;
        }

        public Node getNext() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }
    }

    public Integer getSize() {
        return size;
    }

    public Node getHead() {
        return head;
    }

    public void setHead(Node head) {
        this.head = head;
    }
}

测试一下单链表:

public class SingleLinkedListTest {
    public static void main(String[] args) {
        SingleLinkedList<String> singleLinkedList = new SingleLinkedList();
        // 添加元素
        System.out.println("---------添加元素--------");
        singleLinkedList.add("a");
        singleLinkedList.add("b");
        singleLinkedList.add("c");
        singleLinkedList.add("d");
        singleLinkedList.add("e");
        singleLinkedList.add("f");
        singleLinkedList.print();

        // 添加到指定位置
        singleLinkedList.add(5, "h");
        System.out.println();
        singleLinkedList.print();

        //删除最后一个元素
        singleLinkedList.remove();
        System.out.println();
        System.out.println("---------删除元素--------");
        singleLinkedList.print();

        //删除指定元素
        System.out.println();
        singleLinkedList.remove(2);
        singleLinkedList.print();
    }
}

运行结果

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 11:02:29  更:2021-08-02 11:02:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/11 1:44:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码