[Java实现数据结构]-单链表

2022-09-01 14:36:58

那么我们正式踏入了对数据结构的学习
本篇博客教大家学习单链表
以下为代码实现的思维导图
单链表.png

想要理解清楚的小伙伴一定要耐心看完哦

单链表的概念

image.png

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


链式的结构分为一个一个节点,什么是节点呢?

节点:

  1. 数值域
  2. next域(可以理解为指针域或是引用域)

image.png

注意:👇

  1. 那么我们在下面的图中可以看出,链式结构在逻辑上是连续的,但是在物理上不一定连续
  2. 现实中的节点一般都是从堆上申请的
  3. 从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续,下图中的0×11,0×12就是连续的特殊情况

1651457344847.jpg
这样单向,带头,非循环的,我们称其中的节点为傀儡节点,那么什么是双向呢?
在这里插入图片描述


那么什么是不带头的呢?,就是没有数值域为空的节点
那么什么是循环呢?就是最后的next域不指向null,而是指向首节点,构成循环

image.png

这些条件排列组合一下会产生许许多多的链表,但我们常用的链表主要是以下两种:

  1. 无头单向非循环链表:结构比较简单,一般不会单独用来存储数据。实际上更多是作为其他数据结构的子结构。

  1. 无头双向链表:在Java的集合框架库中LinkedList底层实现就是无头双向循环链表。

在这里插入图片描述

单链表的实现

/**
 * @author Gremmie102
 * @date 2022/4/28 9:24
 * @purpose :单链表的实现
 */publicclassMySingleList{staticclassListNode{publicint val;//数值域publicListNode next;//存储下一个节点的地址publicListNode(int val){this.val= val;}}publicListNode head;//代表单链表的头结点的引用/**
     * 这里只是简单的进行,链表的构造。
     */publicvoidcreateList(){ListNode listNode1=newListNode(12);ListNode listNode2=newListNode(23);ListNode listNode3=newListNode(34);ListNode listNode4=newListNode(45);ListNode listNode5=newListNode(56);

        listNode1.next= listNode2;

        listNode2.next= listNode3;
        listNode3.next= listNode4;
        listNode4.next= listNode5;this.head= listNode1;}publicvoiddisplay(){ListNode cur= head;while(cur!=null){System.out.print(cur.val+" ");
            cur= cur.next;}System.out.println();}/**
     * 头插法
     * O(1)
     */publicvoidaddFirst(int data){ListNode node=newListNode(data);/*if(this.head == null) {
            this.head = node;
        }else {
            node.next = this.head;
            this.head = node;
        }*/
        node.next=this.head;this.head= node;}//尾插法 O(n)publicvoidaddLast(int data){ListNode node=newListNode(data);if(head==null){
            head= node;}else{ListNode cur= head;while(cur.next!=null){
                cur= cur.next;}//cur.next == null;
            cur.next= node;}}/**
     * 任意位置插入,第一个数据节点为0号下标
     * 指定位置插入
     */publicvoidaddIndex(int index,int data)throwsMySingleListIndexOutOfException{checkIndexAdd(index);if(index==0){addFirst(data);return;}if(index==size()){addLast(data);return;}ListNode node=newListNode(data);ListNode cur=findIndexSubOne(index);
        node.next= cur.next;
        cur.next= node;}/**
     * 找到index-1位置的节点
     * @param index
     * @return 该节点的地址
     */privateListNodefindIndexSubOne(int index){ListNode cur=this.head;while(index-1!=0){
            cur= cur.next;
            index--;}return cur;}privatevoidcheckIndexAdd(int index){if(index<0|| index>size()){thrownewMySingleListIndexOutOfException("任意位置插入的时候,index不合法!");}}//查找是否包含关键字key是否在单链表当中  314publicbooleancontains(int key){//head == nullListNode cur=this.head;//cur != null 说明 没有遍历完 链表while(cur!=null){if(cur.val== key){returntrue;}
            cur= cur.next;}returnfalse;}//删除第一次出现关键字为key的节点publicvoidremove(int key){if(this.head==null){System.out.println("此时链表为空,不能进行删除!");return;}if(this.head.val== key){//判断 第一个节点是不是等于我要删除的节点this.head=this.head.next;return;}ListNode cur=this.head;while(cur.next!=null){if(cur.next.val== key){//进行删除了ListNode del= cur.next;
                cur.next= del.next;return;}
            cur= cur.next;}}//删除所有值为key的节点publicvoidremoveAllKey(int key){while(true){remove(key);if(this.contains(key)){continue;}elsebreak;}}//得到单链表的长度publicintsize(){int count=0;ListNode cur=this.head;while(cur!=null){
            count++;
            cur= cur.next;}return count;}publicvoidclear(){this.head=null;}}

LinkedList

那么上面的代码是我们自己实现的单链表。
在Java中,已经有大佬帮我们写好了单链表,叫做LinkedList

使用方式

image.png

方法

methodexplain
void add(int index, E element)将 e 插入到 index 位置
boolean add(E e)尾插 e
boolean addAll(Collection c)尾插 c 中的元素
E remove(int index)删除 index 位置元素
boolean remove(Object o)删除遇到的第一个 o
E get(int index)获取下标 index 位置元素
E set(int index, E element)将下标 index 位置元素设置为 element
void clear()清空
boolean contains(Object o)判断 o 是否在线性表中
int lastIndexOf(Object o)返回最后一个 o 的下标
int indexOf(Object o)返回第一个 o 所在下标
List subList(int fromIndex, int toIndex)截取部分 list
publicstaticvoidmain(String[] args){LinkedList<Integer> list=newLinkedList<>();
    list.add(1);// add(elem): 表示尾插
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    list.add(6);
    list.add(7);System.out.println(list.size());System.out.println(list);// 在起始位置插入0
    list.add(0,0);// add(index, elem): 在index位置插入元素elemSystem.out.println(list);
    list.remove();// remove(): 删除第一个元素,内部调用的是removeFirst()
    list.removeFirst();// removeFirst(): 删除第一个元素
    list.removeLast();// removeLast(): 删除最后元素
    list.remove(1);// remove(index): 删除index位置的元素System.out.println(list);// contains(elem): 检测elem元素是否存在,如果存在返回true,否则返回falseif(!list.contains(1)){
        list.add(0,1);}
    list.add(1);System.out.println(list);System.out.println(list.indexOf(1));// indexOf(elem): 从前往后找到第一个elem的位置System.out.println(list.lastIndexOf(1));// lastIndexOf(elem): 从后往前找第一个1的位置int elem= list.get(0);// get(index): 获取指定位置元素
    list.set(0,100);// set(index, elem): 将index位置的元素设置为elemSystem.out.println(list);// subList(from, to): 用list中[from, to)之间的元素构造一个新的LinkedList返回List<Integer> copy= list.subList(0,3);System.out.println(list);System.out.println(copy);
    list.clear();// 将list中元素清空System.out.println(list.size());}

链表后续还会更新题目,大家拭目以待
最近临近考试,学习任务繁重
如果文章有哪里不足的地方麻烦大佬指出
感谢阅读~

  • 作者:Gremmie102
  • 原文链接:https://blog.csdn.net/qq_63511424/article/details/124538028
    更新时间:2022-09-01 14:36:58